Installation Guide Created by: Thomas Bucher, Developer 13. November 2012 Version: 0.8
Intro Initial situation In many circumstances, there are datas in an LDAP directory, you want to share with others. For example you may want to share data as a phonebook or in a web based application. Normal solutions are often extremely slow. They have to fetch the datas from the LDAP each time, they are needed. Maybe they cache the data, and are no accurate all the time. For linked data they need to fetch all the objects to display just one informational page. Like the group names a user is in. With more data in the directory, the performance gets worser and worser. If you need to sort and filter the data, this can easily get a nightmare. If more than 100 000 entries need to be prepared, it takes often many seconds up to minutes. Solution This service fetches all the needed predefined data from the LDAP directory. This data can then be fetched as a JSON stream from the service. All the data is in the memory of the cache server. They get filtered, manipulated and sorted directly on the server. For a Matrix of 200 000 entries with 8 columns we need less than a second to filter, sort and send the result to the client.
Structure of the Solution positives The following positives can be achieved by this concept: The predefined datas are fast and accurate ready for the client. There can be as many caching servers as needed. The datas are only fetched on startup from the LDAP servers. The datas are all the time accurate. They get updated by a persistent search. All changes on the LDAP directory are exposed to the caching server and the data will be updated immediately. The user has fast access to the data, without waiting for it. All the datas can be manipulated / transformed as they are loaded into the cache negatives The cache server uses quite a bit of memory. All the data are only loaded into memory. On the start of the services, it may take a bit of time. The cache needs to be generated, before any user may use the service Do the loaded data not fit into the memory, the service is not able to start.
Installation To install the service you need at least the following: A server with va 6 or newer. 512M memory + 1GB per 2 millions values (see calculation of memory) edirectory 8.7 or newer as LDAP server. Apache or any other Proxy-Server. Installing va on the Server you like to run the cacher service. Download va from Sun. Use a 64 Bit Version. You can use a JDK or JRE. JDK has more options like -server available. Run it as Administrator Click Yes Install it
Finished Copy the DTLDAP.jar into the folder, you want the service to be installed in. And then open it. On the first run, it extracts some needed files. Download the Proc-Tools from Apache, to install DTLDAP as a service. http://commons.apache.org/daemon/procrun.html http://mirror.switch.ch/mirror/apache/dist//commons/daemon/binaries/windows /commons-daemon-1.0.10-bin-windows.zip Copy the prunmgr.exe and the correct prunsrv.exe to the installation directory of DTLDAP from inside the downloaded zip file.
Now its time to configure the service. (see configuration section, later in this document) If you like, you can install the DTLDAP as a service on windows. Start a command line shell. Run it as Administrator!! Switch to the directory where you installed the files. Install the Service like this prunsrv.exe //IS//DTLDAP --DisplayName="DTLDAP Cache Service" --Install=C:\DTLDAP\prunsrv.exe --Jvm=auto --StartMode jvm --StartClass ch.ktn.thomas.dtldap.dtldap --StartMethod start --StopMode jvm --StopClass ch.ktn.thomas.dtldap.dtldap --StopMethod stop --StartParams=dtldap.yml Make Adjustments like Heap-Space with the Command prunmgr,exe //ES//DTLDAP Set the Initial Memory Pool and the Maximum as needed. (1 Giga per 500 000 ) Cached Objects
Also set the filename for logging and error reporting. Check the Settings in Startup and Shutdown Service should be Installed. Check the Service View Start the service When the service starts, the logfiles will be created. Check them for any failures.
Maybe you need to adjust the windows firewall, so you are able to connect to the service from outside. Check if you can connect to the service. Check if the queries you defined are correct and the data is filled in correctly. For this you can access the server on the ip / port you defined in the configuration under -> config -> server Congratulations! You installed the DTLDAP - Caching Server
Configuration of the DTLDAP Server dtldap.yml Die Konfigurationsdatei heisst per Default dtldap.yml Sie ist im YAML Format. Siehe dazu http://www.yaml.org/ Die folgenden Parameter sind zu Konfiguration des LDAP Server LDAP Server Parameters ldap: ldap: port: ldap: user: Parameter Beschreibung Beispiel Optional ldap: password: Die IP-Addresse oder der DNS Name des LDAP Servers, von welchem die Daten geholt werden sollen Port, auf welchem der LDAP Server antwortet. (kein SLDAP) Benutzer für den LDAP Server. FQDN Passwort des LDAP Benutzers 127.0.0.1 ldap.mycompanie.org 389 cn=user,ou=users,o=system Default: localhost Default: 10389 ****** Default: a fqdn for development Default: keines, es wird als Public angemeldet DTLDAP Service Parameters host: port: Parameter Beschreibung Beispiel Optional separator: Die IP-Addresse oder der DNS Name auf welchen dieser Service gebunden werden soll. Es kann nur über diese auf den Service zugegriffen werden Port auf welchem der Service reagieren soll Trennzeichen, für Mehrwertige Felder in der Rückgabe der Datatable 10.0.0.10 dtldap.mycompanie.org 15667 #:# Default: 127.0.0.1 Default: 3176 Default: #:#
Parameter Beschreibung Beispiel Optional ldifsafe: htmlsafe: shutdown: threads: pagesize: failsize: enable_generate: Sollen die Daten ldifsafe übergeben werden (im JSON Feed) Sollen die Daten HTML Sicher übergeben werden (öäü ersetzten durch ä etc..) Via RCP kann der Server gestoppt werden. Telnet serverip:serviceport shutdown<return><return> Anzahl der Threads, die beim Einlesen der Daten vom LDAP Server benutzt werden. Anzahl der Objekte, bevor ein neuer Thread gestartet wird. Pro Thread werden maximal pagesize Objecte geladen Anzahl der erlaubten Change Requeste in der Queue oder im Helper, bevor der Cache von Grundauf neu gestartet wird (Changestorms) Soll der QuickStart / Demo DataTables-Generator verfügbar sein? srv:port/generate false true false Default: false Default: true 8 5000 1000 true Default: false Default: 4 Default: 10000 Default: 10000 Default: true enable_index: Index Service. Soll eine Einsteigsseite verfügbar sein? srv:port/ true Default: true
enable_index: Parameter Beschreibung Beispiel Optional enable_backend: Sollen die Backend Informationen abrufbar sein? srv:port/daten true Default: true enable_file Sell der Service als Webserver funktionieren? Alle Files aus extdata können via srv:port/* abgerufen werden true Default: true enable_themes: Sollen die DataTables von der Generierung UITheme extra Tags erhalten? false Default: false enable_querycss: Sollen die generierten DataTables eine extra Klasse erhalten mit dem Namen der Query? true Default: false Sollen die generierten Daten komprimiert zum Client true Default: false enable_compression: übermittel werden?
Parameter Beschreibung Beispiel Optional disable_filecache: csv_delimiter: csv_multivalue_delimi ter: Sollen die Files, welche als Fileserver zur Verfügung stehen, jedes mal vom Filesystem geladen werden? Wie sollen CSV Exports getrennt werden Wie sollen Mehrwertige Felder im CSV getrennt sein? false Default: false For Debugging set this to true, Default:, Default:
Helper Definitionen Helpers sind Hilfscacher. Sie werden benötigt, um Referenzen aufzulösen. Also Wenn man z.b auf einem Benutzer alle Gruppenmitgliedschaften durch den Gruppennamen ersetzten möchte. Der Helper ist ein Persisten Search, und informiert auch die einzelnen Queries, über welche Objekte neu gecacht werden müssen. Der name des Helpers <helpername> is frei wählbar, und wird in der Query dann als Referenz benutzt. Beispiel auflösen mitgliedschafts DN auf Beschreibung der Gruppe: groupmembership<#0d<hlp_group_description>> wobei hlp_group_description dem Helpernamen entprechen muss. helpers: <helpername>: filter: helpers: <helpername>: basedn: helpers: <helpername>: attr: Parameter Beschreibung Beispiel LDAP Filter für diesen Helfer LDAP BaseDN, von welchem aus gesucht werden soll Das Attribute, das gelesen werden soll. Dies ist der Wert, durch welchen dann der DN ersetzt wird in der Query (objectclass=groupofnames) ou=groups,o=demo description Das attr eines Helpers kann alle Attribute-Modifikationen beinhalten ausser d (Auflösung auf einen Helper). Query Definitionen Die Queries definieren was später via JSON Feed abgeholt werden kann. Alles diese Informationen werden von LDAP Server abgeholt und im Arbeitsspeicher in einer vereinfachten Form abgelegt. Parameter Beschreibung Beispiel queries: <queryname>: filter: queries: <queryname>: basedn: queries: <queryname>: attrs: LDAP Filter für diese Query LDAP BaseDN, von welchem aus gesucht werden soll Attribute welche gelesen werden sollen. Diese Attribute können alle Modifikationen erhalten (objectclass=person) ou=users,o=demo -cn -dn -'groupmembership<#0d<hlp_group_description>>' Der Name der Query <queryname> entspricht dabei dem Namen, mit welchem aus der DataTable die Daten abgeholt werden. Debug des Services Bei Problemen kann diese Option in die Konfig aufgenommen werden. Es gibt dann viel mehr Informationen. Parameter Beschreibung Beispiel debug: Debug the Service.. Lot of Output! true Remove the Option from Config if not needed
Attribut Modifikationen Attribute können bearbeitet werden, bevor diese im Cache abgelegt werden. Alle Attributewerte (bei Multivalue Feldern) werden einzeln Modifiziert und danach in eine String gepackt, mit separator getrennt. Um ein Attribute to bearbeiten wird am Ende des Attributenames ein Modify Tag geöffnet. Normales Attribute: membership Attribute mit Modifikation: membership<modifikation> Ein Modifikation besteht aus ein oder mehreren Modifiers. Diese sind in vier Kategorien unterteilt: - Auswahl (selectors) - Filter (filters) - Ausgabe (output) - Auflöser (helpers) Die Modifikationen werden immer von Links nach Rechts abgearbeitet. Zuerst wird immer der Wert oder einen Teil davon ausgewählt und dann bearbeitet. Dies geschieht mit #. Die Nummer dahinter entspricht dem Komponententeil. Bei einem Attribute ohne Komponenten sollte immer alles ausgewählt werden mit einer null #0. In einer Modifikation können beliebig viele # selector vorhanden sein, Sie werden nacheinander abgearbeitet und aneinander gehängt. Mehere Modifikationen werden innerhalb des # Parameters mit getrennt. Der Wert des vorherigen Aufrufs wird dann an die nächste Modifikation weitergereicht. Beispiele: Definition Wert aus LDAP Ausgabe in DataTable - fullname<#0ta< >#0ta< >#0ta< >> Mark Test Mark Test Mark Test Mark Test - 'dirxml-associations<#1ta< >#2ta<>>' ou=idm,o=system#1#dummy ou=idm,o=system 1 Wichtig zu verstehen hier, dass jedes #X separat bearbeitet wird, und die Ausgabe aller # zusammengefügt wird. Mögliche Modifikationen Selectors Wird zum Selektieren von Werten benutzt Parameter Beschreibung #x Teil der Komponente 0 = alles, 1, 2, 3= erster bis 3 Teil des Komponenten Attributes vb<x> va<x> Wert aus diesem Objekt, bevor es bearbeitet wurde. Nummer des Attributes aus der definition Wert aus diesem Objekt, nachdem es bearbeitet wurde. Achtung, die Bearbeitung findes der Reihe nach statt. Der Wert aus einem Attribute das nachher definiert wurde entspricht immer vb, da es noch nicht bearbeitet wurde Filters Falls ein Filter nichts zurück gibt, wird die Verarbeitung abgebrochen. Ansonsten wird der Originale Wert weitergereicht in der Modifikationsliste
Parameter e<xxx> c<xxx> rm<xxx> xm<xxx> Beschreibung Wenn der Wert nicht dem Wert xxx enspricht (Case Insensitive) wird die Verarbeitung abgebrochen und ein leeres Feld zurück gegeben. Wenn der Wert nicht den Wert xxx enthält (Case Insentitive) wird die Verarbeitung abgebrochen und ein leeres Feld zurück gegeben. Wenn der Wert nicht mit Regex Match etwas trifft mit xxx, wird kein Wert zurückgegeben. Der Wert wird mit XPath nach xxx durchsucht. Wenn kein Resultat gefunden wird, wird kein Wert zurückgegeben Output Mit Outputs wir der Wert bearbeitet. Mehrere Outputs können mit aneinander gehängt werden. Innerhalb der Outputs muss mit \ Escaped werden. Parameter rs<xxx> xs<xxx> sa<xxx> sb<xxx> ta<xxx> tb<xxx> Beschreibung Es wird mit Regex xxx selektiert, was aus dem Wert zurückgegeben werden soll Es wird mit XPath xxx selektiert und das Resultat als Wert zurückgegeben Alles was im Wert nach xxx kommt wird zurückgegeben Alles was im Wert vor xxx kommt wird zurückgegeben An den Wert wird xxx angehängt Vor den Wert wird xxx hizugefügt Helpers Mit dem Helper wird ein DN durch einen Attributewert eines Helpers ersetzt d<xxx> Parameter Beschreibung xxx entspricht einem Helpernamen. Von diesem Helper wird der Wert des Eintrages entnommen, wo der DN dem Wert entspricht.
Beispiele für Modifikationen Hier ein paar Beispiele, wie man Modifikationen erstellen kann. Einfache Modifikationen Eingabe Wert Modifikation Ausgabe Ein String <#0ta< Added>> Ein String Added Eingabe Wert Modifikation Ausgabe Ein String <#0c<Added>> Eingabe Wert Modifikation Ausgabe Ein Added String <#0c<Added>> Ein Added String Eingabe Wert Modifikation Ausgabe Ein String <#0sa<Ein >> String Eingabe Wert Modifikation Ausgabe <k><val>test</val></k> <#0xs</k/val>> Test Eingabe Wert Modifikation Ausgabe <k><val>test</val></k> <#0xs</k/val> ta< is Completed>> Test is Completed Modifikation mit Helpers Eingabe Wert Modifikation Ausgabe cn=agroup,ou=groups,o=demo <#0d<hlp_grp_description>> A Group Description Komplexe Modifikationen Eingabe Wert Modifikation Ausgabe cn=agroup,ou=groups,o=demo <#0d<hlp_group_description> ta< [>#0d<hlp_group_cn> ta<]>> A Group Description [agroup] Eingabe Wert Modifikation Ausgabe en~en Description de~de Beschreibung fr~fr dunno <#0sa<\ de~> sb<\ >> DE Beschreibung
Konfigurationsdatei anpassen Die Konfiguration des LDAP-Datatables erfolgt über die Datei dtldap.yml Sektionen Die Konfigurationsdatei ist aufgeteilt in Folgende Sektionen: config ldap server queries queryname debug config Die Konfig Sektion ist in 2 Untersektionen unterteilt. ldap und server ldap In dieser Subsektion werden alle LDAP Parameter definiert <ipaddresse> port: <portnummer> user: <fqdn des benutzers> password: <passwort des benutzers> server In dieser Subsektion werden alle Parameter des Cache Servers definiert port: <portnummer des Servers> separator: <Separator mit welchem Multivaluefelder getrennt werden sollen> ldifsafe: <true / false soll die Ausgabe im JSON ldifsafe sein (base64 codiert) htmlsafe: <true / false soll die JSON Ausgabe HTML Safe codiert sein (Escape von Tags & Umlauten> extpath: <path to extended Files (Service Supports Filetransfer) demo: <not implemented, this should allways be no> queries Die Queries Sektion besteht aus einer Liste mit Queries, diese können beliebig benannt werden. Eine Querie entspricht einer Definition, welche Daten von welchen Objekten gecacht werden sollen. aquery01 in einer Query wird folgendes definiert:
filter: <ldap Filter, welcher benutz werden soll> basedn: <basedn, von wo an die Objekte gesucht / gecacht werden sollen> attrs: <Liste mit Attributen, welche gecacht werden sollen> Die Definition der Attribute kann um folgendes erweitert werden: Modifications: Here are the Modifications, which can be applied on an Attribute on the Helpers and the Queries Add <> after the attrname and fill in the modifications attrname<modifier> modifiers: selector: #x -> path X part (#0 = everything) vb<xxx> -> Value X from Array before transform va<xxx> -> Value X from Array after transform (has to be processed allready...) filter: e<xxxx> -> filter XXXX = equals c<xxxx> -> filter XXXX = contains rm<xxxx> ->filter XXXX = regex Macth (as Filter) xm<xxxx> -> xpath XXXX = Match (as Filter) output: rs<xxxx> -> regex xxx as Selector xs<xxxx> -> xpath XXXX = Match (as Selector) sa<xxxxx> -> Substring After xxxxx sb<xxxxx> -> Substring Before xxxxx ta<xxxxx> -> text after tb<xxxxx> -> text before helpers: d<attrname> -> Get Attr from the the Helper with the same dn Process Order: from left to Right for every # part Multiple Filters / Modifications are splitter by has to be Escaped if used as Value Output: Wenn output leer dann return = ""; Examples: 'nrflocalizeddescrs<#0sa<\ de~> sb<\ >>' get Attribute nrflocalizeddescrs get all of it #0 get all after de~ get all before Input: en~english de~deutsch fr~frensch Filter: 'nrflocalizeddescrs<#0sa<\ de~> sb<\ >>' Output: Deutsch Input: cn=xyuser,ou=users,o=companie#:#cn=zkuser,ou=users,o=companie Filter: 'member<#0d<hlp_user_fullname>>' Output: Fritz Test#:#Hans Muster