JavaScript in SAP HANA Das Schöne und das Biest? Dr. Ralph Guderlei JAX 2014 Agenda 2| ● Serverseitiges Javascript ● SAP HANA vs. Node.js ● Fazit Titel Anpass en unter Typische Anwendung Web Mobile REST Geschäftslogik Datenbank 3| Titel Anpass en unter … Warum Serverseitiges Javascript? 4| ● Reduzierung der Anzahl der verwendeten Sprachen ● Interessante Features von JavaScript insb. Funktionale Konzepte ● Effiziente Umsetzung von Projekten ● hohe Geschwindigkeit der Innovation ● Performance z.B. durch Async/Non-blocking IO Titel Anpass en unter Node.js ● ● 5| Erstes Release: Mai 2009 Runtime : Google v8 ● Server für TCP, DNS, HTTP, … ● Single-Threaded Event Loop ● Non-blocking IO ● Viele Module (ca. 70.000) ● Open Source Titel Anpass en unter Node.js – ME(A)N Stack ● ● ● Node.js Service-Frameworks ● REST: Restify/express ● OData: Jaydata Datenhaltung ● Mongoose ● MongoDB ● ● ● 6| UI: Angular.js Utilities ● Q ● lodash Titel Anpass en unter SAP Hana ● Erstes Release: November 2010 ● SpaIten-orientierte In-Memory Datenbank ● Repository, Staging-Mechanismus ● ● 7| Javascript-Runtime (XS Engine) ● Engine: Spidermonkey ● API/Library basiert auf JQuery kommerziell Titel Anpass en unter Vergleichsszenarien ● Tooling ● „normale“ REST-Services ● ODATA ● ● 8| Geschäftslogik ● Abfragen ● Transformation von Daten Infrastruktur ● Security Titel Anpass en unter Node.js - Tooling ● ● ● ● 9| Primär Command Line-basiert Etablierte Tools: ● NPM (Node Package Manager) ● Grunt (Task runner, vergleichbar mit Ant) ● Viele gute Testtools (Jasmine, Karma) IDE-Unterstützung ● IntelliJ Idea ● Visual Studio Instabilität: „Jeder Tag ein neues Buildsystem“ Titel Anpass en unter SAP Hana - Arbeitsweise ● Integrierte Toolchain auf Eclipse-Basis ● Editoren für Javascript, SQLScript … ● Interaktion mit Repository und Staging Titel Anpass en 10 | unter HANA Studio Node.js – REST-Services Routendefinition server.post('/items', items.create); // url with path param server.get('/items/:itemId', items.fetchOne); // versioned url via AcceptVersion header server.get({path: '/items', version: '1.0.0'}, items.listV1); Callback exports.fetchOne = function (req, res, next) { model.items.findById(req.params.itemId, function (err, data) { assert.ifError(err); res.send(data); return next(); }); }; Titel Anpass en 12 | unter SAP Hana – REST-Services mit XSJS Titel - Anpassen unter Ansicht|Kopf-/Fußzeile query = 'SELECT NAME, DATEN FROM "RepairService.data::ZORIGINALDOKUMENT" WHERE QMNUM = ?'; preparedStatement = connection.prepareStatement(query); preparedStatement.setNString(1, meldungsnummer); var rs = preparedStatement.executeQuery(); var body = '['; while (rs.next()) { if (!first) { body += ','; first = false; } body += '{ "name" : "' + rs.getNString(1) + '", "data" : "'; body += base64ArrayBuffer(rs.getBlob(2)) + '" }'; } body += ']'; $.response.contentType = 'application/json'; $.response.setBody(body); $.response.status = $.net.http.OK; 13 | ODATA ● Open Data Access Protocol ● Entwickelt von Microsoft ● Basiert auf AtomPub ● Alternativen: Gdata, RDF ● Versuch einer semantischen Standardisierung von REST-Services ● „SOAP für REST-Services“ ● Erleichtert durch die Standardisierung die (automatisierte) Verwendung von REST-Services Titel Anpass en 14 | unter ODATA – Beispiel Metadaten <edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0"> <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="2.0"> <Schema xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/05/edm" Namespace="reparatur.services"> <EntityType Name="KundenType"> <Key> <PropertyRef Name="KUNNR"/> </Key> <Property Name="KUNNR" Type="Edm.String" Nullable="false" MaxLength="10"/> <Property Name="LAND1" Type="Edm.String" Nullable="false" MaxLength="3"/> <Property Name="NAME1" Type="Edm.String" Nullable="false" MaxLength="35"/> <Property Name="ORT01" Type="Edm.String" Nullable="false" MaxLength="35"/> <Property Name="PSTLZ" Type="Edm.String" Nullable="false" MaxLength="10"/> <Property Name="STRAS" Type="Edm.String" Nullable="false" MaxLength="35"/> <Property Name="APART" Type="Edm.String" Nullable="false" MaxLength="40"/> </EntityType> <EntityContainer Name="kunden" m:IsDefaultEntityContainer="true"> <EntitySet Name="Kunden" EntityType="reparatur.services.KundenType"/> </EntityContainer> </Schema> </edmx:DataServices> </edmx:Edmx> Titel Anpass en 15 | unter Odata – Beispiel Nutzdaten <feed xml:base="http://54.83.207.87:8000/RepairService/services/kunden.xsodata/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom"> <title type="text">Kunden</title> <id>http://somehost:8000/RepairService/services/kunden.xsodata/Kunden</id> <author> <name/> </author> <link rel="self" title="Kunden" href="Kunden"/> <entry> <id>http://somehost:8000/RepairService/services/kunden.xsodata/Kunden('1')</id> <title type="text"></title> <author> <name/> </author> <link rel="edit" title="Kunden" href="Kunden('1')"/> <content type="application/xml"> <m:properties> <d:KUNNR m:type="Edm.String">1</d:KUNNR> <d:LAND1 m:type="Edm.String">DE</d:LAND1> <d:NAME1 m:type="Edm.String">Kunde1</d:NAME1> <d:ORT01 m:type="Edm.String">Ulm</d:ORT01> <d:PSTLZ m:type="Edm.String">89073</d:PSTLZ> <d:STRAS m:type="Edm.String">Beim Alten Fritz 1</d:STRAS> <d:APART m:type="Edm.String">Ansprechpartner 1</d:APART> </m:properties> </content> </entry> </feed> Node.js OData Server require('odata-server'); $data.Entity.extend("Todo", { Id: { type: "id", key: true, computed: true }, Task: { type: String, required: true, maxLength: 200 }, DueDate: { type: Date }, Completed: { type: Boolean } }); $data.EntityContext.extend("TodoDatabase", { Todos: { type: $data.EntitySet, elementType: Todo } }); $data.createODataServer(TodoDatabase, '/todo', 52999, 'localhost'); SAP HANA – ODATA-Service service namespace "reparatur.services" { "JAX_DEMO"."RepairService.data::ZGERAETE" as "Geraete"; } Titel Anpass en 18 | unter Node.js - Datentransformation Stream – API ermöglicht UNIX-artige Pipeline - Konstrukte model.tests.find({_id: {$in: result}}) .lean() .batchSize(1000) .stream() .pipe(someTransformation) .pipe(anotherTransformation) .pipe(res); Titel Anpass en 19 | unter SAP HANA - Datentransformationen Sprache: SQL Script ● l l Wizzards zum Erstellen von Views im Hana Studio CREATE PROCEDURE ProcWithResultView(IN id INT, OUT o1 CUSTOMER) LANGUAGE SQLSCRIPT READS SQL DATA WITH RESULT VIEW ProcView AS BEGIN o1 = SELECT * FROM CUSTOMER WHERE CUST_ID = :id; END l l Titel Anpass en 20 | unter Node.js - Security ● Authentifizierung / Authorisierung über NPM-Modul ● z.B. Passport.js ● Typischerweise HTTP Authentication oder OpenID/OAuth Titel Anpass en 21 | unter SAP HANA - Security ● Integriertes Rechte/Rollen-Konzept ● Single-Sign-On via Kerberos/SAML ● Integrierter Auditing Trail bis auf Datenbank-Ebene Titel Anpass en 22 | unter All together now Node – Hana – Modul: client.prepare('call * from DUMMY where X = ?', function (err, statement){ if (err) { return console.error('Error:', err); } statement.exec([1], function (err, rows) { if (err) { return console.error('Error:', err); } res.send(JSON.stringify(rows)); return next(); }); }); Node.js – Pros & Cons ● ● ● ● ● Großes Open Source – Ökosystem Leichtgewichtige Entwicklung Gute Performance Dynamische Entwicklung CPU-intensive Aufgaben limitieren Performance (node ist single threaded) Titel Anpass en 24 | unter SAP Hana – Pros & Cons ● ● ● ● ● ● ● ● Odata-Support Viele Standards Gutes Tooling Integrierte Lösung Lizenzkosten Hardware-Bundle Widersprüchliche Dokumentation zu SapUI5 im Netz ungewöhnliches Doku-Format (PDF) Titel Anpass en 25 | unter Danke für Ihre Aufmerksamkeit! [email protected] | @rguderlei Demo am Stand von eXXcellent Solutions Titel Anpass en 26 | unter