Middleware im Schweinsgalopp 1
Szenario Unternehmen verwendet SAP als ERP-System wickelt Versand über Dienstleister, hier UPS ab UPS bietet Verfolgung der Lieferung über Web- Schnittstelle Daten im ERP (z.b. Auftrag) und beim Dienstleister müssen abgeglichen werden Verschiedene Lösungswege 2
Separate Clients SAP GUI SAP Browser Spezieller Client für jede Anwendung Abgleich erfolgt manuell (copy-paste,...) Probleme: Effizienz, Konsistenz usw. UPS 3
Spezieller Client Client SAP Client Client Client Spezieller Client für diese Anwendung UPS integriert die Daten Probleme: Aufwand Für jede mögliche Anwendung muss neuer Client entwickelt werden (und installiert, gewartet,...) 4
Integration SAP-GUI SAP UPS Kopplung zwischen den (Server-) Systemen SAP greift auf Daten aus Fremdsystem zu Problem: Programmierung (auf Server) nötig Wie kommunizieren die verschiedenen Systeme? 5
Middleware Techniken zur Kopplung von Systemen Selbst gebastelt (Text, TCP/IP sockets, FTP,...) RPC (Remote Procedure Call) CORBA (Common Object Request Broker Architecture) COM+ (Common Object Model,.NET) RMI (Remote Method Invocation) XML-RPC SOAP (Simple Object Access Protocol) Web Services usw. 6
RMI Remote Method Invocation 7
Wir haben Komponenten auf einem Rechner Komp1 Komp2 8
Wir wollen zwei Rechner Komp1 Komp2 TCP/IP aber wie? 9
allgemein K1 Proxy Proxy K2 TCP/IP Client spricht nicht mit dem Server, sondern mit (Proxy-) Objekt, das die gleiche Schnittstelle hat wie das Server-Objekt. Für K2 sieht es aus, als ob ein Aufruf vom Proxy kommt --> K1 und K2 müssen nicht modifiziert werden (außer Verbindungsaufbau) Proxy kümmert sich um Kommunikation 10
Proxy überträgt Parameter (Objekte) übers Netz Serialisierung kümmert sich um Probleme wie: Verbindungsabbruch Übertragungsfehler Verschlüsselung verschiedene Transportmechanismen möglich Datenkonvertierung (hier nicht nötig, da alles Java) vgl. CORBA wird generiert: muß nicht programmiert werden 11
Vorgehen Schnittstelle definieren Java Interface keine eigene Sprache (vgl. CORBA) Schnittstelle implementieren (Server) Proxy erzeugen Wie finden Clients das Server-Objekt? registry Server muß angemeldet werden Beispiel: komplexe Berechnung 12
Schnittstelle import java.rmi.*; public interface Rechner extends Remote { public int compute(int par) throws RemoteException; } interface, keine Klasse muß public sein erweitert Remote jede Methode kann RemoteException werfen (Fehler auf der anderen Seite) 13
Implementierung import java.rmi.*; import java.rmi.server.*; public class RechnerImpl extends UnicastRemoteObject implements Rechner { // Default-Konstruktor muss implementiert werden // (kann RemoreException werfen public RechnerImpl() throws RemoteException { } public int compute(int par) throws RemoteException { return par+1; } } 14
Proxy erzeugen $> rmic RechnerImpl $> ls Rechner.class Rechner.java RechnerImpl.class RechnerImpl.java RechnerImpl_Skel.class RechnerImpl_Stub.class *_Stub ist der Proxy auf Client-Seite *_Skel ist der Dispatcher auf Server-Seite Quellcode behalten mit rmic -keep 15
Dateien K1 Proxy Proxy K2 RMI RechnerClient RechnerImpl_Stub RechnerImpl_Skel RechnerImpl 16
Anmerkung: IDL #include "orb.idl" #ifndef Rechner #define Rechner interface Rechner { long compute( in long arg0 ); }; #pragma ID Rechner "RMI:Rechner:0000000000000000" #endif rmic -idl Rechner erzeugt (CORBA-) IDL RMI kann über IIOP (Internet Inter Orb Protocol) aufgerufen werden 17
Registry+Server starten mit: rmiregistry Standard-Port: 1099 dann: Server registrieren: import java.rmi.*; import java.rmi.server.*; public class RechnerServer { public static void main(string args[]) { try { // Naming.bind() bindet nur einmal, sonst Fehler // Naming.rebind() ersetzt ggf. Bindung Naming.rebind("rmi://localhost/Rechner",new RechnerImpl()); } catch (Exception e) { e.printstacktrace(); } } } 18
Client holt sich die Referenz zum Remote-Objekt von der registry und los gehts import java.rmi.*; public class RechnerClient { public static void main(string args[]) { try { Rechner r = (Rechner) Naming.lookup("rmi://localhost/Rechner"); int ergebnis = r.compute(3); System.out.println(ergebnis); } catch (Exception e) {e.printstacktrace(); } } } et voila 19
Web services in 21 Minuten 20
Wir haben... K1 Proxy Proxy K2 RMI 21
Probleme RMI ist Java-spezifisch CORBA nicht, aber komplex komplexe Programmierung Kommunikation durch Firewalls RMI z.b. Port 1099 (normal zu) konkurrierende Standards 22
Idee Browser Webserver Servlet- Engine Servlet Servlet Servlet Servlet Browser schickt Anfrage (mit Parametern) an Servlet und kriegt generierte Antwort; wenn Browser = Client (-Programm) Engine = ORB Servlet = Server (Objekt) HTTP- = Funktionsparameter Parameter dann RPC 23
Schwierigkeiten Parameter nicht typisiert Ergebnis nicht strukturiert Statuscode + irgendwas (z.b. Text) keine (standardisierte) Fehlerbehandlung Lösung. Anfrage + Antwort als XML XML-RPC SOAP 24
SOAP Frage: <?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <SOAP-ENV:Body> <ns1:getbestand xmlns:ns1="http://www.tillh.de/"> <ArtikelNr xsi:type="xsd:string">4711</artikelnr> </ns1:getbestand> </SOAP-ENV:Body> </SOAP-ENV:Envelope> und Antwort <?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <SOAP-ENV:Body> <ns1:getbestandresponse xmlns:ns1="http://www.tillh.de/"> <result xsi:type="xsd:int">127</result> </ns1:getbestandresponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 25
wie? unabhängig von Plattform Programmiersprache Transport-Protokoll (HTTP, SMTP,...) trotzdem mühsam (von Hand) zu programmieren verschiedene Tools für Client und Server hier: apache axis 26
Server public class StoreService { public int getbestand(string ProductID) { Bestand b = new Bestand(); // rechnen... return 42; } } als.jws Datei im axis webapps-verzeichnis speichern Now for step 2... hm, wait a minute. You're done [axis User guide: http://ws.apache.org/axis/java/user-guide.html] 27
Client mal einfacher: require 'soap/rpc/driver' proxy = SOAP::RPC::Driver.new( "http://localhost:8080/axis/storeservice.jws", "http://localhost:8080/axis/storeservice.jws") proxy.add_method('getbestand', 'ID') puts "verfuegbar: #{proxy.getbestand("2")}" (ruby) 28
Client contd. mal komplizierter: public class getbestand { public static void main(string[] args) throws Exception { try { String ProductID = "2"; URL endpoint = new URL("http://localhost:8080/axis/StoreService.jws"); Service s = new Service(); Call c = (Call) s.createcall(); c.settargetendpointaddress(endpoint); c.setoperationname("getbestand"); Object[] params = new Object[] {ProductID}; Integer bestand = (Integer) c.invoke(params); System.out.println("Bestand fuer Produkt " + ProductID + ": " + bestand); } catch (Exception e) { e.printstacktrace(); } } } (Java) 29
Web services Web Services Security 56 UsernameToken Profile 15 X.509 Certificate Token Profile 16 Policy Language 13 Trust Language 41 Secure Conversation Language 17 Web Services Federation Language 28 WS-Federation: Active Requestor Profile 14 WS-Federation: Passive Requestor Profile 13 Kerberos Binding 17 Reliable Messaging 21 Coordination 16 Atomic Transaction 10 Business Activity Framework 13 WSDL 1.1 32 Policy Framework 15 Policy Attachment 10 Policy Assertions Language 9 Dynamic Discovery 22 Metadata Exchange 23 SOAP 1.2 Primer 39 SOAP 1.2 Messaging Framework 47 SOAP 1.2 Adjuncts 25 Addressing 15 MTOM 13 Enumeration 27 Eventing 21 Transfer 17 SOAP-over-UDP 7 Web Services for Management 23 BPEL4WS 74 Devices Profile 24 WS-I Basic Profile 50 The Internet RFC 791 (IP) 45 RFC 793 (TCP) 84 RFC 1034 (DNS) 55 RFC 1738 (URL) 25 RFC 1939 (POP3) 23 RFC 2616 (HTTP) 176 RFC 2821 (SMTP) 79 RFC 2822 (IMF) 51 some core standards with page count [http://www.tbray.org/ongoing/when/200x/2004/09/21/ws-research] 30
Einschub: REST Representational State Transfer Architecture HTTP Webserver Resourcen Client Darstellung der Resource, z.b. HTML-Darstellung eines Datensatzes in DB (nicht () der Datensatz selbst) Darstellungen der Ressourcen (üblicherweise XML) werden bewegt/manipuliert (verschiedene HTTP-Methoden ) Beispiel: GET /warenkorb/4711 31
HTTP-Methoden GET: Darstellung der Resource lesen POST: Resource ändern PUT: Resource erzeugen DELETE: Resource löschen HEAD: Metadaten lesen Idee: Server hat Resourcen, die über URI identifiziert werden. Funktion durch HTTP-Methode. Interaktion ist stateless (Skalierbarkeit ) 32
Objekte als Resourcen [http://www.oio.de/public/xml/rest-webservices.htm] 33
Beispiel: google calendar 34
mit API CalendarService myservice = new CalendarService("tillh-webcal-1"); myservice.setusercredentials("haenisch@ba-heidenheim.de", "geheim"); new EventFeed().declareExtensions(myService.getExtensionProfile()); EventFeed myfeed = myservice.getfeed(feedurl, EventFeed.class); EventEntry calentry = null; if (myfeed.getentries().size() > 0) { for (int n = 0; n < myfeed.getentries().size(); n++) { calentry = (EventEntry) myfeed.getentries().get(n); System.out.println("calEntry.getTitle().getPlainText()); } } } 35
Beispiel rails rails stellt Resourcen mit REST als default-schnittstelle zur Verfügung 36
Beispiel: strongloop (Node.js) 37
Beispiel: strongloop http://strongloop.com/wp-content/uploads/2013/12/strongloop-dec-5-loopback-webinar.pdf 38
Warum? http://strongloop.com/wp-content/uploads/2013/12/strongloop-dec-5-loopback-webinar.pdf 39