Implementierungsdetails des ArmClientTransportHandler


\begin{lstlisting}[caption={C++ Klasse ArmClientTransportHandler}, numbers=left,...
...L onFault(void* pvIMsg);
int AXISCALL invoke(void* pvIMsg);
};
\end{lstlisting}
Wie man schon im Klassendiagramm gesehen hat, muss der eigene Handler von der Klasse Handler erben und die abstrakten Methoden der Schittstellenklasse BasicHandler implementieren. Die Methoden init() und fini() werden jeweils vor der eigentlichen Ausführung und nach der eigentlichen Ausführung aufgerufen. Code, der für das Aufräumen nach der Ausführung bestimmt ist, sollte in der fini() Methode stehen. Es ist nicht sicher, wann der Destruktor aufgerufen wird. Die Methode onFault() wird im Fehlerfall von der Axis Engine aufgerufen. Hier sollte implementiert werden, was beim Auftreten einer Exception geschehen soll. Die eigentliche Verarbeitung in einem Handler findet in der invoke Methode statt. Die Methoden init(), fini() und onFault() werden hier nicht betrachtet.
Wie man in vorherigen Kapiteln gesehen hat, ist es nicht notwendig, jeweils einen eigenen Handler für den request flow und den response flow zu schreiben. Dafür besteht in der invoke Methode die Möglichkeit zu prüfen, wo man sich gerade befindet.

\begin{lstlisting}[caption={C++ Grundgerüst der invoke Methode}, numbers=left, f...
...uestFlow
else
{
// responseFlow
}
return AXIS_SUCCESS;
}
\end{lstlisting}

In der Abbildung sieht man das Grundgerüst der invoke Methode. Als Parameter bekommt man hier einen Zeiger auf void übergeben, welchen man auf ein IMessageData Zeiger casten muss. Hinter diesem Zeiger steckt dann das in Java als MessageContext bezeichnete Objekt. Mit der Methode isPastPivot() kann man dann prüfen, ob man das Pivot Element (Wendepunkt der Nachricht) schon passiert hat oder nicht. In diesem Fall wird im request flow der Code innerhalb des if Zweigs ausgeführt und im response flow der Code innerhalb des else Zweigs.
Wie der Zugriff auf die Name-Value Paare, die im Deployment Deskriptor mit übergeben wurden, realsisiert wird, zeigt das folgende Listing.

\begin{lstlisting}[caption={C++ Zugriff auf die Parameter vom WSDD File}, number...
...n)
{
name = this->getOption(\uml {A}pplicationName);
}
...
\end{lstlisting}
Die Variable m_pOption ist ein Zeiger vom Typ einer STL map. Diese ist in der Klasse Handler mit scope protected deklariert. Damit erbt man diese im Handler. Falls keine Parameter im Deployment Deskriptor übergeben werden, ist die map nicht initialisiert. Der Aufruf von getOption() endet also in einem Segmentation Fault. Aufgrund dieses Verhaltens sollte man immer erst prüfen, ob die Variable initialisiert worden ist. Gibt man mindestens einen Parameter im Deployment Deskriptor mit, dann wird die map initialisiert, und der Aufruf der Methode getOption(), auch mit einem Parameter den es nicht gibt, endet nicht in einem Segmentation Fault, sondern man bekommt einen leeren String.

Im nachfolgenden Listing sieht man, wie das Problem gelöst wird, das man nur eine ARM Applikation innerhab eines Prozesses erzeugt.

\begin{lstlisting}[caption={C++ Setzen und Auslesen von Propertys im IMessageDat...
...pplicationId, applicationId,
sizeof(*applicationId));
}
...
\end{lstlisting}
Es wird in den Propertys des IMessageData Objekts nachgeschaut ob, das Property vorhanden ist. Ist dies nicht der Fall, wird eine neue ARM Applikation erzeugt. Die von der ARM Library erhaltene applicationId wird dann mittels der Methode setComplexProperty() abgelegt und ist für alle nachfolgenden Handler verfügbar.


\begin{lstlisting}[caption={C++ hinzufügen eines SOAP Header Elements}, numbers=...
...de->setValue(val);
\par
pIHeaderBlock->addChild(basicNode);
...
\end{lstlisting}
Hier kann man sehr schön sehen, was dazu notwendig ist, den ARM Correlator base64 codiert im Header abzulegen. In Zeile 7 wird mit Hilfe der Axis API-Funktion der Correlator base64 codiert und in einem String abgespeichert. Ab Zeile 10 wird der Header Block angelegt und der lokale Name und die URI vergeben. In Zeile 19 wird ein neues Kindelement im Header angelegt und der base64 codierte Correlator darin abgelegt. Das sind die notwendigen Schritte um einen SOAP Header unter Axis anzulegen und zu erweitern.

Thomas Termin 2005-02-24