AMETAS.servicedev
Class AMETASSyncServiceProxy

java.lang.Object
  extended byAMETAS.event.AMETASEventHandler
      extended byAMETAS.servicedev.AMETASServiceProxy
          extended byAMETAS.servicedev.AMETASSyncServiceProxy
All Implemented Interfaces:
AMETASEventHandlerIf, java.io.Serializable

public abstract class AMETASSyncServiceProxy
extends AMETASServiceProxy

Diese Klasse implementiert einen klassischen Proxy für die Nutzung eines AMETAS-Dienstes. Das Problem bei der Dienstnutzung ist der relativ umständliche Umgang mit Dienstaufrufen. Diese Aufruf müssen natürlich über Agentennachrichten erfolgen. D.h. der Klient muß sich zuerst die ID des Dienstes vom Dienstvermittler der Stelle besorgen, dann muß er geeignete Nachrichten basteln, sie im PostOffice ablegen und auf die Antwort warten. Dieser Ganze Vorgang kann zurecht als etwas umständlich, unintuitiv und fehleranfällig bezeichnet werden. Zudem muß jeder Klient diese Schritte selbst implementieren, so daß große Teile des Codes jedes Klienten für die Bearbeitung von Dienstaufrufen zuständig sind, obwohl diese Schritte für alle Klienten gleich aussehen. Wünschenswert wäre die Möglichkeit, einen Dienst so nutzen zu können, als sei er ein lokales Objekt, auf dem man einfach eine Methode aufruft. Hier kommt der Proxy ins Spiel. Er kapselt die Details eines Dienstaufrufes über Agentennachrichten weitgehend und verbirgt die Aufrufe hinter Methoden. Der Klient ruft also eine Methode auf dem Proxy auf, welche die Aufrufparameter geeignet verpackt, eine Nachricht generiert, diese an den Dienst schickt, auf die Antwort wartet, diese entpackt und die entsprechenden Daten dem Aufrufer zurückgibt. Jeder AMETASSyncServiceProxy besitzt eine bestimmte Basisfunktionalität, welche von dieser Basisklasse implementiert wird. Die dienstspezifischen Funktionen müssen in entsprechenden Subklassen zu dem speziellen Dienst implementiert werden. Am einfachsten ist dies, wenn der Dienstentwickler den Proxy gleich mitliefert. Dieser kann ein Agent instantiieren und verwenden. Achtung : Ein AMETASServiceProxy ist nicht Thread-Safe! Aufrufe auf dem Proxy sind also immer von Stellennutzer-Thread (Treiber-Thread) zu machen. Jeder Stellennutzer besitzt neben seinem eigentlichen Thread, dem Treiber-Thread, noch einen zweiten, einen AMETASEventNotificator. Dieser dient zur Benachrichtigung des Stellennutzers über das Auftreten von Ereignissen. Dieser Thread ruft, falls der Stellennutzer entsprechend als EventListener registriert ist, eine handle-Methode auf, die der Stellennutzer bereitstellen muß (siehe AMETAS-Tutorial für weitere Informationen). Theoretisch könnte innerhalb dieser handle-Methode ebenfalls ein Aufruf auf dem Proxy-Objekt gemacht werden. Dies könnte dazu führen, daß beide Threads gleichzeitig eine Methode aufrufen. In diesem Fall liefern beide Aufrufe undefinierte Ergebnisse zurück! Dies gilt auch, wenn beide gleichzeitig unterschiedliche Dienstmethoden des Proxies aufrufen! Wenn eine Dienstmethode als Reaktion auf ein Ereignis aufgerufen werden soll, so sollte in der handle-Methode der Treiber-Thread informiert werden (z.B. über Member-Variablen des Stellennutzers) und daraufhin selbst aktiv werden. Davon abgesehen ist es sowieso fragwürdig, langwierige Aktonen direkt in einer handle-Methode auszuführen. Durch diese wird nämlich der AMETASEventNotificator blockiert! Dies führt dazu, daß weitere Ereignisse nicht zugestellt werden können. Wenn ein Stellennutzer also in einer handle-Methode z.B. eine Endlosschleife startet, dann wird er nie wieder Ereignisse bekommen! Also: handle-Methode immer so kurz wie möglich fassen!

Der Mechanismus

Noch ein Wort zum Mechanismus, den der Proxy verwendet, um Aufrufe zu tätigen und auf Ergebnisse zu warten. Eine Dienstmethode eines AMETASSyncServiceProxy, die vom Proxy-Entwickler zu implementieren ist, macht generell folgendes:

Damit der Proxy die Nachricht, in der die Dienstantwort steckt, empfangen kann, ist er als AMETASEventHandler implementiert. Der Stellennutzer instantiiert den Proxy und initialisiert ihn über init. In init werden alle Aktionen durchgeführt, die nötig sind, damit der Proxy die Antwortnachrichten des Dienstes erhält. Hierzu muß der Agent ein AMETASNotifiableAgent (oder, wenn der Proxy von einer Benutzeradapter verwendet wird, ein AMETASNotifiableUserAdapter) sein. Der Proxy erhält daraufhin, in seiner Eigenschaft als EventHandler alle Nachrichten von dem anzusprechenden Dienst.

Since:
Version 2.1.0
See Also:
Serialized Form

Field Summary
protected  long m_lTimeout
          Die Zeit in Millisekunden, nach der ein Aufruf als gescheitert gilt, falls keine Antwort gekommen ist.
protected  AMETASMessageID m_midRequestID
          Hier wird die Nachrichten-ID der Anfragenachricht vor dem Absenden abgelegt.
 
Fields inherited from class AMETAS.servicedev.AMETASServiceProxy
m_aobjResponseBody, m_drvClientDriver, m_idService, m_mesResponse, m_puClient, m_puidClientID, m_sResponseTypeSpec, m_sServiceName, NO_SERVICE_NAME, OK, SERVICE_NOT_FOUND
 
Constructor Summary
AMETASSyncServiceProxy(AMETASPlaceUser puClient, AMETASPlaceUserDriverIf drvClientDriver)
          Konstruktor.
 
Method Summary
protected  void depositRequestAndWait(java.lang.Object[] aobjParams)
          Legt eine Anfragenachricht ab.
 boolean handleServiceMessage(java.lang.String sTypeSpec, java.lang.Object[] aobjBody, AMETASMessage mes)
          Empfängt die Antworten des Dienstes.
 void setTimeout(long lTimeout)
          Setzt das Timeout, das beim Dienstaufruf eingehalten werden soll.
 
Methods inherited from class AMETAS.servicedev.AMETASServiceProxy
cleanup, depositRequest, getServiceID, getServiceName, init, init, output, setServiceName
 
Methods inherited from class AMETAS.event.AMETASEventHandler
handleApplicationMessage, handleCustomMessage, handleMessageEvent, handleMessageMessage, handlePlaceEvent, handlePlaceMessage, handlePlaceUserEvent, handleSecurityMessage, handleTradingMessage
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

m_lTimeout

protected long m_lTimeout
Die Zeit in Millisekunden, nach der ein Aufruf als gescheitert gilt, falls keine Antwort gekommen ist. Empfängt der Proxy keine Antwort innerhalb dieser Zeit, so wirft die aufgerufene Methode eine ProxyTimeoutException.


m_midRequestID

protected transient AMETASMessageID m_midRequestID
Hier wird die Nachrichten-ID der Anfragenachricht vor dem Absenden abgelegt. Diese kann dann mit der Nachrichten-ID im ReplyTo-Feld einer Antwortnachricht verglichen werden. So kann sichergestellt werden, daß die erhaltene Antwort auch eine Antwort auf die abgesendete Anfrage ist.

Constructor Detail

AMETASSyncServiceProxy

public AMETASSyncServiceProxy(AMETASPlaceUser puClient,
                              AMETASPlaceUserDriverIf drvClientDriver)
Konstruktor.

Parameters:
puClient - Das Stellennutzerobjekt des Klienten, zu übergeben als this
drvClientDriver - Der Treiber des Klienten
Method Detail

setTimeout

public void setTimeout(long lTimeout)
Setzt das Timeout, das beim Dienstaufruf eingehalten werden soll.

Parameters:
lTimeout - Timeout in Millisekunden.

depositRequestAndWait

protected void depositRequestAndWait(java.lang.Object[] aobjParams)
                              throws ProxyTimeoutException
Legt eine Anfragenachricht ab. Die Nachricht wird mit Standardparametern ausgestattet, und erhält als Nutzlast die übergebenen Anfrageparameter.

Parameters:
aobjParams - Die Nutzlast der Anfragenachricht.
Throws:
ProxyTimeoutException - falls ein Timeout auftritt bevor die Antwort des Dienstes eingetroffen ist.

handleServiceMessage

public boolean handleServiceMessage(java.lang.String sTypeSpec,
                                    java.lang.Object[] aobjBody,
                                    AMETASMessage mes)
Empfängt die Antworten des Dienstes. Die Antwortnachricht wird in m_mesResponse abgelegt, bevor der Treiber-Thread aufgeweckt wird. vctBodyData wurde bereits von der ersten Typspezifikation (REQUEST) befreit.

Specified by:
handleServiceMessage in interface AMETASEventHandlerIf
Overrides:
handleServiceMessage in class AMETASEventHandler
Parameters:
sTypeSpec - Die Typspezifikation der Antwortnachricht
aobjBody - Die Nutzlast der Antwortnachricht
mes - Die Antwortnachricht selbst
Returns:
true, falls die eingehende Nachricht von dieser Methode verarbeitet wurde, false sonst
See Also:
AMETASMessage