Nexus maven repository with Apache as proxy and OpenDJ for authentication

For a client I have recently setup a nexus (oss) maven repository with apache proxy/reverse proxy and OpenDJ to provide LDAP authentication.

Nexus, which competes with Artifactory as maven repository, by default is waiting on port 8081 with the context path /nexus, which means that you can connect to it to the address http://localhost:8081/nexus (admin/admin123)

Having defined the name of my machine as maven I first configured Apache as proxy pointing to Nexus in this way:

ProxyPass         /nexus http://maven:8081/nexus
ProxyPassReverse  /nexus http://maven:8081/nexus

Having configured Apache to accept only https connections to be forwarded to Nexus in http (so https–>Apache–>http–>Nexus), I need to add before the ProxyPass directive the following RequestHeader:

RequestHeader set X-Forwarded-Proto “https”

in this way, the Nexus zip version, which is bundled with the servlet container Jetty 8.1.11 (which from the version 7.2.0 understands x-forwarded-proto header, see also the commit related) it will reply with the connection option (forwarded=true), see below the default configuration (in /nexus/config/jetty.xml):

<New class=org.sonatype.nexus.bootstrap.jetty.instrumentedSelectChannelConnector">
<Set name="host">${application-host}</Set>
<Set name="port>${application-port}</Set>
<Set name="forwarded">true</Set>
</New>

Now we add the ldap authentication, we go under Administration -> Server and add the OSS LDAP Authentication Realm to the Selected Realms.

I have OpenDJ listening on port 1389 (default), so we go under Security -> LDAP Configuration, we set the following parameters:

Connection
Protocol ldap
Hostname opendj
Port 1389
Search Base dc=my,dc=example,dc=com
Authentication
Authentication method Simple Authentication
Username cn=admin
Password mypassword
User Element Mapping
Base DN ou=users
Object Class inetOrgPerson
User ID Attribute uid
Real Name Attribute cn
E-Mail Attribute mail
Group Element Mapping
Group type Dynamic groups
Member of Attribute isMemberOf

The last 2 lines are optional to Static groups, but since OpenDJ allows to use the isMemberOf attribute, I preferred to use Dynamic groups (see Nexus documentation). For static groups you can check out also this article based on OpenDS on which OpenDJ is based on.

Now if you click on the Check User Mapping button you should see the list of users and groups retrieved from OpenDJ.

The last step would be add roles to the user so we go under Security ->Roles -> Add…->External Role Mapping and we select the LDAP group which will act as nexus administrators and we add all the roles for the group. So we logout and then we login with the nexus ldap administrator.

 

 

 

 

Testare applicazioni web con Selenium e Hudson

La fase di test di una applicazione è una di quelle più delicate in quanto dovrebbe cominciare (almeno il design) non appena i requisiti funzionali di una applicazione sono definiti. E’ difficile perchè entrano in gioco diversi fattori dall’usabilità di una applicazione all’architettura della applicazione stessa.

Normalmente in applicazioni Java avete Junit (o TestNG o ancora Nunit per applicazioni .NET) come libreria che vi permette di creare unit test per la vostra applicazione. In questa maniera avete modo di verificare che le vostre classi fanno il loro dovere. Per rendere poi gli unit test automatici potete usare continuous integration server come Hudson i quali non appena compilano il vostro codice permettono anche di eseguirli.

Se però sviluppate una applicazione con interfaccia web vi servirebbe uno strumento che vi permette di simulare il comportamento di un utente (cosa alquanto difficile) o comunque che dimostri che i requisiti funzionali dell’applicazione siano rispettati. Si parla di requisiti come:

  • se l’utente si vuole loggare sul sito web:
    • egli clicca sul link per accedere sulla pagina di login
    • digita username e password
    • clicca sul pulsante di login
    • appare una stringa dove esce il nome utente o comuque una pagina di benvenuto
    • l’attesa tra la pressione del pulsante login e il caricamento della pagina di benvenuto non deve essere più di tot secondi
  • se l’utente vuole cercare una risorsa nel sito web:
    • egli digita una parola chiave nell’apposito form
    • clicca sul pulsante cerca
    • visualizza, se esistono, pagine che contengono quella parola chiave

Rimane ovvio che il requisito del login più restringente è quello sul tempo di attesa, esso dovrebbe dipendere dall’achitettura software (accesso al database, uso di cookie ecc), mentre sulla ricerca non è sempre vero che inserendo una parola chiave riusciamo a trovare qualcosa.

Selenium è un software scritto per testare interfacce web che di base si presenta come una estensione per Firefox (Selenium IDE) o ancora come server (Selenium RC) per automatizzare i test e lanciare istanze di browser per eseguire i test stessi.

Selenium IDE in pratica permette di scrivere test tramite una comoda interfaccia web. Questi test in realtà vengono salvati come pagine html che contengono una semplice tabella come la seguente:

New Test
open /ig?hl=it
type q selenium
clickAndWait btnG
verifyTextPresent Selenium web application testing system
clickAndWait link=Selenium web application testing system
clickAndWait link=Documentation
clickAndWait link=Selenium-IDE

Questo test in particolare esegue la ricerca su http://www.google.it della parola “selenium”, verifica che tra i risultati compare la scritta “Selenium web application testing system”, clicca sul link e accede alla sezione documentazione sul Selenium-IDE. I comandi (scritti in Selenese :-) ) sono di semplice comprensione (accettano da 1 a 2 parametri) e possono essere generati automaticamente dal Selenium IDE utilizzando la modalità Record che registra l’attività utente sul sito web e modificati manualmente in ogni momento. Esistono diversi comandi che permettono per esempio:

  • di simulare il doppio click
  • di simulare la pressione di un tasto
  • di simulare il mouse sopra un particolare oggetto (evento OnMouseOver)
  • di fermare l’esecuzione del test per un determinato tempo
  • di rimuovere i cookie
  • di catturare lo screenshot di una pagina
  • di salvare e caricare variabili
  • ecc

Capite bene però che, leggendo il test precedente, il test può fallire per diversi motivi (il link documentazione è stato cambitato ad esempio) e non esistono condizioni per dire “se questa condizione fallisce allora verifica quest’altra”. Inoltre si vorrebbe verificare se gli stessi test sono validi su diversi browser e magari rendere la procedura più automatica possibile.

Ecco per cui è stato realizzato Selenium RC, un server java che rimane in ascolto di chiamate da client scritti in diversi linguaggi (Java, C#, Perl, PHP, Python, Ruby) ed esegue i test lanciando istanze di browser come Firefox, Internet Explorer, Safari e Opera.

Un esempio di test in Java sarebbe:

package com.example.tests;

import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;

public class NewTest extends SeleneseTestCase {
    public void setUp() throws Exception {
        setUp("http://www.google.com/", "*firefox");
    }
      public void testNew() throws Exception {
          selenium.open("/");
          selenium.type("q", "selenium");
          selenium.click("btnG");
          selenium.waitForPageToLoad("30000");
          assertTrue(selenium.isTextPresent("Results * for selenium"));
    }
}

Il codice è anche qui di facile comprensione, occorre leggersi con comodo le API da usare. Quindi magari ora potreste pensare di includere il codice in Junit o Nunit test per esempio da essere eseguiti automaticamente da un continuous integration server.

Hudson in particolare ha 2 plugin di cui uno apposito per Selenium RC e permette di generare i report, alternativamente esiste un Ant task. La cosa interessante è che partono direttamente dall’html senza passare ai test scritti in Java (a voi la scelta).

Il problema concreto è quindi non tanto usare i comandi quanto identificare l’oggetto su cui eseguire il comando, infatti potete usare attributi Id, attributi Name, DOM, Xpath, CSS sta a voi vedere dove usare una tecnica o l’altra perchè per esempio in talune applicazioni gli attributi Id sono generati dinamicamente e non potete di conseguenza creare i test.

Sul sito di Selenium trovate molta documentazione dallo screencast, al forum, bug tracker e al wiki.

Sul sito di Refcardz trovate una scheda riassuntiva.

Qualche nota interessante:

Buon test e buon anno a tutti !

Webclient for SVN, Hudson e Artifactory

Salve a tutti, in questi giorni mi sono addentrato ancora nel mondo del continuous integration perchè sto lavorando su un progetto in Java, gestito in outsourcing, dove aiuto un gruppo di sviluppatori ad utilizzare strumenti di sviluppo che facilitano il lavoro quali un sistema di continuos integration.

Sono partito da un progetto con subversion installato su una macchina e so che nel progetto usano Jboss con JDK 1.5 (ancora non so perchè)

Su un’altra macchina remota vado e installo JDK 1.5.0.22, Ant 1.7.1, Maven 2.2.1 (fino ad ora (2 mesi di progetto) hanno usato solo Ant e vorrebbero passare a Maven), Jboss 5.1.0, Webclient for SVN 3.1.0 e Artifactory 2.1.2.

Piccola nota: volevo usare Sventon ma l’ultima versione aveva problemi con le librerie e le precedenti mi davano anch’esse problemi.

Non sapete cosa è Artifactory ??? Allora è possibile che siete ancora freschi su Maven (non è che io non lo sia :-) )

Artifactory è una applicazione web che permette di gestire repository Maven, sviluppata in Java e rilasciata con licenza LGPL 3.0. L’applicazione è realizzata da JFrog Ltd, una società privata isreliana.

Strutturalmente si poggia su Apache Jackrabbit per l’implemetazione delle specifiche JSR 170 per il cosiddetto Java Content Repository (anche altri content manager come Nuxeo si appoggiano su Jackrabbit).

Piccola nota: la JSR 170 (rilasciata nel 2005) è seguita dalla JSR 283 da poco rilasciata (25 Settempre 2009) ed entrambe sono condotte da David Nuescheler, CTO della società svizzera Day Software.

Inoltre Artifactory si basa su Apache Lucene per indicizzare i file e Apache Wicket per l’interfaccia utente.

Ora l’applicazione è rilasciata come standalone ma esiste la versione war che può essere deployata su un application server e quindi l’ho messa su Jboss insieme ad Hudson e Webclient for SVN (questi 2 li ho poi legati con il plugin di hudson per Polarion che permette di linkare la lista di file modificati ai file presenti sul webclient e si possono anche vedere le differenze con le versioni precedenti).

La struttura è basata anche su database, di default Apache Derby ma che può essere cambiato (vedi anche qui).

A parte il fatto che Artifactory permette di base una autenticazione LDAP, quello che lascia senza parole è la semplicità di uso (andrebbe confrontato con Nexus ma non ne ho tempo, di sicuro nella versione base manca LDAP (anche se ho scoperto di recente che esiste un plugin di terze parti) e di sicuro gli sviluppatori hanno realizzato una bella guida a maven e un plugin per Eclipse). Una volta andato su

http://localhost:8080/artifactory

e loggato, sono andato sul pannello amministrativo e nella sezione repository ho creato un repository locale dove fare il deploy dei propri jar file e un repository virtuale in cui aggiungo quello locale più tutti i remoti quali quello di Maven, Jboss ecc ecc. Fatto ! Ora potete generare anche la sezione del file settings.xml da aggiungere nel vostro progetto Maven.

Per una vecchia guida vi rimando qui. Per un confronto con Nexus e Archiva vi rimando a questo link (attenzione è scritto dallo stesso autore della guida su Artifactory ma sembra serio)

Buon maven a tutti !

Nota: Webclient for SVN si basa su Subversion 1.4 (con versioni successive ho avuto problemi perchè usa un SVNKit vecchio che non posso aggiornare perchè c’è una particolare classe non più presente nelle ultime versioni), potete trovare Subversion 1.4 qui:

http://downloads-guests.open.collab.net/servlets/ProjectDocumentList?folderID=6