### # specify knitr options
knitr::opts_chunk$set(echo = FALSE, results = 'asis')
### # initialize section counter
# robjSecEnum <- rqudocuhelper::SectionEnumerator$new()
### # instantiate table of abbreviation
r6ob_abbrtable <- rmddochelper::R6ClassTableAbbrev$new()

Qualitas Logo

\fcolorbox{black}{white}{ \parbox[t]{1.0\linewidth}{ \centering \fontsize{12pt}{20pt}\selectfont % \vspace*{0.5cm} %

    \hfill Umsetzungsdokumentation

    \vspace*{0.5cm} 
}

}

\vspace*{0.5cm}

\fcolorbox{black}{white}{ \parbox[t]{1.0\linewidth}{ \centering \fontsize{25pt}{40pt}\selectfont % \vspace*{0.7cm} Automated Animal Data Exchange \ Jax Webservice Prototyp \ ATDA-ASR \

    \vspace*{0.7cm} % Space between the end of the title and the bottom of the grey box
}

}

\vspace*{1cm}

\begin{center} \includegraphics[width=0.5\textwidth]{png/Pedigree.png} \end{center}

\vspace{5ex} {\centering \small \hfill \begin{tabular}{l} Peter von Rohr \ FB EDV, Qualitas AG \ Chamerstrasse 56, CH-6300 Zug \ \verb+http://www.qualitasag.ch+ \ \verb+peter.vonrohr@qualitasag.ch+
\end{tabular} }

\pagebreak

\tableofcontents

\pagebreak

r6objDocStat <- rmddochelper::R6ClassDocuStatus$new()

# r6objDocStat$set_current_status(psVersion = "0.0.901",
#                                 psStatus  = "Erstellung",
#                                 psProject = "ATDA-ASR",
#                                 psDate = "2016-07-25")
# r6objDocStat$set_current_status(psVersion = "0.0.902",
#                                 psStatus  = "Maven Projekte",
#                                 psProject = "ATDA-ASR",
#                                 psDate = "2016-07-28")
# r6objDocStat$set_current_status(psVersion = "0.0.903",
#                                 psStatus  = "Erstellen WSDL Datei",
#                                 psProject = "ATDA-ASR",
#                                 psDate = "2016-07-28")

r6objDocStat$set_current_status(psVersion = "0.0.904",
                                psStatus  = "Webservice basierend auf WSDL",
                                psProject = "ATDA-ASR",
                                psDate = "2016-08-02")

r6objDocStat$set_current_status(psVersion = "0.0.905",
                                psStatus  = "Ergebnisse von Tests mit CXF und Axis2",
                                psProject = "ATDA-ASR",
                                psDate = "2016-09-14")

r6objDocStat$set_current_status(psVersion = "0.0.906",
                                psStatus  = "Wechsel auf Eclipse Neon",
                                psProject = "ATDA-ASR",
                                psDate = "2016-09-14")

r6objDocStat$set_current_status(psVersion = "0.0.907",
                                psStatus  = "Hello World JAX-WS",
                                psProject = "ATDA-ASR",
                                psDate = "2016-09-21")

r6objDocStat$set_current_status(psVersion = "0.0.908",
                                psStatus  = "Auslagerung Anhang ins Protokoll",
                                psProject = "ATDA-ASR",
                                psDate = "2016-09-21")

r6objDocStat$set_current_status(psVersion = "0.0.909",
                                psStatus  = "GetAnimalService aus ICAR-ADE",
                                psProject = "ATDA-ASR",
                                psDate = "2016-09-27")

r6objDocStat$set_current_status(psVersion = "0.0.910",
                                psStatus  = "Bestandteile der GetAnimalResponseType aus ICAR-ADE",
                                psProject = "ATDA-ASR",
                                psDate = "2016-09-29")

r6objDocStat$include_doc_stat(psTitle = "## Dokumentenstatus")

\pagebreak

Erklärung

Dieses Dokument protokolliert die Schritte zur Erstellung eines r r6ob_abbrtable$add_abbrev(psAbbrev = "JAX-WS", psMeaning = "Java XML Webservice"). Im Projekt r r6ob_abbrtable$add_abbrev(psAbbrev = "ATDA-ASR", psMeaning = "Automatisierter Tierdatenaustausch der ASR") stellt sich bei der geplanten Zusammenarbeit mit r r6ob_abbrtable$add_abbrev(psAbbrev = "CRV", psMeaning = "Cooperative Cattle Improvement") zur Entwicklung von PlugIns für den Export von Milchmengendaten ab r r6ob_abbrtable$add_abbrev(psAbbrev = "ISM", psMeaning = "Informationssysteme der Melkanlagen") die Fragestellung nach der Implementierung eines Systems basierend auf Spezifikationen, welche als r r6ob_abbrtable$add_abbrev(psAbbrev = "WSDL", psMeaning = "Webservice Description Language") und r r6ob_abbrtable$add_abbrev(psAbbrev = "XSD", psMeaning = "XML Service Description") Dateien gegeben sind. Mit der Implementierung ist hier gemeint, dass wir die WSDL- und die XSD-Dateien als Input verwenden, um das Grundgerüst des Programmcodes für einen Server (r r6ob_abbrtable$add_abbrev(psAbbrev = "SEI", psMeaning = "Service Endpoint Interface")) und einen Client zu erzeugen. Dieses Grundgerüst wird im Wesentlichen aus Definitionen von Klassen und Methoden bestehen. Die Client-Seite soll durch die Onfarm-Plugins von CRV umgesetzt werden.

Einführung

Der Datentransfer im Projekt ATDA-ASR ist in drei Abschnitten geplant.

  1. Export der Milchmengendaten aus dem ISM mit Hilfe von Onfarm-Plugins (CRV)
  2. Transfer der exportierten Milchmengendaten vom ISM zur Datenbank
  3. Import der transferierten Daten in ARGUS

In den Abschnitten 1 und 2 wäre eine Zusammenarbeit mit CRV für uns sehr wertvoll. Insbesondere die Verwendung der PlugIns auf den ISM auf den Betrieben würde unser Projekt sehr beschleunigen. Die ISM auf den Betrieben sind Hersteller-spezifisch und müssen darum an die technischen Besonderheiten der Hersteller angepasst werden. Eine eigene Entwicklung dieser PlugIns würde den Aufwand im Projekt ATDA-ASR sehr stark erhöhen.

Gemäss r r6ob_abbrtable$add_abbrev(psAbbrev = "BvL", psMeaning = "Bert vant Land") von CRV ist im Herbst 2016 ein Projekt zur Entwicklung eines generischen APIs für die Betriebs-PlugIns geplant. Dieses Projekt soll auf den Vorgaben des Projekts r r6ob_abbrtable$add_abbrev(psAbbrev = "ICAR-ADE", psMeaning = "ICAR Animal Data Exchange") r r6ob_abbrtable$add_abbrev(psAbbrev = "ICAR", psMeaning = "International Committee for Animal Recording", pbQuote = FALSE, pbOut = FALSE) basieren. Diese Vorgaben bestehen aus einer Projektspezifikation und aus WSDL- und XSD-Dateien. Somit bekommt die automatische Code-Generierung basieren auf WSDL- und XSD-Dateien eine bestimmte Wichtigkeit.

Ein SOAP-basierter Web Service

In der Spezifikation zum Projekt ICAR-ADE wurden verschiedene Möglichkeiten für die Umsetzung eines Webservices erwähnt, aber die eigentliche Umsetzung wurde nur für die Variante eines SOAP basierten Webservices mit XML spezifiziert. Die von CRV in Aussicht gestellten PlugIns werden laut BvL auf der Spezifikation von ICAR-ADE basieren. Prinzipiell sind Webservices neutral im Bezug auf die Verwendung von Programmiersprachen. Es ist aber klar, dass die Verwendung der gleichen Programmiersprache in einem System, die Umsetzung vereinfachen sollte. Da die existierenden Webservice-Komponenten von ARGUS in Java umgesetzt wird, kommt auch hier Java zum Einsatz. Deshalb versuchen wir hier als erstes einen einfachen JAX-WS Webservice zu erstellen.

JAX-WS

JAX-WS steht für Java API für XMS Web Services und ist ein Java-API für die Erstellung von Webservices. JAX-WS wurde mit r r6ob_abbrtable$add_abbrev(psAbbrev = "EE", psMeaning = "Enterprise Edition") 5 eingeführt und ist seit Version 1.6 auch Teil der r r6ob_abbrtable$add_abbrev(psAbbrev = "SE", psMeaning = "Standard Edition"). Wie andere Java-EE APIs verwendet auch JAX-WS sogenannte Annotationen {mit @ gekennzeichnete Schlüsselwörter}, zur Vereinfachung der Entwicklung und des Deployments von Webservice-Clients und von Service-Endpunkten {Server}.

Hello World JAX-WS

Gemäss der Anleitung unter http://www.eclipse.org/webtools/jst/components/ws/1.5/tutorials/TopDownWebService/TopDownWebService.html kann für eine gegebene WSDL-Datei (http://www.eclipse.org/webtools/jst/components/ws/1.5/tutorials/TopDownWebService/srcfiles/AreaService.wsdl) ein Webservice erzeugt werden.

Die in der Anleitung gezeigten Schritte werden hier nochmals wiederholt. Die folgenden Schritte erzeugen einen JAX-WS server basierend auf einer gegebenen WSDL-Datei.

Server

Als erstes muss in Eclipse ein Dynamic Web Project erstellt werden. Dieses Projekt beinhaltet nachher den Serverteil des Webservice.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "NewDynamicWebProject")

In das Verzeichnis WebContent wird die WSDL-Datei von http://www.eclipse.org/webtools/jst/components/ws/1.5/tutorials/TopDownWebService/srcfiles/AreaService.wsdl importiert.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "ImportWsdlDatei")

Basierend auf der importierten WSDL-Datei wird nun der Webservice erzeugt.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "NewOtherWebservice")

Innerhalb des Web Service-Fensters werden die Default-Werte übernommen.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "WebServiceWizard")

Die nächsten Fenster werden mit Next durchlaufen. Dabei wird der Applikationsserver gestartet und die nötigen Ergänzungen zum Projekt gemacht. Als Resultat wird die Implementationsklasse des Services im Editor geöffnet. Diese Implementation muss noch angepasst werden damit wirklich die Fläche berechnet wird. Die Anpassung besteht darin den Return-Wert von $-3$ durch den Ausdruck parameters.getHeight()*parameters.getWidth() zu ersetzen.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "AdaptationServiceImpl")

Client

Unter http://www.eclipse.org/webtools/jst/components/ws/1.5/tutorials/WebServiceClient/WebServiceClient.html ist beschrieben, wie ein Client zum oben erstellten Server erstellt wird.

Die folgenden Schritte wiederholen die Anleitung zur Erstellung des Clients.

  1. Auswahl der Datei AreaServiceSOAP.wsdl. WICHTIG ist, dass wir nicht die Datei AreaService.wsdl, welche wir zur Erstellung des Servers verwendet hatten, auswählen.
rmddochelper::insertOdgAsPdf(psOdgFileStem = "AreaServiceSOAP")
  1. Erstellen des Webservice Clients über den Wizard
rmddochelper::insertOdgAsPdf(psOdgFileStem = "WebserviceClientWizard")

Danach erscheint das Web Service Client-Fenster in welchem der Client konfiguriert werden kann. Den Slider schieben wir ganz hoch bis der Status Test client erscheint. Danach wird unter dem Link Client project das Projekt angegeben, welches den Client beherbergen soll.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "WebserviceConfiguration")

Die verbleibenden Fenster können mit Next durchlaufen werden und dann sollte als Resultat die folgende Webseite angezeigt werden.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "WebseiteResultat")

Im Fenster Methods klickt man auf calculateRectArea. Dann können Inputs eingegeben werden. Der Service funktioniert auch über die Eingabe des URI http://localhost:8080/AreaProjClient/sampleAreaServiceProxy/TestClient.jsp in einem Browser.

In Eclipse kann der Client-Test jeder Zeit wieder gestartet werden, indem durch einen Rechtsklick auf TestClient.jsp in AreaProjCleint > WebContent > sampleAreaServiceProxy und dann Run As > Run on Server auswählt.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "TestClientRunOnServer")

Nächste Schritte

In einem nächsten Schritt geht es darum die gleiche Prozedur für eine WSDL-Datei zu machen, welche aus dem Projekt ICAR-ADE kommt. Da die vollständige WSDL-Datei sehr umfangreich ist, versuchen wir zuerst mit einer minimalen Version mit einem Test-Service für Milchleistungsdaten einen Server zu erstellen.

Sobald der Server-Prototyp steht, wird der nächste Schritt die Anbindung an eine Datenbank sein, welche die übermittelten Werte speichert.

JAX-WS SEI für ein Beispiel-Service aus ICAR-ADE

Da die Übertragung der Milchleistungsdaten in ICAR-ADE mit einem sehr ausgedehnten Service umgesetzt sind, wurde der Service GetAnimal als einfacheres Bespiel ausgewählt. Das folgende Vorgehen ist geplant.

  1. Aus der WSDL-Datei (wsMrAde.wsdl) wird der Service GetAnimal extrahiert und es wird daraus eine neue WSDL-Datei erstellt (wsMrAdeGetAnimal.wsdl).
  2. Die abhängigen Definitionen werden angepasst.
  3. Die Namespacebezeichnungen werden angepasst. ICARAggregateBusinessInformationEntity:1.1 wird zu ICARAggregateBusinessInformationEntity,
  4. Fehler mit inkonsistenten Namespacebezeichungen, beispielsweise sc::SpecieCodeType versus clmICARSpecieCode:SpecieCodeType
  5. In der WSDL-Datei (wsMrAdeGetAnimal.wsdl) wurde ein neuer r r6ob_abbrtable$add_abbrev(psAbbrev = "xmlns", psMeaning = "XML namespace") definiert und dem Namespace des Haupt-Schemas (ADE_GetAnimal.xsd) zugewiesen.
  6. Wie oben beschrieben wurde der Webservice generiert.

Resultat des mit Apache Axis generierten Servers

Als Resultat wird folgendes Gerüst für den Server aufgebaut. Die Vielzahl der unter dem Punkt "Java Resources/src" gezeigten Java-Pakete wurden alle aus den XSD/WSDL-Dateien erzeugt.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "IcarAdeSkeletonSei")

Der rote Pfeil im obigen Diagramm zeigt auf die Klasse BasicHttpBinding_wsMrAdeInterfaceImpl, in welcher die Implementation des Servers eingefügt werden muss. Diese Klasse hat eine öffentliche Methode getAnimal, welche als Parameter ein Objekt vom Typ GetAnimalRequestType bekommt und als Resultat ein Objekt vom Typ GetAnimalResponseType zurückgeben muss.

Für die Implementationsmethode getAnimal ist also das GetAnimalRequestType-Objekt der Input und das GetAnimalResponseType-Objekt der Output. Beide Objekte können wir uns in Eclipse graphisch darstellen lassen. Die Struktur des Inputs GetAnimalRequestType sieht wie folgt aus.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "GetAnimalRequestType")

Die analoge Darstellung für den Output GetAnimalResponseType ist hier im Anschluss gezeigt.

rmddochelper::insertOdgAsPdf(psOdgFileStem = "GetAnimalResponseType")

Implementation

Aus den Informationen im Input von GetAnimalRequestType und zusätzlichen Informationen, zum angeforderten Tier soll der Output vom Typ GetAnimalResponseType erzeugt werden. Der Output GetAnimalResponseType besteht aus drei Komponenten

  1. MessageHeader vom Typ ADEExchangedDocumentType
  2. StandardResponse vom Typ StandardResponseType
  3. SpecificResponseGetAnimal vom Typ SpecificResponseGetAnimalType

MessageHeader

Der MessageHeader ist vom Typ ADEExchangedDocumentType. Dieser Datentyp ist in der Spezifikation im Abschnitt 3.10.1 beschrieben. Der Aufbau dieses Typs ist im folgenden Diagramm dargestellt.

Der Typ ADEExchangedDocumentType enthält die folgenden Komponenten:

rmddochelper::insertOdgAsPdf(psOdgFileStem = "ADEExchangedDocumentTypeDiagram")

SenderParty und RecipientParty sind beide vom Typ ADEPARTYTYPE, welcher von ICAR-ADE definiert wurde (siehe 3.10.2 in der Spezifikation). Der Einfachheit halber wird die RecipientParty der Response von der Senderparty des Requests übernommen. Die SenderParty der Response wird aus einer neu geschriebenen Generatorklasse namens QualitasSenderPartyGenerator generiert.

Die Komponente Identifier wird über die neu geschriebene Generatoren-Klasse AnimalResponseIdGenerator erzeugt. Die Sprache und die RecipientParty wurden vom Request übernommen und als Datum wird das aktuelle Datum eingetragen.

StandardResponse

Die Komponente StandardResponse ist vom Typ StandardResponseType. Der Typ StandardResponseType besteht seinerseits aus den drei Komponenten

  1. RequestProcessingStatus vom Typ rpsc:RequestProcessingStatusCodeType: Status der Verarbeitung nach der Codeliste RequestProcessingStatusCode
  2. RequestID vom Typ udt:IDType: Kopie der Nachrichten-Id im Header der Request-Nachricht
  3. RequestProcessingError vom Typ icar:ErrorType: Fehlerbeschreibung
rmddochelper::insertOdgAsPdf(psOdgFileStem = "StandardResponseTypeDiagram", pnPaperWidthScale = 0.6)

Die Fehlerbeschreibung RequestProcessingError ist vom Typ icar:ErrorType

rmddochelper::insertOdgAsPdf(psOdgFileStem = "ErrorTypeDiagram")

Die Komponenten ErrorID und ErrorDescription sind beide vom Typ TextType, welche einfach mit einem String erzeugt werden können. Die ErrorSeverity ist eine Integer-Zahl welche den Grad des Fehlers bezeichnet.

SpecificResponse

The third part consists of the SpecificResponse of type SpecificResponseGetAnimalType. This type contains three sub-types consisting of

  1. TicketResponse of type TicketResponseType
  2. AnimalMessage of type AnimalDescriptionType
  3. GetAnimalResponseZipMessage of type ZipMessageType
rmddochelper::insertOdgAsPdf(psOdgFileStem = "SpecificResponseGetAnimalTypeDiagram")
if (!r6ob_abbrtable$is_empty_abbr())
  r6ob_abbrtable$writeToTsvFile()

\pagebreak

r6ob_abbrtable$include_abbr_table(psAbbrTitle = "## Abkürzungen")


pvrqualitasag/AadeJaxWsPrototypeDocu documentation built on May 26, 2019, 11:33 a.m.