Bonita Open Solution auf Tomcat6 unter Ubuntu mit MySQL, LDAP Auth/Abfragen sowie Mail Versand

von   4 Kommentare

Nachfolgender Artikel dreht sich um die Installation von Bonita Open Solution. Einer Business Process Modeling (BPM) Software, mit der man einen Geschäfts-Prozess grafisch entwickeln (zusammenklicken ;)), mittels Java/Groovy erweitern und auf einem Application-Server deployen kann.

Da ich mir die Informationen für meine Installations-Konstellation (Ubuntu, Tomcat 6, MySQL, Active Directory/OpenLdap) von Hand zusammensuchen musste, hier eine Installationsanleitung für Bonita 5.4 bis Bonita 5.6 (hierbei kam nur xcmis als Dokumentenmanager dazu).

Basic Bonita Installation

  1. apt-get install tomcat6

    (vorher sicherstellen, dass sun-java installiert ist. Mit open-java kommt es an unterschiedlichen Stellen zu merkwürdigen fehlern.

  2. Aus dem Installation-Guide aus dem Bonita Wiki. Wobei ich ihn nicht mehr finde. Tomcat_home ist /var/lib/tomcat6/ unter Ubuntu. Außerdem muss ess entgegen der Bonita Anleitung catalina.base statt home sein, weil Tomcat unter Ubuntu die Einstellung so hat, wie Tomcat es empfiehlt und nicht wie es üblich ist. Unten ist es entsprechend korrigiert.
    • Copy \web\bonita.war to \webapps
    • Create a folder \lib\bonita
    • Copy all *.jar files from \web\lib\ to \lib\bonita.
    • Go to \conf and copy the bonita and external folders to
    • Modify \conf\catalina.properties to add
      ,${catalina.base}/lib/bonita/*.jar

      to the property common.loader to get

      common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,${catalina.base}/lib/bonita/*.jar

    • Create a setenv.bat (Windows) or setenv.sh (Linux) file in \bin. Example setenv.sh:
      #!/bin/bash
      BONITA_HOME="-DBONITA_HOME=$CATALINA_BASE/bonita"
      #BONITA_OPTS="-Dorg.ow2.bonita.environment=/var/lib/tomcat6/bonita/server/default/conf/bonita-server.xml"
      LOG_OPTS="-Djava.util.logging.config.file=$CATALINA_BASE/external/logging/logging.properties"
      SECURITY_OPTS="-Djava.security.auth.login.config=$CATALINA_BASE/external/security/jaas-standard.cfg"
      MEMORY_OPTS="-Xshare:auto -Xms512m -Xmx1024m -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError"
      # folgendes nur mit XCMIS, ab Bonita 5.6
      CMIS_CONFIG="-Dexo.data.dir=$CATALINA_BASE/external/xcmis/ext-exo-data -Dorg.exoplatform.container.standalone.config=$CATALINA_BASE/external/xcmis/ext-exo-conf/exo-configuration-mysql.xml"
      #CATALINA_BASE="/var/lib/tomcat6"
      export CATALINA_OPTS="$JAVA_OPTS $LOG_OPTS $SECURITY_OPTS $BONITA_HOME $MEMORY_OPTS $CMIS_CONFIG"
  3. Sicherstellen, dass /var/lib/tomcat6/bonita/server/default/ schreibbar ist, da die h2-file database dort erstellt wird.
  4. Ab Version Bonita 5.6:
    Das Verzeichnis $CATALINA_BASE/external/xcmis/ext-exo-data muss schreibbar sein, damit XCMIS korrekt startet.
  5. Damit wäre alles eingerichtet, um die Basis-Funktion von Bonita zu testen. Ergebnis: Bonita Login läuft

MySQL als Backend

  1. Datenbanken bonita_journal und bonita_history erstellen und User bonita mit „all privileges“.
  2. Konfiguration von Bonits anpassen (/var/lib/tomcat6/bonita/server/default/conf/bonita-journal|history), damit MySQL benutzt wird und nicht vergessen den Block zu H2 auszukommentieren:

    hibernate.dialect org.hibernate.dialect.MySQL5InnoDBDialect
    hibernate.connection.shutdown true
    bonita.hibernate.interceptor org.ow2.bonita.env.interceptor.MySQLDescNullFirstInterceptor

    # The following properties must be commented out for deployment using datasource (e.g. when using bundles provided by BonitaSoft)
    hibernate.connection.driver_class com.mysql.jdbc.Driver
    hibernate.connection.url jdbc:mysql://localhost:3306/bonita_history?dontTrackOpenResources=true
    hibernate.connection.username bonita
    hibernate.connection.password bpm

  3. Mysql-connector (mysql-connector-java-5.1.15-bin.jar) nach /var/lib/tomcat6/lib/bonita/mysql kopieren. (Unterordner mysql, um etwas Übersicht reinzubringen. (Connector gibts bei: http://dev.mysql.com/downloads/connector/j/)
  4. Das Verzeichnis lib/bonita/mysql zum oben bereits erwähnten common.loader hinzufügen, damit die libs von Tomcat gefunden werden.
  5. Tomcat6 neustarten, damit der Connector verwendet wird und Bonita auf MySQL zugreift.
  6. Bonita aufrufen und die entsprechenden Tabellen werden automatisch aufgesetzt.

MySQL und Connection pooling

Da Hibernate standardmäßig eine Datenbankverbindung nicht wieder aufbaut, sobald MySQL sie dicht gemacht hat, muß mittels connection pooling der Wiederaufbau der Verbindung sichergestellt werden, sonst gibt es hässliche Fehlermeldungen.

  1. Die Datenbank-Konfiguration (/var/lib/tomcat6/bonita/server/default/conf/bonita-journal|history auf Benutzung der c3p0-lib ändern, indem man folgendes Beispiel anhängt:

    hibernate.hbm2ddl.auto update
    hibernate.cache.use_second_level_cache false
    hibernate.cache.use_query_cache false
    hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
    hibernate.show_sql false
    hibernate.format_sql false
    hibernate.use_sql_comments false
    hibernate.c3p0.min_size 5
    hibernate.c3p0.max_size 20
    hibernate.c3p0.timeout 1800
    hibernate.c3p0.max_statements 50
    hibernate.c3p0.idle_test_period 10
    hibernate.c3p0.acquire_increment 5
    hibernate.connection.provider_class org.hibernate.connection.C3P0ConnectionProvider

  2. Die Libs hibernation-c3p0 / c3p0 / mchange-commons-0.2.jar nach lib/bonita/mysql/ kopieren. Download der libs lässt sich über Google finden.
  3. Tomcat neustarten und hibernate benutzt jetzt Connection pooling und die Verbindungen zu Mysql werden neu aufgebaut, nachdem MySQL sie nach dem Timeout dicht gemacht hat.

Ldap Authentifizierung

Im Unternehmensumfeld, will man natürlich bereits vorhandene Benutzerkonten nutzen. Oftmals liegen diese in einem Active Directory oder in einem LDAP-Verzeichnis. Folgendes basiert auf einem anderen Blog-Eintrag

  1. Die Datei /var/lib/tomcat6/external/security/jaas-standard.cfg wie folgt bearbeiten:

    BonitaAuth {
    com.sun.security.auth.module.LdapLoginModule REQUIRED
    authzIdentity=“{USERNAME}“
    userProvider=“ldap://:389/dc=company,dc=com“
    userFilter=“(uid={USERNAME})“
    useSSL=false
    debug=true;
    };
    BonitaStore {
    org.ow2.bonita.identity.auth.LocalStorageLoginModule required;
    };

  2. Ab Bonita 5.6 muss folgendes noch vorhanden sein:

    exo-domain {
    org.exoplatform.services.security.j2ee.TomcatLoginModule required;
    };

    Der Rest aus der Datei kann, muss aber nicht weg ;).

  3. Damit funktioniert grundlegende Ldap Authentification.

Ldap Admin Zugang

Mit oben beschriebendem Ldap-Auth Setup, kann man sich zwar einloggen, bekommt aber nie Admin Zugang. Diese Information bekommt Bonita vom AD/Ldap nicht. Kann wie folgt erreicht werden (ist aus irgendeinem Forumseintrag/Blog, finde es aber ebenfalls nicht mehr):

  1. In der Datei /var/lib/tomcat6/bonita/server/default/conf/bonita-server.xml

    <authentication-service name=’authentication-service‘ class=’org.ow2.bonita.services.impl.DbAuthentication‘>

    durch

    <authentication-service name=’authentication-service‘ class=’com.domain.bonita.auth.SimpleLdapAuth‘>

    ersetzen.

  2. Dazu die folgende Java-Class SimpleLdapAuth erzeugen.
    package com.domain.bonita.auth;
    import org.ow2.bonita.facade.exception.UserNotFoundException;
    import org.ow2.bonita.services.AuthenticationService;
    
    public class SimpleLdapAuth implements AuthenticationService {
            private String persistenceServiceName;
            public SimpleLdapAuth(String persistenceServiceName) {
                super();
                this.persistenceServiceName = persistenceServiceName;
            }
    
            /**
             * Determines if the user should have amdin accesses to the bonita interface
             * Let's say that Domain Admins have that privilege
             */
            // It looks like by "admin" here, it means whether the user can administer users, roles,
            // etc. in the UserXP.
            public boolean isUserAdmin(String username) throws UserNotFoundException {
                if (username.equals("usernamewhichisadmin")) {
                    return true;
                } else {
                    return false;
                }
            }
    
        /**
             * @return always true. If the LDAP request failed before, it doesn't matter (?)
             * Necessary to implement interface
             */
            public boolean checkUserCredentials(String username, String password) {
                return false;
            }
    
            public boolean checkUserCredentialsWithPasswordHash(String username, String password) {
                return false;
            }
    }

    Wird folgendermaßen kompiliert:

    javac -cp /var/lib/tomcat6/lib/bonita/bonita-server-5.6.jar SimpleLdapAuth.java

  3. Verzeichnisse entsprechend der Klassenstruktur und unterhalb von lib/ im Tomcat-Lib Verzeichnis anlegen, also z.B.:

    /var/lib/tomcat/lib/com/domain/bonita/auth

  4. Das Ergebnis des compiles, also die SimpleLdapAuth.class in das Verzeichnis kopieren.
  5. Und dann noch:

    jar -cfv SimpleLdapAuth.jar /var/lib/tomcat6/lib/com/domain/bonita/auth/SimpleLdapAuth.class

  6. Die SimpleLdapAuth.jar dann auch noch nach /var/lib/tomcat6/lib/ kopieren.
  7. Mal wieder Tomcat neustarten und wen auch immer man bei isUserAdmin angegeben hat hat nun Admin Rechte in Bonita.

LDAP Abfrage in einem Prozess mittels Connector

Der Connector ist völlig unabhängig von LDAP auth, kann also auch eingesetzt werden, wenn man Bonita Auth-Mechanismen verwendet.

  1. Bei Activity im „General“ Tab einen neuen Connector erzeugen und LDAP auswählen.
  2. Einen Name vergeben und on „Entry“ wählen. Oder wann auch immer die LDAP-Abfrage stattfinden soll
  3. Den Host, Port, Username und Passwort eintragen, die notwendig sind, um eine Abfrage ans LDAP zu richten.
  4. Base dn angeben (z.B. ou=Users,dc=company,dc=com), sowie Filter ( z.B. (&(uid=*)(objectClass=person))) und Attribute (z.B. für ein AD uid,displayName,mail,DEPARTMENT,physicalDeliveryOfficeName,l,sn,givenName)
  5. Jetzt der Kopfweh Teil. Der Code kommt in den Connector output (links) und passend dazu rechts eine Variable (Hashmap) angeben, welcher die LDAP Daten enthalten soll:
    def usersById = new HashMap()
    def name=''
    def uid=''
    ldapAttributeList.each {
    	def user= new HashMap()
    	it.each {
    		if( it.getName().equals("displayName") ){
    			name= it.getValue()
    		}
    		if( it.getName().equals("uid") ){
    			uid= it.getValue()
    		}
    		user.put( it.getName(), it.getValue() )
    	}
    	usersById.put( uid.toLowerCase(), user )
    }
    usersById

    Wir erzeugen also eine Hashmap als Output des Connectors, bei der hm[‚uid‘] => hm[$attributenames]=$attributevalue ist. Selbiges kann man z.B. noch machen, um einen Userindex mit map[‚displayName‘] => user[‚attributenname‘]= attributevalue zu bekommen. Diese map, kann man dann als Auswahloption hinter ein Dropdown legen, um so vom Namen eines Users auf seine Attribute zu kommen.

LDAP Identity synchronisiert gegen ein AD

Basierend auf der LDAP-aware IdentityService Extension, kann man die Benutzer im LDAP/AD in die Benutzerverwaltung von Bonita synchronisieren. Denn egal, ob man LDAP-Auth nutzt oder nicht, die Benutzer-Details, wie Name, E-Mail-Adresse etc. pp. sind solange nicht greifbar, wie sie sich nicht in der Bonita DB befinden. Entweder man macht das also manuell oder mit folgender Klasse. Ich habe die Benutzung aber eingestellt, da sie bei mir Probleme mit dem Synchronisieren machte und allerlei Exceptions im Log warf.

In der Klasse muss man aber in jedem Fall die Base-DN anpassen, bevor man sie kompiliert, damit im LDAP auch an der richtigen Stelle gesucht wird.

Datenbank-Abfrage (MySQL oder Oracle) mittels Connector

  1. Neuer Connector -> Oracle/MySQL/usw -> Zeitpunkt wählen
  2. Folgenden Code mit Query bei dem in letzter Zeile die query zurückgegeben wird:
    query= """\
    select 
      something as smthg,
      somethingelse as smthgels
    from sometable
    where nothing="something"
    """
    query
  3. Der Connector output wird dann entsprechend zurückzugeben. Also wieder folgendes links und eine passende Variable rechts.
    if( rowSet.getValues().size() > 0 )
    {
    	var['smthg']= rowSet.toList("smthg").get(0)
    	var['smthgels']= rowSet.toList("smthels").get(0)
    }
    var

Mail-Versand mittels Start-Instance Connector und passendem Prozess

Um in einem Prozess nicht unzählige Bonita Connectoren zu haben (Bonita hat leider keine Connectoren-Templates mit Vererbung), die man dann jedes Mal alle bearbeiten muss, wenn es Änderungen gibt. Prinzipiell sollte man natürlich sowieso Variablen-Namen für die ganzen Attribute (SMTP-Details, Mail-From, To, Subject, Body etc. pp.) verwenden, trotzdem macht es Sinn statt vielfachen E-Mail-Connectoren, die E-Mails darüber zu versenden, dass man an entsprechender Stelle einen anderen Prozess startet, der den Versand übernimmt.

Dafür einen Prozess bauen, der völlig automatisch abläuft und z.B. in einem ersten Schritt die E-Mail zusammenbaut und in einem zweiten Schritt mittels Connector die Mail versendet. Die Daten für die Mail kommen aus den globalen Prozess-Variablen, die dieser Mail-Prozess über den Start-Instance-Connector vom ursprünglichen Prozess bekommen hat.

Im versendenden Prozess über Connector -> Bonita -> Start Instance Connector anlegen und als Prozess Name, den Prozess Namen des Mail-Prozess ohne Versions-Angabe angeben. Dadurch wird automatisch die aktuellste version gestartet und durch das Angeben von Variablen, werden die Globalen Variablen des anderen Prozesses gefüllt.

Ein weiterer Vorteil dieses Vorgehens besteht darin, dass im Falle von unerwartetem Daten zum Versand, nur der Sub-Prozess nicht funktioniert, der Hauptprozess aber ohne Probleme weitergeht, wenn man mal von der fehlenden Email absieht.

Als aufbauenden Schritt, kann man Bonita verlassen auf bestimmte Trigger hin, den Sub-Prozess auszuführen ohne dass man den Start-Instance-Connector noch bräuchte. Darauf gehe ich in einem dedizierten Artikel noch ein.

Fazit

Ich hoffe die Anleitung stimmt noch, sobald ziemlich bald Bonita 6 rauskommt. Andernfalls werde ich sie anpassen. Abgesehen davon, hoffe ich, die Details hier helfen jemandem.


Tags: , , , , , , , , , ,

4 Kommentare zu “Bonita Open Solution auf Tomcat6 unter Ubuntu mit MySQL, LDAP Auth/Abfragen sowie Mail Versand”

  1. Peter Germany Google Chrome Linux   am:

    Die obige Implementierung des Interfaces halte ich für nochmal anschauenswert.

    Sehe keinen Sinn darin ein Interface, das Password Hashes überprüft mit „return true“ zu implementieren.


    Antworten
  2. Peter Germany Google Chrome Linux   am:

    Wenn man weiß wie dein Adminbenutzername ist, dann kann man sich wohl das Passwort schenken 🙂


    Antworten
  3. Andi Mozilla Firefox Ubuntu Linux   am:

    Gebe dir Recht, sieht abenteuerlich aus, ist aber irrelevant. Die Klasse ist wirklich nur dafür da, um festzustellen, ob ein sich anmeldender Benutzer Admin ist. Das Authentifizierung findet über JAAS statt, wie oben als ersten Schritt (ldap-bezogen) auch aufgeführt.
    Das ist in der kostenfreien Version von Bonita leider tatsächlich umständlich. Man hat leider keine wirklich Verbindung zum LDAP und muss sich z.B. Benutzerrollen selbst synchronisieren.
    Andererseits ist BOS auch so Marktführer im Bereich Open-Source BPM. Das Ding kann einfach verdammt viel.
    Und wenn man es sich einfacher machen will, muss man halt eine Subscription abschliessen.
    Ist ja immer nur eine Frage des Aufwandes oder Geldes 😉


    Antworten
  4. Peter Frühberger Germany Google Chrome Linux   am:

    Kannst du, damit ich wieder ruhig schlafen kann, nicht einfach: „return false;“ reinschreiben? 🙂


    Antworten

Kommentar hinterlassen