### # 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()
\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
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.
Der Datentransfer im Projekt ATDA-ASR ist in drei Abschnitten geplant.
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.
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 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}.
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.
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")
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.
AreaService.wsdl
, welche wir zur Erstellung des Servers verwendet hatten, auswählen.rmddochelper::insertOdgAsPdf(psOdgFileStem = "AreaServiceSOAP")
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")
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.
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.
sc::SpecieCodeType
versus clmICARSpecieCode:SpecieCodeType
r r6ob_abbrtable$add_abbrev(psAbbrev = "xmlns", psMeaning = "XML namespace")
definiert und dem Namespace des Haupt-Schemas (ADE_GetAnimal.xsd) zugewiesen. 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")
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
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:
Identifier
: Identität der Nachricht generiert durch den SenderIssueing
: Datum und Uhrzeit, wann Nachricht erzeugt wurde.Version
: VersionsnummerLanguage
: Sprache der NachrichtLocalAdditionalData
: Optionale zusätzliche DAtenSenderParty
: Organisation oder Person, welche für den Inhalt verantwortlich istRecipientParty
: Organisation oder Person, welche für die Verarbeitung der Nachricht zuständig ist.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.
Die Komponente StandardResponse
ist vom Typ StandardResponseType
. Der Typ StandardResponseType
besteht seinerseits aus den drei Komponenten
RequestProcessingStatus
vom Typ rpsc:RequestProcessingStatusCodeType
: Status der Verarbeitung nach der Codeliste RequestProcessingStatusCode
RequestID
vom Typ udt:IDType
: Kopie der Nachrichten-Id im Header der Request-NachrichtRequestProcessingError
vom Typ icar:ErrorType
: Fehlerbeschreibungrmddochelper::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.
The third part consists of the SpecificResponse
of type SpecificResponseGetAnimalType
. This type contains three sub-types consisting of
TicketResponse
of type TicketResponseType
AnimalMessage
of type AnimalDescriptionType
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")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.