S33 the cloud

After all that hype about cloud and Amazon services, I decided to set up a simple S3 server on my laptop. On google code I found little-s3, a funny webapp which implements the s3 protocol and I check it out.

The guide is straightforward and the protocol implemented is mainly a GET/PUT server: a free place for testing your “cloud” infrastructure.

Here are some example methods:

1- create the object foo.html.

curl –data “@foo.html” –request PUT –header “Content-Type: text/html” “http://localhost:8080/littleS3-2.1.0/firstBucket/foo.html”

2- Retrieve an object

curl “http://localhost:8080/littleS3-2.1.0/firstBucket/foo.html”

3- Delete an object
curl –request DELETE “http://localhost:8080/littleS3-2.1.0/firstBucket/foo.html”

4- Delete a bucket
curl –request DELETE “http://localhost:8080/littleS3-2.1.0/firstBucket”

Jndi connection pooling: a common pitfall

When enabling jndi connection pooling with java, you have to set just this context property


// Enable connection pooling
env.put("com.sun.jndi.ldap.connect.pool", "true");

But if you’re using SSL, Anonimous bind or MD5 auth, you have to specify some System properties too

com.sun.jndi.ldap.connect.pool.protocol="plain ssl"
com.sun.jndi.ldap.connect.pool.authentication="none simple DIGEST-MD5"

or ssl, anonymous and md5 connections will be excluded from the pool

info here

Velocity e il controllo di un attributo null

Con Velocity, se vogliamo fare un controllo di un null in un attributo (in questo caso ‘fuel’) di un oggetto (‘car’), con una istruzione simile a:

#if ($car.fuel == null)

Abbiamo due tipi di approcci per realizzare questa condizione.
Approccio 1:
Sfruttare il fatto che l’attributo di un oggetto, se è null Velocity lo valuta come una condizionale false, per cui nel template scriveremo:

#if( ! $car.fuel )

Nota: Questa condizione passerebbe anche se il risultato di car.fuel sia realmente un booleano “false”. Quindi quello che questo tipo di approccio controlla effettivamente è che l’attributo dell’oggetto sia false o null.

Approccio 2:
Sfruttare il fatto che l’attributo di un oggetto, se è null Velocity viene valutato come una stringa vuota in una Quiet Reference Notation, per cui nel template scriveremo:

#if( “$!car.fuel” == “” )

Nota: Questa condizione passerebbe anche se il risultato di car.fuel sia realmente una stringa vuota. Quindi quello che questo tipo di approccio controlla effettivamente è che l’attributo dell’oggetto sia stringa vuota o null

Per cui, combinando i due approcci avremo il modo per controllare se l’attributo dell’oggetto sia solamente null, in questo modo:

#if ((! $car.fuel) && (“$!car.fuel” == “”))

P.S. esiste anche una “custom directive” per controllare se un attributo sia null, usando l’istruzione cf. IfNullDirective, IfNotNullDirective, ma non funziona se aggiungiamo l’istruzione #else if o #else al template:

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )

Nota: Bisogna registrare queste direttive nel velocity.properties:

userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Golden Axis: save connections with HTTP/1.1

By default axis use HTTP/1.0 for calling webservices.

The following code

for i in 1..10:
   axis.method("doit")

creates 10 connection to the server:

# netstat -tuap |egrep -ic 'http.*clienthost.*ESTAB'
10

We can configure axis to use just one connection setting:

  • HTTP/1.1
  • transfer encoding:  chunked

this involves

  1. configuring axis client.wsdd to use Commons-Httpclient-3.0 for transport
  2. enabling pre-emptive authentication

Use CommonsHTTPClient

# find $TOMCAT/ -name axis\*.jar
# unzip axis-1.4.jar org/apache/axis/client/client-config.wsdd
# vi org/apache/axis/client/client-config.wsdd

change HTTPSender with the apache commons one and repack file:

- <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
+ <transport name="http" pivot="java:org.apache.axis.transport.http.CommonsHTTPSender"/>
# zip -f zip axis-1.4.jar org/apache/axis/client/client-config.wsdd

Now with wireshark/ethereal/netstat you’ll see that while running you got:

# netstat -tuap |egrep -ic 'http.*clienthost.*ESTAB'
1

Setting PreEmptive authentication

Sniffing, you’ll notice one issue: client won’t automatically send authentication data. Instead it

  1. client send an unauth soap request
  2. server returns 401 (Authentication Required)
  3. client send the authenticated request
  4. server says ok

To force CommonsHTTPClient to send authentication data, we need to set the following property:

        System.setProperty("httpclient.authentication.preemptive", "true");

And the magic is done: jjust one connection for all the call…and your WebService Producer say thankyou!

Makefile per Java

gnu make Quanti di voi programmatori Java hanno avuto problemi per la compilazione di programmi? librerie fuori da $CLASSPATH, parametri chilometrici da passare al compilatore Java. Anche usando ambienti di sviluppo per Java la situazione non migliora di molto. Spendiamo molto tempo a settare paramteri e ogni volta che lanciamo la compilazione manca sempre qualcosa!

Potete evitare tutti questi problemi semplicemente organizzando i sorgenti Java e usando un Makefile scritto ad hoc.
Continua a leggere

Log for the bare necessities, the simple bare necessities

Why did you do that if you weren’t asked to? Improving performance means doing just the minimum tasks. As stated in “Performance” section, http://logging.apache.org/log4j/1.2/manual.html , we’d better check if we need creating tonns of strings in java. So

if (log.isDebugEnabled()) {

log.debug(“Create” + “this” + message + “string”);

}

prevents creating unneeded debug/trace strings.

Managing dependencies with maven

Maven is a nice build tool helper for java projects. A cool feature is the way to specify if some dependencies are

  1. necessaries at runtime
  2. provided by the application server
  3. necessaries while doing tests but not at deploy time

That’s an example in my pom.xml:

<!– I need to embed javamail in my package –>

<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>

<!– while Log4j is provided by the application server –>

<dependency>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
<version>1.2.14</version>
<scope>provided</scope>
</dependency>
<!– and  Hypersonic Database is used for testing–>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.1</version>
<scope>test</scope>
</dependency>

Creare Una Cache con Java

Quante volte vi sarà capitato di dover creare una “semplice” Cache? Le Librerie che implementano questo comportamento esistono ma a volte sono troppo complicate da implementare… vediamo allora come implementarla con pochissime righe di codice ed usando solo la libreria standard.

La classe che andremo a creare estende la classe LinkedHashMap<T, K> questo tipo di mappa espone il metodo protected boolean removeEldestEntry che risponde alla domanda tolgo l’ultima entry inserita?

Vediamo come abbiamo implementato la classe per rispondere alla nostra esigenza di creare una cache con politica FIFO

public class Cache<T, K> extends LinkedHashMap<T, K> {

private int maxSize = 1;

public Cache(int maxSize) {
this.maxSize = maxSize;
}

@Override
protected boolean removeEldestEntry(java.util.Map.Entry<T, K> eldest) {
return size() > this.maxSize;
}

}

et voilà il gioco è fatto…. vediamo come funziona:

public static void main(String[] args) {

//Creo una cache che contiene fino a 4 elementi

Map<String, Integer> cache = new Cache<String, Integer>(3);

cache.put(“INBOX-1”, 1);
cache.put(“INBOX-2”, 2);
cache.put(“INBOX-3”, 3);
cache.put(“INBOX-4”, 4);

System.out.println(cache);

}

come output abbiamo

{INBOX-2=2, INBOX-3=3, INBOX-4=4}

La chiave piu vecchia INBOX-1 è stata eliminata…. spada no! 😉

Ma miglioriamo il tutto, invece che FIFO vogliamo che scelga quella che ha l’ultimo accesso più datato poche modifiche al codice ed il gioco è fatto:

nella classe cache aggiungiamo l’override del metodo get in modo da far andare quella acceduta come ultima in classifica

public class Cache<T, K> extends LinkedHashMap<T, K> {
private int maxSize = 1;
//Questo è il metodo aggiunto rispetto a prima
@Override
public K get(Object key) {
K tmpObj = super.get(key);

super.remove(key);

super.put((T)key, tmpObj);

return super.get(key);
}

public Cache(int maxSize) {
this.maxSize = maxSize;
}

@Override
protected boolean removeEldestEntry(java.util.Map.Entry<T, K> eldest) {
return size() > this.maxSize;
}
}

lanciamo questo test

public static void main(String[] args) {

Map<String, Integer> cache = new Cache<String, Integer>(3);

cache.put(“INBOX-1”, 1);
cache.put(“INBOX-2”, 2);
cache.put(“INBOX-3”, 3);
cache.get(“INBOX-1”);
cache.put(“INBOX-4”, 4);

System.out.println(cache);

}

e avremo come output

{INBOX-3=3, INBOX-1=1, INBOX-4=4}

Come ci aspettavamo è stata tolta la seconda entry…..

spada no?

Potere di JAVA 😉

beanshell: scripting for java

Ok, I never really liked java – as I think it moves problem from developers to sysadmin 😉 but I have to say that there are very nice java things: beanshell is one of this.

The problem I face was the post-processing of funambol output to a mobile device, shortly I had to filter an xml (syncml) response, regexp-replacing some values if the client was a Nokia mobile.

Doing it in the webapp code was ugly and leaves the webapp jars Nokia-dependant 🙁
So I decided to look at synclets (the way as Funambol uses beanshell for this kind of job) and quick-and-dirty write those lines.

What’s a synclet?
1- Funambol extends BeanShell with BeanShellSynclet
2- a BeanShellSynclet is a java-bean (an object), configured by an xml file
3- the xml refers to a .bsh file which includes methods and attributes written in java
4- the xml contains a User-Agent string

How Funambol use Synclets
Synclets are used when a User-Agent connects to the server (ex. a Nokia Mobile)
1- Funambol stores synclet’s XMLs configuration files in a proper directory
2- create a synclet object for each configuration file whose matches the User-Agent connected
3- before passing syncml streams to clients, parse it with all those synclets

Advantages
1- your webapp code is clear and rfc-compliant
2- writing synclet is easy
3- synclets applies only to the right User-Agent
4- you don’t have to re-deploy webapps, as synclets are instantiate at runtime

Have your say & Peace,
Rob