Connector für OData

Troubleshooting

Fehlermeldungen


OData Anbieter
Sollten während einer OData-Request-Verarbeitung Fehler auftreten, werden aus Sicherheitsgründen keine Fehlerdetails an den Client zurückgegeben. Stattdessen wird je nach Art des Fehlers eine Antwort mit einem entsprechenden HTTP-Fehlercode generiert. Tritt der Fehler innerhalb der Intrexx-Businesslogik auf, so enthält das Portalserver-Log unter Umständen detaillierte Fehlermeldungen. Sollte der Fehler aber schon zu Beginn der Request-Verarbeitung auftreten, gibt es zur Analyse nur die Möglichkeit, den detaillierten Fehlerbericht in die Antwort an den Client einzubetten.

Dazu muss die Log4j-Konfiguration des Intrexx Portalservers so angepasst werden, dass als Log-Level für das OData-Producer-Modul DEBUG anstatt INFO verwendet wird.

Öffnen Sie die Datei \internal\cfg\log4j.properties im Portalverzeichnis in einem Texteditor. Suchen Sie in der Datei nach der Zeile OData Producer und ändern Sie in der nächsten Zeile den Wert INFO zu DEBUG. Nach dem Speichern der Datei muss der Portalserver neu gestartet werden, um die detaillierten Fehlermeldungen zu aktivieren.

OData Konsument
Sollten während eines OData-Requests Fehler auftreten, versucht Intrexx die Fehlermeldungen aus der Antwort des Services zu ermitteln und im Browser anzuzeigen. Dies ist nicht immer in allen Fällen möglich. Für eine detailliertere Fehleranalyse bietet es sich deshalb an, das OData-Request-Tracing im Intrexx Portalserver zu aktivieren.

Request-Tracing und Fehlerprotokollierung

Bei aktiviertem Request Tracing werden sowohl die OData-Requests als auch Responses im Detail in die Intrexx-Portal-Logdatei geschrieben. Für Requests besteht ein Eintrag aus der HTTP Aktion, der URL, den Query Options, den Request-Headern und dem XML Body. Bei Antworten werden die HTTP-Header und der Response XML Body ausgegeben. Aktiviert wird das Tracing wie folgt:
  1. Öffnen Sie die Datei log4.properties aus dem Portalverzeichnis /internal/cfg mit einem Texteditor Ihrer Wahl.
  2. Navigieren Sie zum Abschnitt logging for OData und ändern Sie den Wert von INFO auf DEBUG:
    # logging for OData
    		log4j.logger.de.uplanet.lucy.server.odata.consumer=DEBUG, File
    		log4j.additivity.de.uplanet.lucy.server.odata.consumer=false
    		
  3. Führen Sie einen Neustart des Portal-Dienstes durch.
  4. Bei jeder OData Aktion werden nun die Request Details in der portal.log-Datei protokolliert.
Beispiel für einen Request/Response Tracing Eintrag:
DEBUG 2014-05-23 09:47:57,384
OData response: 
Status: 200
DataServiceVersion: 1.0;
Content-Length: 5074
Server: Microsoft-IIS/8.0
Date: Fri, 23 May 2014 07:47:57 GMT
Content-Type: application/atom+xml;charset=utf-8

<feed xml:base="http://sharepoint2013/myTest/_vti_bin/listdata.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">  
	<title type="text">MyTestAufgaben</title>
	<id>http://sharepoint2013/myTest/_vti_bin/listdata.svc/MyTestAufgaben</id>  
	<updated>2014-05-23T07:47:57Z</updated>  
	<link href="MyTestAufgaben" rel="self" title="MyTestAufgaben" />  
	<entry m:etag="W/"6"">    
		<id>http://sharepoint2013/myTest/_vti_bin/listdata.svc/MyTestAufgaben(2)</id>    
		<title type="text">MyTask</title>    
		<updated>2014-04-28T14:54:43+02:00</updated>    
		<author>      
		<name />    
		</author>    
		<link href="MyTestAufgaben(2)" rel="edit" title="MyTestAufgabenItem" />    
		<category scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" term="Microsoft.SharePoint.DataService.MyTestAufgabenItem" />    
		<content type="application/xml">      
			<m:properties>        
			<d:ID m:type="Edm.Int32">2</d:ID>        
			<d:Vorgangsname>MyTask</d:Vorgangsname>        
			<d:Anfangsdatum m:type="Edm.DateTime">2014-04-11T00:00:00</d:Anfangsdatum>        
			<d:Fälligkeitsdatum m:type="Edm.DateTime">2014-04-29T00:00:00</d:Fälligkeitsdatum>      
			</m:properties>    
		</content>  
	</entry>  
	<entry m:etag="W/"5"">    
		<id>http://sharepoint2013/myTest/_vti_bin/listdata.svc/MyTestAufgaben(3)</id>    
		<title type="text">PortalVisions 2014 - Infrastruktur</title>    
		<updated>2014-04-25T17:29:00+02:00</updated>    
		<author>      
		<name />    
		</author>    
		<link href="MyTestAufgaben(3)" rel="edit" title="MyTestAufgabenItem" />    
		<category scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" term="Microsoft.SharePoint.DataService.MyTestAufgabenItem" />    
		<content type="application/xml">      
			<m:properties>        
			<d:ID m:type="Edm.Int32">3</d:ID>        
			<d:Vorgangsname>PortalVisions 2014 - Infrastruktur</d:Vorgangsname>        
			<d:Anfangsdatum m:type="Edm.DateTime">2014-04-23T00:00:00</d:Anfangsdatum>        
			<d:Fälligkeitsdatum m:type="Edm.DateTime">2014-04-28T00:00:00</d:Fälligkeitsdatum>      
			</m:properties>    
		</content>  
	</entry>
</feed>
Um für den OData-Provider eine detaillierte Protokollierung in eine Logdatei zu aktivieren, öffnen Sie die Datei /internal/cfg/portal.wcf im Portalverzeichnis und fügen dem Abschnitt Java Additional Parameters folgende Zeile hinzu:
wrapper.java.additional.12=-Djava.util.logging.config.file= <intrexx>\org\<portal>\internal\cfg\odata\producer\logging.properties
Ersetzen Sie dabei <intrexx> und <portal> mit den Werten Ihrer Portalumgebung und führen Sie nach dem Speichern der Datei einen Neustart des Portalservers durch. Anschließend werden die OData-Anfragen inklusive Inhalt protokolliert. Weitere Einstellungen können in der Datei logging.properties vorgenommen werden.

Nicht unterstützte OData Funktionen

Während Intrexx-Unterstützung für alle wesentlichen Funktionen der OData-Spezifikation Version 2.0 anbietet, kann es unter Umständen vorkommen, dass ein Service bestimmte Funktionen nicht unterstützt. In diesem Fall kommt es entweder zu einem Fehler oder eine Abfrage liefert nicht das erwartete Ergebnis. Da die OData-Spezifikation den implementierenden Diensten einen relativ großen Spielraum bietet, was die Unterstützung von Features betrifft, kann in einem solchen Fall nur die Intrexx-Applikation derart angepasst werden, dass nur vom Service unterstützte Funktionen verwendet werden.

Beispiele für solche Fälle sind Filterdefinitionen, Seitennavigation (Pagination) oder Sortierung. Über die entsprechenden Expert Settings lassen sich problematische OData Features deaktivieren. Falls bestimmte Filterdefinitionen nicht unterstützt werden, muss der Filter in Intrexx entsprechend angepasst bzw. vereinfacht werden.

SSL-Verbindungen

Für SSL-Verbindungen zwischen dem Intrexx-Portalserver und einem OData-Service muss das Zertifikat der Certificate Authority, die das Service-Zertifikat ausgestellt hat, dem Zertifikatsspeicher des Intrexx-Portalservers hinzugefügt worden sein.

Eine Ausnahme bilden selbstsignierte Zertifikate, die nicht von einer bekannten Certificate Authority ausgestellt wurden. Um SSL-Verbindungen zu Diensten mit selbstsignierten Zertifikaten zu ermöglichen, muss in diesem Fall im Intrexx Server die Prüfung der Certificate Chain deaktiviert werden. Dies ist auf Service-Ebene über eine System Property möglich.

Öffnen Sie die Datei /internal/cfg/portal.cfg im Portalverzeichnis mit einem Texteditor und fügen Sie dem Abschnitt <environment> einen neuen <systemProperty> Eintrag hinzu:
<systemProperty name = "de.uplanet.lucy.server.odata.consumer.ssl.allowSelfSignedCerts.<SERVICE_GUID>;" value="true"/>
Der Platzhalter <SERVICE_GUID> ist mit der GUID des OData-Services zu ersetzen. Die GUID können Sie der Service-Konfigurationsdatei im Portalverzeichnis internal/cfg/odata entnehmen. Nach dem Speichern der portal.cfg Datei muss der Intrexx-Portalserver-Dienst neu gestartet werden, damit die Änderungen wirksam werden.

Beenden von Intrexx OData Sessions

Intrexx-Sitzungen, die über den OData-Provider eröffnet wurden, werden entweder durch einen automatischen Timeout oder auf Anfrage des Clients beendet. Im Fall von Timeouts wird zwischen anonymen und authentifizierten Sitzungen unterschieden. Standardmäßig wird für anonyme Sitzungen ein Timeout von 60 Sekunden verwendet, bei Benutzersitzungen wird die Sitzung nach 10 Minuten ohne Aktivität automatisch beendet. Beide Timeout-Varianten können über eine System Property eingestellt werden. Um die Default Werte zu ändern, können in der Datei internal/cfg/portal.cfg im Portalverzeichnis dem Abschnitt environment zwei neue <systemProperty> Einträge hinzugefügt werden:
<systemProperty name="de.uplanet.lucy.server.odata.producer.anonymousSessionTimeoutMilliseconds" value="70000"/>
<systemProperty name="de.uplanet.lucy.server.odata.producer.authenticatedSessionTimeoutMilliseconds" value="700000"/>
Bitte beachten Sie, dass die Werte für den Session Timeout in Millisekunden anzugeben sind. Die Änderungen werden nach einem Neustart des Portal-Dienstes übernommen.

Die zweite Möglichkeit zum Beenden einer Sitzung besteht in einem Logout-Request durch den OData Client. Dazu sendet der Client einen Request an den Server, wobei der URL mit dem Pfad $logout enden muss. Mit der im HTTP-Header als Cookie angegebenen Session ID wird die Intrexx-Session identifiziert und automatisch beendet.

Anhang

OData Spezifikation

Eine Beschreibung des OData-Protokolls sowie die OData-Spezifikation erhalten Sie hier.

OData Tools

Folgende Tools haben sich bei der Anwendungserstellung und Problemanalyse als hilfreich erwiesen:

Reverse Proxy Konfiguration

Aus technischen Gründen ist es derzeit nicht möglich, Portalserver als auch OData-Services unter dem gleichen TCP-Port zu betreiben. Daher muss für Intrexx OData-Services ein anderer Port als der Standard HTTP Port 80 (bzw. 443 für SSL Verbindungen) gewählt werden, wenn das Portal unter diesem erreichbar sein soll. Um sowohl den Portalserver als auch OData-Services unter einem einheitlichen Port zu betreiben, bietet sich der Einsatz eines Reverse Proxys an. Dabei handelt es sich um einen vorgeschalteten Webserver, der Benutzer Anfragen empfängt und auf Basis eines Regelwerks an das entsprechende Backendsystem weiterleitet. Es gibt verschiedene freie und kommerzielle Reverse Proxy Lösungen. Beispielhaft wird im Folgenden eine Implementierung mit dem freien und kostenlosen Webserver Nginx beschrieben. Es wird dabei davon ausgegangen, dass sowohl Nginx als auch der Intrexx Poralserver auf dem gleichen physischen Server installiert sind und das Portal unter dem Port 8080 und OData-Services unter Port 9090 erreichbar sind.

Die aktuelle Nginx Version können Sie unter dem URL http://nginx.org beziehen. Nach dem Entpacken der Downloaddatei befindet sich die Konfigurationsdatei nginx.conf im Unterordner /conf. Ersetzen Sie diese mit folgender Beispielkonfiguration (eine Kopie der Datei befindet sich im Installationsverzeichnis unter \adapter\odata\nginx).
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events 
{
	worker_connections  1024;
}

http 
{				
	include       mime.types;
	default_type  application/octet-stream;

	#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
	#                  '$status $body_bytes_sent "$http_referer" '
	#                  '"$http_user_agent" "$http_x_forwarded_for"';

	#access_log  logs/access.log  main;

	sendfile        on;
	#tcp_nopush     on;

	#keepalive_timeout  0;
	keepalive_timeout  65;

	#gzip  on;

	#upstream odata 
	{
		#  server 127.0.0.1:9090; #jetty
		#
	}

	#upstream intrexx 
	{
		#  server 127.0.0.1:8080; #iis/tomcat
		#
	}

	## IX/OData reverse proxy##
	server 
	{
		listen       *:80;
		#server_name  $hostname;

		#access_log  /var/log/nginx/log/www.example.access.log  main;
		#error_log  /var/log/nginx/log/www.example.error.log;
		root   html;
		index  index.html index.htm;

		## send request back to intrexx ##location /ix/ 
		{
			#rewrite /ix/(.*) /$1 break;
			proxy_pass http://127.0.0.1:8080;
			proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
			proxy_redirect off;
			proxy_buffering off;
			proxy_set_header        Host            $hostname;
			proxy_set_header        X-Real-IP       $remote_addr;
			proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header        X-Forwarded-Server $hostname;
		}

		## send request back to odata ##
		location /odata/ 
		{
			#rewrite /odata/(.*) /$1 break;
			proxy_pass http://127.0.0.1:9090;
			proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
			proxy_redirect off;proxy_buffering off;
			proxy_set_header        Host            $hostname;
			proxy_set_header        X-Real-IP       $remote_addr;
			proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header        X-Forwarded-Server $hostname;
		}
	}
}
Passen Sie die Konfigurationsdatei gegebenenfalls Ihrer System-/Netzwerkumgebung an und speichern Sie die Datei. Anschließend kann der Nginx-Server über die Datei nginx.exe im Hauptverzeichnis gestartet werden. Testen Sie die Erreichbarkeit des Intrexx Portals sowie der OData-Services unter der einheitlichen Adresse mit Port 80.

Nun sollte noch sichergestellt werden, dass eingebettete URLs in OData-Dokumenten (wie z.B. Links zu in Beziehung stehenden Datensätzen) den korrekten Endpoint URL enthalten. Normalerweise wird für die URLs der Name und Port des OData-Servers verwendet. Dieser weicht beim Einsatz eines Reverse Proxys aber vom Endpunkt-URL ab. Daher wird ein dynamischer Mechanismus benötigt, der zur Laufzeit die korrekte Endpunkt-URL für OData Adressen verwendet.

Um dies zu erreichen, sendet der Reverse Proxy Server seinen Hostname und Port über spezielle Request Header (X-Forwarded-*) an das Backend System. Dieses kann die Header auslesen und damit den für Clients relevanten URL bilden. Um den Mechanismus zu aktivieren, gibt es in der OData-Server Konfiguration den Parameter Host. Tragen Sie hier entweder [X-Forwarded] ein, um den Host aus den Request Headern zu ermitteln, oder geben Sie direkt den Hostnamen und Port im Format hostname:port des Reverse Proxys an (wodurch Header-Werte überschrieben werden).