de.bsvrz.dav.daf.communication.protocol
Class ClientHighLevelCommunication

java.lang.Object
  extended by de.bsvrz.dav.daf.communication.protocol.ClientHighLevelCommunication
All Implemented Interfaces:
HighLevelCommunicationCallbackInterface

public class ClientHighLevelCommunication
extends Object
implements HighLevelCommunicationCallbackInterface

Das Modul Protokollsteuerung ist das Bindeglied der Komponente Kommunikation zwischen den Modulen Telegrammverwaltung und Verwaltung. Es stellt für die Interaktion mit dem Datenverteiler eine Funktionsschnittstelle zur Verfügung, die die technischen Aspekte der Kommunikation gegenüber der Verwaltung kapselt und implementiert die Abbildung auf Telegramme und Kommunikationsabläufe. Die Protokollsteuerung grenzt sich zur Telegrammverwaltung ab, weil hier die aus Sicht der Datenverteiler-Applikationsfunktionen speziellen und nicht wiederverwendbaren Funktionen der Kommunikation mit dem Datenverteiler enthalten sind. Folgende Funktionen und Abläufe werden in der Protokollsteuerung implementiert:

Author:
Kappich Systemberatung

Nested Class Summary
private  class ClientHighLevelCommunication.SendControlNotifier
          Asynchrone Verarbeitung von empfangenen Sendsteuerungstelegrammen.
 
Field Summary
private  long _applicationId
          Die Applikation Id
private  CacheManager _cacheManager
          Der Cache-Manager (Teil der Verwaltung).
private  ApplicationCloseActionHandler _closer
          Das Objekt, das für das Schliessen nach Auftritt eines Fehlers zuständig ist.
private  ConfigurationManager _configurationManager
          Der Konfigurationsmanager (Teil der Verwaltung).
private  DavConnectionListener _connectionListener
          Beobachter für Zustandsänderungen der Datenverteilerverbindung.
private  int _dafVersion
          Die eingestellte Protokollversion
private static Debug _debug
          Der Debug-Logger.
private  boolean _disconnecting
          Wird beim ersten Aufruf von terminate(...) gesetzt.
private  boolean _disconnectingOnError
          Wird beim ersten Aufruf von terminate(true, ...) gesetzt.
private  long _localConfigurationId
          Die lokale Konfiguration Id
private  long _localDVId
          Die lokale Datenverteiler-Id
private  boolean _readyForConfigDependantData
          Hält die Informationen über den Initialisierungszustand dieser Komponente.
private  ClientHighLevelCommunication.SendControlNotifier _sendControlNotifier
          Asynchrone Verarbeitung von empfangenen Sendsteuerungstelegrammen
private  SubscriptionManager _subscriptionManager
          Der Anmeldemanager (Teil der Verwaltung).
private  List<DataTelegram> _syncSystemTelegramList
          Temporäre Liste der Systemtelegramme für interne Synchronisationszwecke.
private  long _userId
          Die Id des Benutzers
private  ClientConnectionProperties properties
          Die Kommunikationseingenschaften
private  SplittedApplicationTelegramsTable splittedTelegramsTable
          Temporäre Liste der zerstückelten Telegramme.
 
Constructor Summary
ClientHighLevelCommunication()
          Dieser Konstruktor wird für JUnit-Tests gebraucht.
ClientHighLevelCommunication(ClientDavParameters clientDavParameters, ApplicationCloseActionHandler closer)
          Dieser Konstruktor erzeugt eine Instanz dieser Klasse mit den übergebenen Parametern.
 
Method Summary
private  AuthentificationAnswer authentify(byte[] encryptedUserPassword)
          Schickt ein Authentifikations-Telegramm zum Datenverteiler und wartet auf seine Antwort.
 void completeInitialisation(ConfigurationManager configurationManager, CacheManager cacheManager, SubscriptionManager subscriptionManager)
          Schließt die Initialisierung ab.
 void connect()
          Die Methode erstellt eine logische Verbindung zum Datenverteiler, d.
 void disconnected(boolean error, String message)
          Wird von der unteren Kommunikationsschicht in Fehlersituationen zum Abbruch der Kommunikationsverbindung aufgerufen.
 long getApplicationId()
          Gibt die Id der Applikation zurück.
private  AuthentificationTextAnswer getAuthentificationText()
          Schickt ein AuthentifikationsText-Telegramm zum Datenverteiler und wartet auf seine Antwort.
private  ComParametersAnswer getComParameters()
          Schickt ein ComParameter-Telegramm zum Datenverteiler und wartet auf seine Antwort.
 long getConfigurationId()
          Gibt die Id der Konfiguration zurück.
 ClientConnectionProperties getConnectionProperties()
          Diese Methode gibt die Eigenschaften dieser Verbindung zurück.
private  DataTelegram getDataTelegram(long maximumWaitingTime, byte telegramType)
          Diese Methode dient dem reduzieren von doppeltem Code.
 long getDataTransmitterId()
          Gibt die Id des Datenverteilers zurück.
private  ProtocolVersionAnswer getProtocolVersions()
          Schickt ein Protokollversions-Telegramm zum Datenverteiler und wartet auf seine Antwort.
 List<DataTelegram> getSyncSystemTelegramList()
          Gibt die temporäre Liste der Systemtelegramme für interne Synchronisationszwecke zurück.
 long getTelegramTime(long maxWaitingTime)
          Schickt ein Laufzeitermittlungs-Telegramm zum Datenverteiler und wartet auf seine Antwort, um herauszubekommen, wie viel Zeit die Übertragung in Anspruch nimmt.
 long getUserId()
          Gibt die Id des Benutzers zurück.
private  void notifyConnectionClosed()
          Wird die Verbindung zum Datenverteiler terminiert, so wird dem Beobachter, der sich dafür interessiert, dieses mitgeteilt.
 void sendData(SendDataObject dataToSend)
          Versendet ein Applikationsdatentelegramm an den Datenverteiler.
 void sendReceiveSubscription(ReceiveSubscriptionInfo subscription)
          Es wird ein Empfangsanmeldungstelegramm erstellt und zum Datenverteiler gesendet.
 void sendReceiveUnsubscription(BaseSubscriptionInfo unsubscription)
          Es wird ein Empfangsabmeldungstelegramm erstellt und zum Datenverteiler gesendet.
 void sendSendSubscription(SendSubscriptionInfo subscription)
          Es wird ein Sendeanmeldetelegramm erstellt und zum Datenverteiler gesendet.
 void sendSendUnsubscription(BaseSubscriptionInfo unsubscription)
          Es wird ein Sendeabmeldetelegramm erstellt und zum Datenverteiler gesendet.
 void setCloseHandler(ApplicationCloseActionHandler closer)
          Setzt den ApplicationCloseActionHandler dieser Subkomponente.
 void setConnectionListener(DavConnectionListener connectionListener)
          Meldet einen Beobachter für Zustandsänderungen der Datenverteilerverbindung an.
 void setReadyForConfigDependantData()
          Diese Methode wird vom Anmeldungsmanager aufgerufen, nachdem die Anmeldungen erfolgreich abgeschlossen sind, die eine gerichtete Kommunikation mit der Konfiguration gewährleisten.
 void terminate(boolean error, String message)
          Die bestehende Verbindung zum Datenverteiler wird terminiert, und der Kommunikationskanal wird geschlossen.
 void terminate(boolean error, String message, DataTelegram terminationTelegram)
           
 void update(DataTelegram telegram)
          Wird von der unteren Kommunikationsschicht nach Empfang eines Telegramms aufgerufen. Erhält ein Aktualisierungsdatum vom Datenverteiler.
 void updateConfigData(SendDataObject receivedData)
          Wenn ein neues Konfigurationstelegramm angekommen ist, wird es an die Verwaltung weitergeleitet.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_debug

private static final Debug _debug
Der Debug-Logger.


_dafVersion

private int _dafVersion
Die eingestellte Protokollversion


_userId

private long _userId
Die Id des Benutzers


_applicationId

private long _applicationId
Die Applikation Id


_localConfigurationId

private long _localConfigurationId
Die lokale Konfiguration Id


_localDVId

private long _localDVId
Die lokale Datenverteiler-Id


_configurationManager

private ConfigurationManager _configurationManager
Der Konfigurationsmanager (Teil der Verwaltung).


_cacheManager

private CacheManager _cacheManager
Der Cache-Manager (Teil der Verwaltung).


_subscriptionManager

private SubscriptionManager _subscriptionManager
Der Anmeldemanager (Teil der Verwaltung).


_syncSystemTelegramList

private final List<DataTelegram> _syncSystemTelegramList
Temporäre Liste der Systemtelegramme für interne Synchronisationszwecke.


splittedTelegramsTable

private SplittedApplicationTelegramsTable splittedTelegramsTable
Temporäre Liste der zerstückelten Telegramme.


_readyForConfigDependantData

private boolean _readyForConfigDependantData
Hält die Informationen über den Initialisierungszustand dieser Komponente.


_disconnecting

private volatile boolean _disconnecting
Wird beim ersten Aufruf von terminate(...) gesetzt.


_disconnectingOnError

private volatile boolean _disconnectingOnError
Wird beim ersten Aufruf von terminate(true, ...) gesetzt.


_closer

private ApplicationCloseActionHandler _closer
Das Objekt, das für das Schliessen nach Auftritt eines Fehlers zuständig ist.


properties

private ClientConnectionProperties properties
Die Kommunikationseingenschaften


_connectionListener

private DavConnectionListener _connectionListener
Beobachter für Zustandsänderungen der Datenverteilerverbindung.


_sendControlNotifier

private ClientHighLevelCommunication.SendControlNotifier _sendControlNotifier
Asynchrone Verarbeitung von empfangenen Sendsteuerungstelegrammen

Constructor Detail

ClientHighLevelCommunication

public ClientHighLevelCommunication(ClientDavParameters clientDavParameters,
                                    ApplicationCloseActionHandler closer)
                             throws CommunicationError,
                                    ConnectionException
Dieser Konstruktor erzeugt eine Instanz dieser Klasse mit den übergebenen Parametern. ClientDavParameters enthält die Adresse und Subadresse des Datenverteilers, spezifiziert das zu verwendende Protokoll durch dessen Namen. ApplicationCloseActionHandler bestimmt wie die Applikationsfunktion auf einen Kommunikationsfehler reagieren soll.

ClientConnectionProperties werden erzeugt, die die Eigenschaften dieser Verbindung verkörpern. Sie spezifizieren insbesondere den AuthentificationProcess, das für die Passwortverschlüsselung zuständige Verfahren. Weiter enthalten sie die PID der Konfiguration.

Ein Systemtelegramm ProtocolVersionRequest wird gebildet und zum Datenverteiler gesendet. Es enthält Angaben über die unterstützte Protokollversion. Auf die Antwort wird eine festgelegte Zeit gewartet (maximale Wartezeit auf synchrone Antworten). Wenn die Antwort nicht innerhalb diese Zeit an-gekommen ist oder die Protokollversion vom Datenverteiler nicht unterstützt wird, dann wird eine CommunicationError-Ausnahme erzeugt.

Parameters:
clientDavParameters - Parameterklasse für die Datenverteiler-Applikationsfunktionen
closer - bestimmt, wie die Applikationsfunktionen auf einen Kommunikationsfehler reagieren soll
Throws:
CommunicationError - Wenn die Verhandlung der Protokollversion nicht durchgeführt wurde oder die Protokollversion nicht unterstützt wird.
ConnectionException - Wenn die Verbindung über die Telegrammverwaltung fehlschlägt.

ClientHighLevelCommunication

public ClientHighLevelCommunication()
Dieser Konstruktor wird für JUnit-Tests gebraucht.

Method Detail

completeInitialisation

public final void completeInitialisation(ConfigurationManager configurationManager,
                                         CacheManager cacheManager,
                                         SubscriptionManager subscriptionManager)
Schließt die Initialisierung ab. Diese Methode wird von ClientDavConnection aufgerufen. Es werden Referenzen auf den Konfigurationsmanager, den Cache-Manager und den Anmeldungsmanager festgehalten. Zusätzlich wird eine Referenz auf ClientHighLevelCommunication an den Anmeldungsmanager übergeben.

Parameters:
configurationManager - der Konfigurationsmanager
cacheManager - der Cache-Manager
subscriptionManager - der Anmeldungsmanager

getApplicationId

public long getApplicationId()
Gibt die Id der Applikation zurück.

Returns:
die Id der Applikation

getDataTransmitterId

public final long getDataTransmitterId()
Gibt die Id des Datenverteilers zurück.

Returns:
die Id des Datenverteilers

getConfigurationId

public final long getConfigurationId()
Gibt die Id der Konfiguration zurück.

Returns:
die ID der Konfiguration

getUserId

public final long getUserId()
Gibt die Id des Benutzers zurück.

Returns:
die ID des Benutzers

setReadyForConfigDependantData

public final void setReadyForConfigDependantData()
Diese Methode wird vom Anmeldungsmanager aufgerufen, nachdem die Anmeldungen erfolgreich abgeschlossen sind, die eine gerichtete Kommunikation mit der Konfiguration gewährleisten. Dadurch signalisiert der Anmeldungsmanager die Bereitschaft, Datensätze zu empfangen, die Konfigurationsdaten benötigen, um interpretiert zu werden.


setCloseHandler

public final void setCloseHandler(ApplicationCloseActionHandler closer)
Setzt den ApplicationCloseActionHandler dieser Subkomponente. Dieser bestimmt wie die Applikationsfunktion auf einen Kommunikationsfehler reagieren soll.

Parameters:
closer - ApplicationCloseActionHandler

connect

public final void connect()
                   throws InconsistentLoginException,
                          CommunicationError
Die Methode erstellt eine logische Verbindung zum Datenverteiler, d. h. die Authentifizierung der Applikation und das Einstellen der Kommunikationsparameter wird durchgeführt, damit der Austausch von Daten sicher durchgeführt werden kann. Ein AuthentificationTextRequest-Telegramm mit der Konfigurations-PID wird über die Telegrammverwaltung zum Datenverteiler gesendet, um einen Schlüssel für die Authentifizierung anzufordern. Auf die Antwort AuthentificationTextAnswer wird eine gewisse Zeit gewartet (maximale Wartezeit auf synchrone Antworten). Mit dem vom Datenverteiler erhaltenen Schlüssel wird das Benutzerpasswort durch den AuthentificationProcess verschlüsselt und als AuthentificationRequest zum Datenverteiler gesendet. Auch hier wird eine gewisse Zeit auf die Antwort AuthentificationAnswer gewartet (maximale Wartezeit auf synchrone Antworten). Wenn die Authentifizierung erfolgreich ist, werden die Ids der Applikation, des Datenverteilers, der Konfiguration und des Benutzers übertragen und von dieser Subkomponente festgehalten. Wird als Id der Konfiguration -1 zurückgegeben, so war die spezifizierte PID dem System nicht bekannt. Sonst werden die Keep-alive-Parameter und die Durchsatzprüfungsparameter mit dem Datenverteiler verhandelt. Ein ComParametersRequest wird zum Datenverteiler gesendet. Auch hier wird auf die Antwort ComParametersAnswer eine gewisse Zeit gewartet (maximale Wartezeit auf synchrone Antworten).

Throws:
InconsistentLoginException - Wenn die Authentifizierung nicht erfolgreich abgeschlossen werden konnte.
CommunicationError - Wenn eine Antwort nicht innerhalb einer parametrierten Zeit vom Datenverteiler beantwortet wird oder wenn als Id der Konfiguration eine -1 ermittelt wird.

sendReceiveSubscription

public void sendReceiveSubscription(ReceiveSubscriptionInfo subscription)
Es wird ein Empfangsanmeldungstelegramm erstellt und zum Datenverteiler gesendet.

Parameters:
subscription - die Empfangsanmeldeinformationen

sendReceiveUnsubscription

public final void sendReceiveUnsubscription(BaseSubscriptionInfo unsubscription)
Es wird ein Empfangsabmeldungstelegramm erstellt und zum Datenverteiler gesendet.

Parameters:
unsubscription - die Empfangsabmeldeinformationen

sendSendSubscription

public void sendSendSubscription(SendSubscriptionInfo subscription)
Es wird ein Sendeanmeldetelegramm erstellt und zum Datenverteiler gesendet.

Parameters:
subscription - die Sendeanmeldeinformationen

sendSendUnsubscription

public final void sendSendUnsubscription(BaseSubscriptionInfo unsubscription)
Es wird ein Sendeabmeldetelegramm erstellt und zum Datenverteiler gesendet.

Parameters:
unsubscription - die Sendeabmeldeinformationen

sendData

public final void sendData(SendDataObject dataToSend)
Versendet ein Applikationsdatentelegramm an den Datenverteiler. Falls der zu sendende Datensatz größer ist, als die im System gesetzte maximale Länge eines Telegramms, wird er in Teiltelegramme zerstückelt und zum Datenverteiler gesendet.

Parameters:
dataToSend - die zu sendenden Daten als Bytefeld vorbereitet

terminate

public final void terminate(boolean error,
                            String message)
Die bestehende Verbindung zum Datenverteiler wird terminiert, und der Kommunikationskanal wird geschlossen. Wenn der Parameter error gesetzt ist, wird die close-Methode vom ApplicationCloseActionHandler aufgerufen.

Parameters:
error - Ist true, wenn die Verbindung im Fehlerfall abgebrochen werden soll, ohne die noch gepufferten Telegramme zu versenden; false, wenn versucht werden soll alle gepufferten Telegramme zu versenden.
message - Fehlermeldung, die die Fehlersituation näher beschreibt.

terminate

public final void terminate(boolean error,
                            String message,
                            DataTelegram terminationTelegram)

disconnected

public void disconnected(boolean error,
                         String message)
Description copied from interface: HighLevelCommunicationCallbackInterface
Wird von der unteren Kommunikationsschicht in Fehlersituationen zum Abbruch der Kommunikationsverbindung aufgerufen.

Specified by:
disconnected in interface HighLevelCommunicationCallbackInterface
Parameters:
error - true signalisiert eine Fehlersituation der unteren Kommunikationsschicht.
message - Fehlermeldung, die die Fehlersituation näher beschreibt.

update

public final void update(DataTelegram telegram)
                  throws InterruptedException
Wird von der unteren Kommunikationsschicht nach Empfang eines Telegramms aufgerufen. Erhält ein Aktualisierungsdatum vom Datenverteiler. Diese Methode wird von der LowLevelCommunication aufgerufen, wenn ein neues Telegramm angekommen ist. Sie reagiert nur auf die Telegramme, die für die Applikation von Interesse sind.

Neu ankommende Telegramme werden je nach Typ unterschiedlich weiterverarbeitet:

Wenn das Telegramm vom Typ AuthentificationTextAnswer, AuthentificationAnswer, ComParametersAnswer, ProtocolVersionAnswer oder TelegramTimeAnswer ist, wird es in eine Liste eingefügt und eine Broadcast-Nachricht an alle wartenden Methoden gesendet. Diese überprüfen ob die Nachricht für sie relevant ist. In diesem Falle wird sie aus der Liste entfernt und bearbeitet.
Wenn das Telegramm vom Typ TelegramTimeRequest ist, wird anhand der übergebenen gemessene Zeit ein TelegramTimeAnswer gebildet und zum Datenverteiler gesendet.
Wenn das Telegramm vom Typ RequestSenderDataTelegram ist, wird die Methode notifySenderApplication des Anmeldungsmanagers aufgerufen, um die Applikation zu benachrichtigen.
Wenn das Telegramm vom Typ ApplicationDataTelegram ist, wird zunächst überprüft, ob ein zerstückeltes Telegramm vorliegt. Ist dies der Fall, dann wird es in eine Liste eingefügt und überprüft ob alle Teiltelegramme vorhanden sind. Sind alle vorhanden, wird aus den Telegrammen ein SendDataObject erzeugt, das weiterverarbeitet werden kann. Wenn das Telegramm nicht zerstückelt ist, wird es sofort in ein SendDataObject zur Weiterbearbeitung umgewandelt. Wenn dieses erfolgreich erzeugt wurde, wird anhand seiner Basisanmeldeinformation überprüft, ob es eine Antwort einer Konfigurationsanfrage ist. Ist dies der Fall, so wird das Telegramm der update-Methode des Konfigurations-Managers übergeben, wenn nicht, handelt es sich um ein Online-Telegramm und es wird an die update-Methode des Cache-Managers übergeben.
Wenn das Telegramm vom Typ ClosingTelegram oder TerminateOrderTelegram ist, wird die Methode terminate(boolean, java.lang.String) aufgerufen.

Jeder andere Telegrammtyp wird ignoriert.

Specified by:
update in interface HighLevelCommunicationCallbackInterface
Parameters:
telegram - Das empfangene Telegramm
Throws:
InterruptedException - Wenn der Thread während eines blockierenden Aufrufs unterbrochen wurde

updateConfigData

public final void updateConfigData(SendDataObject receivedData)
Description copied from interface: HighLevelCommunicationCallbackInterface
Wenn ein neues Konfigurationstelegramm angekommen ist, wird es an die Verwaltung weitergeleitet.

Specified by:
updateConfigData in interface HighLevelCommunicationCallbackInterface
Parameters:
receivedData - das Konfigurationstelegramm

getConnectionProperties

public final ClientConnectionProperties getConnectionProperties()
Diese Methode gibt die Eigenschaften dieser Verbindung zurück.

Returns:
die Eigenschaften dieser Verbindung

getProtocolVersions

private ProtocolVersionAnswer getProtocolVersions()
Schickt ein Protokollversions-Telegramm zum Datenverteiler und wartet auf seine Antwort.

Returns:
Die Protokollversion-Telegramm-Antwort des Datenverteilers oder null, falls die Antwort nicht ermittelt werden konnte.

getDataTelegram

private DataTelegram getDataTelegram(long maximumWaitingTime,
                                     byte telegramType)
Diese Methode dient dem reduzieren von doppeltem Code. Aus einer Telegrammliste wird das gewünschte Telegramm herausgesucht und zurückgegeben.

Parameters:
maximumWaitingTime - die gewünschte maximale Wartezeit
telegramType - den gewünschten Telegramm-Typ
Returns:
das gesuchte Telegramm

getAuthentificationText

private AuthentificationTextAnswer getAuthentificationText()
Schickt ein AuthentifikationsText-Telegramm zum Datenverteiler und wartet auf seine Antwort.

Returns:
Die AuthentifikationsText-Telegramm-Antwort des Datenverteilers oder null, falls sie nicht ermittelt werden konnte.

authentify

private AuthentificationAnswer authentify(byte[] encryptedUserPassword)
Schickt ein Authentifikations-Telegramm zum Datenverteiler und wartet auf seine Antwort.

Parameters:
encryptedUserPassword - das verschlüsselte Passwort des Benutzers
Returns:
Die Authentifikations-Telegramm-Antwort des Datenverteilers oder null, falls die Antwort nicht ermittelt werden konnte.

getComParameters

private ComParametersAnswer getComParameters()
Schickt ein ComParameter-Telegramm zum Datenverteiler und wartet auf seine Antwort.

Returns:
Die ComParameter-Telegramm-Antwort des Datenverteilers oder null, falls die Antwort nicht ermittelt werden konnte.

getTelegramTime

public final long getTelegramTime(long maxWaitingTime)
                           throws CommunicationError
Schickt ein Laufzeitermittlungs-Telegramm zum Datenverteiler und wartet auf seine Antwort, um herauszubekommen, wie viel Zeit die Übertragung in Anspruch nimmt.

Parameters:
maxWaitingTime - Zeit in Millisekunden, die maximal auf eine Antwort gewartet wird.
Returns:
Die Zeit, die benötigt wurde, um ein Telegramm von der Applikation zum Datenverteiler und zurück zu senden oder -1 falls innerhalb der angegebenen Timeout-Zeit keine Antwort empfangen wurde.
Throws:
CommunicationError - Falls die Verbindung zum Datenverteiler gestört ist.

setConnectionListener

public void setConnectionListener(DavConnectionListener connectionListener)
Meldet einen Beobachter für Zustandsänderungen der Datenverteilerverbindung an.

Parameters:
connectionListener - Beobachter für Zustandsänderungen der Datenverteilerverbindung

notifyConnectionClosed

private void notifyConnectionClosed()
Wird die Verbindung zum Datenverteiler terminiert, so wird dem Beobachter, der sich dafür interessiert, dieses mitgeteilt.


getSyncSystemTelegramList

public List<DataTelegram> getSyncSystemTelegramList()
Gibt die temporäre Liste der Systemtelegramme für interne Synchronisationszwecke zurück.

Returns:
die Liste der Systemtelegramme