FreshRSS

🔒
✇ Developer-Blog - Der Pragmatische Architekt

Wo bin ich?

Von heise online — 26. Februar 2018 um 10:00

zurück zum Artikel

Für die meisten mobilen Geräte ist das Ermitteln der geographischen Position eine grundlegende Funktion. GNSS-Dienste wie GPS, Galileo, GLONASS, Beidou erlauben es, den aktuellen Ort mittels Satelliten zu bestimmen. Hierbei steht GNSS für Global Navigation Satellite System. Entsprechende Empfänger befinden sich inzwischen standardmäßig in Fahrzeugen, Smartphones, Kameras, Tablets, Drohnen oder Industriesteuerungen. Wie aber lässt sich eigene Hardware um diese Funktionalität erweitern?

GPS Faktencheck

GPS (Global Positioning System, ursprünglich NAVSTAR GPS, gibt es inzwischen schon seit den Siebziger Jahren. Insgesamt 24 Satelliten mit mittlerem Orbit von 20.200 km über der Erdoberfläche umkreisen unseren Planeten zweimal täglich. Je mindestens vier Satelliten bewegen sich dabei auf einer von sechs Bahnebenen, die 55 Grad gegen die Äquatorlinie geneigt sind. Dadurch sollen GPS-Empfänger zu jedem Zeitpunkt wenigstens vier Satelliten empfangen können. Nur mit Hilfe von vier Satelliten ist eine exakte Messung mit einer Fehlerabweichung von unter 10 Metern möglich.

Alle Satelliten senden diverse Information auf verschiedenen Frequenzen. Sie enthalten Atom- beziehungsweise Cäsium-Uhren, um eine genaue Zeit zusätzlich zur eigenen Position verschicken zu können. Diese Zeit berücksichtigt keine Schaltsekunden und weicht daher inzwischen rund 18 Sekunden von der koordinierten Weltzeit UTC ab, weshalb GPS-Empfänger die eigene Zeit entsprechend berechnen müssen. Aus den erhaltenen Daten kann der GPS-Empfänger unter anderem seine eigene Position, Bewegungsrichtung, Höhe und Geschwindigkeit ermitteln. Wissenswert am Rande ist die Tatsache, dass die GPS-Komponente wegen der hohen Geschwindigkeit von Satelliten relativ zum GPS-Empfänger relativistische Effekte berücksichtigen muss, weil sonst die Abweichung erheblich wäre.

Bewegung der GPS-Satelliten um die Erde. Schwarze Punkte haben Kontakt zum blauen Bezugspunkt auf der Erdoberfläche. Quelle: Wikipedia
Die Abbildung zeigt Bewegung der GPS-Satelliten um die Erde. Schwarze Punkte haben Kontakt zum blauen Bezugspunkt auf der Erdoberfläche. (Bild: wikipedia.org)
GPS-Module

Bei der Suche nach dem Stichwort „GPS module“ im Internet ergeben sich zahlreiche Treffer. Für Elektronikprojekte mit Arduino oder Raspberry Pi bieten die Neo 6M (oder 7M) - Bausteine des Schweizer Herstellers u-blox ein gutes Preis-/Leistungsverhältnis. Fertige Boards mit integriertem Neo6M-GPS-Baustein und brauchbarter passiver Keramik-Antenne schlagen mit Preisen ab 10-15€ zu Buche, wobei sich in den unteren Preisregionen überwiegend Nachbauten aus chinesischer Produktion tummeln. Zwar führen die billigen Klone nur serielle RX/TX-Pins nach außen, während die teureren Modelle zum Beispiel auch über einen I2C-Anschluss verfügen. Das tut dem Spaß aber keinen Abbruch.

Der Standard NMEA 183

Kommerzielle GPS-Module unterstützen den Standard NMEA 183 der National Marine Electronics Association, und senden typischerweise mit 8 Bit Datenbreite (inklusive einem Stop-Bit) ASCII-basierte Nachrichten über eine 4800 Baud-Verbindung.

Die Nachrichten sind wie folgt strukturiert, wobei jede Zeile eine separate Nachricht enthält:

$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76 $GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A $GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70 $GPGSV,3,2,11,02,39,223,19,13,28,070,17,26,23,252,,04,14,186,14*79 $GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76 $GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43 $GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75 $GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A $GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70 $GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77 $GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76 $GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45

So beinhaltet das $GPGGA in der ersten Nachrichtenzeile Fix-Information, ob genügend Satelliten zum Positionieren zur Verfügung stehen.

$GPRMC stehen für eine Positionsbestimmung mit dem empfohlenen Minimum an Information (required minimum).

$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

wobei hier

  • RMCbedeutet Recommended Minimum Sentence C - die minimale Menge an Information, die ein GPS-Modul liefern muss
  • 123519 Verbindung zu ausreichender Zahl an Satelliten erfolgte um 12:35:19 UTC
  • A Status (A= Active, V= Void)
  • 4807.038,N geographische Breite 48° 07.038' North
  • 01131.000,E die geographische Länge 11° 31.000' East
  • 022.4 Geschwindigkeit über Boden (in Knoten)
  • 084.4 Positionierungswinkel in Grad
  • 230394 das Datum - 23. März 1994
  • 003.1,W Magnetische Streuung
  • *6A die Checksumme (beginnt immer mit *)
darstellt.
Drum prüfe, wer sich ewig bindet

Zum ersten Aufwärmen lassen sich die GPS-Module von u-blox mit einer Windows-Software namens u-center[1] auslesen. Das ist insofern interessant, als sich dadurch die Funktion des GPS-Moduls veranschaulichen und prüfen lässt:

Wo bin ich?
Das kostenlose Programm u-center im Betrieb (Microsoft Windows only). Auf dem Fenster sind die empfangbaren Satelliten grün markiert

Um das Modul an einen USB-Port des PCs anzuschließen, bietet sich ein FTDI-USB-to-TTL-Adapter an:

Wo bin ich?
Zum direkten Anschluss des GPS-Empfängers an einen Computer, nutzt die Schaltung einen FTDI-Adapter (USB to TTL)

In der Schaltung existieren folgende Verbindungen:

FTDI TX mit NEO RX

FTDI RX mit NEO TX

FTDI Vcc mit NEO Vcc

FTDI GND mit NEO GND

Das USB-to-TTL-Adapterboard (FTDI) muss dabei auf 3,3V Betrieb gejumpert sein. Natürlich können Sie alternativ auch preisgünstige USB-TTL-Adapter mit Chipsets der Typen CP2102 oder CH340 nutzen, sofern Sie den entsprechenden Treiber installieren.

Nach Anschluss der Schaltung über USB (FTDI-Adapter) an den Windows-PC, und der Einstellung des verwendeten GPS-Produkts sowie des richtigen USB-Ports in u-center dauert es eine Weile bis der GPS-Empfänger Verbindungen zu genügend vielen Satelliten aufbauen konnte. Mindestens vier müssen es sein, wie bereits an anderer Stelle beschrieben. Danach ist die Position fixiert (fixed), eine grüne LED am NEO blinkt, und im Anwendungsfenster erscheinen die erfassten Satelliten und die festgestellte Position, nebst umfangreicher weiterer Information. Aus Platzgründen kann ich an dieser Stelle nicht auf die komplette Funktionalität der Software eingehen.

Schaltung mit Arduino

Für die Beispielsschaltung kommt ein Arduino Nano mit 5V-Logik zum Einsatz, der über die digitalen Pins D3 und D4 als Software-basierten seriellen Port mit dem GPS-Modul verbunden ist. Allerdings darf die Verbindung der beiden Komponenten nicht direkt erfolgen, da ein NEO 6M oder 7M Modul mit 3,3V-Logik arbeitet. Deshalb ist ein Logic-Level-Konverter nötig, der zwischen den beiden Logik-Welten adaptiert. Einige Maker im Internet halten den direkten Anschluss von GPS-Modul an den Arduino zwar für unproblematisch. Das mag kurzfristig gelten, aber bei langem Dauerbetrieb ist ein Abrauchen des GPS-Moduls definitiv nicht auszuschließen.

Folgende Zutaten (Bill of Material) sind notwendig, um die Schaltung aufzubauen:

  • Breadboard
  • Arduino Nano MCU
  • Logic Level Converter (zwischen 3,3V- und 5V-Logik) mit mindestens zwei Kanälen
  • GPS Modul wie z.B. NEO 6M oder 7M GPS
  • 10 Jumper Wires (male to male)
  • 2 Jumper Wires (male to female)
Wo bin ich?
In der Schaltung sind das GPS-Modul (links oben), der Logic Level Konverter (roter Baustein), der Arduino Nano (Mitte) und das FTDI-Board (rechts) zu sehen

Die Schaltung implementiert folgende Verbindungen:

  • Der FTDI-Adapter dient nur zur Versorgung des GPS-Empfängers mit Strom. Dementsprechend laufen von den Ausgängen VCC und GND des Adapters jeweils ein Kabel zu den entsprechenden Stromschienen am Breadboard.
  • Der RX-Eingang des GPS-Moduls wird über den Logic Level Konverter mit dem TX-Ausgang des Arduino Nano verbunden. Im Beispiel fungiert der digitale Pin D4 als TX-Ausgang des Arduino-Boards.
  • Der TX-Ausgang des GPS-Moduls wird über den Logic Level Converter mit dem RX-Eingang des Arduino Nano verbunden. Im Beispiel fungiert der digitale Pin D3 als RX-Eingang des Arduino Boards.

Noch ein Wort zum verwendeten Arduino-Board. Wer ein Board mit seriellen Hardwareports einsetzt wie zum Beispiel einen Arduino Mega, sollte einen seriellen Hardware-Port (Serial1, Serial2, Serial3, ...) für die Verbindung verwenden. Das ist die schnellste und beste Lösung.

Bei Boards wie Arduino Uno, Leonardo, Nano muss stattdessen eine Software-basierte Lösung zum Einsatz kommen, etwa die Standard-Lösung SoftwareSerial. Leider führt SoftwareSerial betriebsbedingt zu hohen Latenzzeiten und kann deshalb nur geringere Baudraten unterstützen. Das können Alternativen wie AltSoftSerial deutlich besser. Für die Geschwindigkeiten der GPS-Module von 4800 Baud oder 9600 Baud erweist sich aber SoftwareSerial als mehr mehr als ausreichend.

Das GPS-Modul zeigt eine grüne, blinkende LED sobald ihm genügend viele Satelliten für die Positionsbestimmung zur Verfügung stehen:

Wo bin ich?
Die Schaltung im Betrieb. Die grün blinkende LED zeigt an, dass der NEO-6m mit mindestens vier Satelliten in Kontakt steht
Programmierung

Es macht keinen Spaß, systemnah mit einem GPS-Modul beziehungsweise mit den Rohdaten im NMEA 183 Standardformat zu arbeiten. Daher existieren diverse Bibliotheken für Arduino, um diese Aufgabe zu erleichtern, darunter die Bibliotheken NEOGPS, GPS-NEO-6m-master und TinyGPSPlus. Eine Suche mit dem Begriff GPS im Menü der Arduino IDE unter Sketch > Include Library > Manage Libraries liefert die entsprechenden Bibliotheken.

Für den Artikel nutze ich TinyGPSPlus. Nach Installation von TinyGPSPlus lässt sich das Beispiel FullExample.ino über den Menüpfad File > Examples > TinyGPSPlus > FullExample öffnen.

Der Anfang des Sketches muss ein Programm den entsprechenden Header inkludieren:

#include 
#include ++.h>

Der Einfachheit halber benutzt der Sketch in unserem Fall SoftwareSerial. Ohnehin steht beim Arduino Nano kein eigener serieller Hardwareport für diesen Zweck zur Verfügung.

Die Pins des Nano-Boards für den Software-Port lauten im obigen Beispiel D3 (als RX) und D4 (als TX):

static const int RXPin = 3, TXPin = 4;
static const uint32_t GPSBaud = 9600;

// Das Objekt zum Zugriff auf die Bibliothek:

TinyGPSPlus gps;

// Software-basierter Serieller Port
SoftwareSerial ss(RXPin, TXPin);

Die Baudrate beträgt in dem von mir verwendeten NEO-6m-Modul 9600 Baud. Üblicherweise kommen auch 4800 Baud recht häufig vor. Dem Datenblatt Ihres GPS-Moduls sollten Sie daher den für Ihr Modul jeweils richtigen Wert entnehmen.

Im setup() des Sketches erfolgt die Verbindung mit dem integrierten seriellen Monitor (der für die Verbindung von PC/Mac mit dem Arduino-Board) über Serial.begin(), und die mit der emulierten seriellen Verbindung vom Arduino-Board zum GPS-Modul über ss.begin();

void setup()
{
Serial.begin(115200); // Serieller Monitor für print-Ausgaben
ss.begin(GPSBaud); // Serieller Software-Port zum GPS-Modul
// ...
}

Im eigentlichen Hauptprogramm loop() ist der Zugriff auf die vom GPS-Modul gelieferte Information möglich:

void loop()
{
while (ss.available() > 0) // Daten liegen an der Leitung an
if (gps.encode(ss.read())) // Lese Daten und enkodiere sie
{
... // Nutzung der gelesenen Daten
}

if (millis() > 10000 && gps.charsProcessed() < 10) // Timeout nach 10 secs
{
Serial.println(F("Kein GPS-Modul gefunden"));
while(true); // Fini, das Ende der Welt
}
}

Information lässt sich über die Variable gps auslesen:

gps.satellites.value() // falls gps.satellites.isValid()
gps.hdop.value() // falls gps.hdop.isValid()
gps.location.lat() // falls gps.location.isValid()
gps.location.lng() // falls gps.location.isValid()
gps.location.age() // falls gps.location.isValid()
gps.date // falls gps.date.isValid()
gps.time // falls gps.time.IsValid()
gps.altitude.meters() // falls gps.altitude.isValid()
gps.course.deg() // falls gps.course.isValid()
gps.speed.kmph() // falls gps.speed.isValid()

Das funktioniert immer nach dem selben Schema: Zuerst ist zu überprüfen, ob überhaupt ein gültiger Datenwert vorliegt wie zum Beispiel bei gps.location.isValid(). Ist dies der Fall, enthalten Variablen wie gps.location.lat() (= geographische Breite) gültige Werte.

Arduino IDE: Sketch, der TinyGPSplus nutzt
Das Bild zeigt die Arduino IDE und den seriellen Monitor. Auf den Arduino läuft ein Beispielsprogramm, das die TinyGPSPlus-Bibliothek mitliefert
Learning by Doing

Die unten abgedruckte Quelldatei beinhaltet ein sehr einfaches Beispiel, bei dem das Arduino-Board den seriellen Monitor zur Ausgabe nutzt und einen Software-emulierten Port zur Kommunikation mit dem GPS-Modul. In der Regel dauert es nach Inbetriebnahme des GPS-Moduls etwas bis es genügend Satelliten zur Positionsbestimmung lokalisieren konnte. Der Einfachheit halber geht die Demo-Anwendung davon aus, dass das Modul betriebsbereit ist und gültige Daten liefert (grüne LED blinkt).

In der Hauptschleife loop bestimmt das Programm in jeder Sekunde die Position, und gibt die entsprechende Information zeilenweise am seriellen Monitor aus.

Die Daten werden im CSV-Format (Comma Separated Values) ausgegeben. Dieses Format hat Vorteile, wenn Benutzerinnen später die Daten weiterverarbeiten wollen. Dazu unten mehr.

/*******************************************************
*
* Demo-Anwendung zur Nutzung eines GPS-Moduls des
* Typs u-blox NEO 6m oder 7m
* (c) Michael Stal, 2018
* frei verwendbar gemaess Creative Commons
*
*******************************************************/

#include ++.h>

#include

// Verwendete digitale Pins für SoftwareSerial
static const int RX = 3, TX = 4;
// !!! Baudrate des GPS-Moduls: Anpassung an eigene HW notwendig
static const uint32_t GPSBaud = 9600;

// Zugriff auf TinyGPS++ ueber gps
TinyGPSPlus gps;

// Emulierter Port zum GPS Geraet
SoftwareSerial gpsPort(RX, TX);

/*******************************************************
*
* setup baut alle Verbindungen auf
* zum seriellen Monitor und zum GPS-Modul
*
*******************************************************/

void setup()
{
// Verbindung zum seriellen Monitor
Serial.begin(115200);
// Verbindung mit GPS-Modul
gpsPort.begin(GPSBaud);

// Header Zeile ausgeben (Format ist .csv)
Serial.println();
Serial.println("utc_t, lat, lon, elevation");
Serial.println("#name, latitude, longitude, elevation");
}

/*******************************************************
*
* Im Hauptprogramm wird jede Sekunde die aktuelle
* Position vom GPS-Geraet gelesen inklusive
* Datum und Zeit, geo. Breite, geo. Laenge, Hoehe
*
*
*******************************************************/

void loop()
{
while (gpsPort.available() > 0) // Daten vorhanden?
if (gps.encode(gpsPort.read())) {
showPositionData(); // ja, dann Ausgabe am ser. Monitor
delay(1000); // 1 Sekunde warten
}

if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println("Fehler: GPS Modul nicht gefunden");
while(true);
}
}

/*******************************************************
*
* showPositionData liest die aktuelle Position
* und gibt die Daten als Zeile (im .csv-Format) aus
*
*******************************************************/

void showPositionData()
{
// Erst Datum ...
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print("/");
Serial.print(gps.date.day());
Serial.print("/");
Serial.print(gps.date.year());
}

Serial.print(" ");

// ... und Zeit
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print("0");
Serial.print(gps.time.hour());
Serial.print(":");
if (gps.time.minute() < 10) Serial.print("0");
Serial.print(gps.time.minute());
Serial.print(":");
if (gps.time.second() < 10) Serial.print("0");
Serial.print(gps.time.second());
}

// Jetzt 2D-Position als geo. Breite, Laenge
if (gps.location.isValid())
{
Serial.print(" , ");
Serial.print(gps.location.lat(), 6);
Serial.print(" , ");
Serial.print(gps.location.lng(), 6);
}

// Und dann noch Hoehe
if (gps.altitude.isValid())
{
Serial.print(" , ");
Serial.print(gps.altitude.meters(), 6);
}

Serial.println();
}

Die Ausgabe des Sketches am seriellen Monitor schaut bei einem sehr einfachen Beispiel wie folgt aus:

utc_t, lat, lon, elevation
#name, latitude, longitude, elevation
2/25/2018 14:33:06 , 48.126541 , 11.571980 , 523.500000
2/25/2018 14:33:07 , 48.126533 , 11.571964 , 523.500000
...
WYSIWYG

Statt auf dem Monitor könnte die obige Anwendung alle Positionsdaten auch als CSV-Datei (zum Beispiel auf einer SD-Card) speichern. In einem früheren Posting [2]hatte ich das dazu notwendige Vorgehen bereits beschrieben.

Dadurch können Maker die erzeugte Datei weiter verarbeiten, um die Tracking-Daten zum Beispiel in Google Earth oder Maps zu visualisieren.

Ein Programm von Format wie Google Earth erwartet allerdings .KML-Dateien (Keyhole Markup Language) oder .KMZ-Dateien. Woher also nehmen und nicht stehlen? Zum Glück gibt es genau zu diesem Zweck einen Online-Dienst namens GPS Visualizer[3].

Die obige Daten-Ausgabe des GPS-Empfängers habe ich in einer Datei arduinotrack.csv gespeichert und den Dienst GPS Visualizer dafür genutzt, um eine Google Map zu erzeugen.

Wo bin ich?
Der freie Online-Dienst GPS Visualizer erlaubt es, GPS-Daten von/nach verschiedenen Formaten zu konvertieren

Die erzeugte Map ist aber zugegebenermaßen eher unspektakulär, weil sich der Testaufbau immer an derselben Stelle meines Büros befunden hat:

Jetzt wissen die Leser wo ich wohne.
GPS Visualizer kann die Daten des GPS-Tracking z.B. über Google Earth oder Google Maps visualizieren
Fazit

In dieser Folge ging es um Ortung der aktuellen Position über GPS. Ein Microcontroller (MCU), in unserem Fall ein Arduino Nano, kommuniziert via serieller Leitung mit der verwendeten GPS-Hardware. Die Einsatzmöglichkeiten sind vielfältig, etwa die Steuerung einer Drohne, das Tracking eines Kraftfahrzeugs oder die Positionsbestimmung eines Containers, um nur einige Beispiele zu nennen.

Wer GPS in seinem Arduino-Projekt integrieren möchte, ist mit den preisgünstigen Komponenten wie dem NEO 6M oder 7M aus der Produktfamilie von u-blox bestens bedient.

Der weiter oben beschriebene Versuchsaufbau gibt lediglich die GPS-Daten aus. Es gibt wie immer unzählige Erweiterungsmöglichkeiten:

  • Mittels eines SD-Card-Shields könnte das Programm auch eine GPS-Datei erzeugen, beispielsweise im KML- oder GPX-Format, die sich über Webdienste wie Google Maps visualisieren lässt.
  • Für mobile Geräte sollte die Stromversorgung über Akkus oder Batterien erfolgen.
  • Statt eines Arduino-Boards bietet sich natürlich auch an, ein kompatibles Board zu nutzen wie ESP32, Teensy, oder STM32F103C8T6 . Diese Boards laufen unter 3,3V, sodass der im Beitrag benutzte Logic Level Konverter entfallen kann.

Jetzt bleibt mir nur noch, Ihnen viel Spaß beim Experimentieren zu wünschen.


URL dieses Artikels:
http://www.heise.de/-3976281

Links in diesem Artikel:
[1] https://www.u-blox.com/en/product/u-center-windows
[2] https://www.heise.de/developer/artikel/Spuren-hinterlassen-Datenlogging-mit-Arduino-3348205.html
[3] http://www.gpsvisualizer.com

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

✇ FreshRSS.org

FreshRSS 1.10.0

Von Alkarex — 24. Februar 2018 um 12:03

Changelog:

  • API
  • Features
    • Ability to pause feeds, and to hide them from categories #1750
    • Ability for the admin to reset a user’s password #960
  • Security
    • Allow HTTP Auth login with REDIRECT_REMOTE_USER when using Apache internal redirect #1772
  • UI
    • New icons for marking as favourite and marking as read in the Reading View #603
    • Add shortcuts to switch views #1755
  • Bug fixing
    • Fix login bug when HTTP REMOTE_USER changes (used by YunoHost) #1756
    • Fix warning in PHP 7.2 #1739
  • Extensions
    • Allow extensions to define their own reading view #1714
  • I18n
  • Misc.
    • More sites in force-https.default.txt #1745
    • Trim URLs when adding new feeds #1778
✇ Developer-Blog - Neuigkeiten von der Insel

MicroProfile unter der Lupe, Teil 3: JWT Security

Von heise online — 20. Februar 2018 um 14:38

zurück zum Artikel

Das Thema Security stellt in einer stark verteilten, Microservices-basierten Umgebung eine besondere Herausforderung dar. Im Umfeld von RESTful-Services hat sich in den letzten Jahren der auf OpenID Connect (OIDC) basierende Standard JSON Web Tokens (JWT) für rollenbasierte Zugriffskontrolle etabliert. Auf diesen Stack setzt auch die Spezifikation MicroProfile JWT RBAC Security (MP-JWT).

Ein Microservice kommt selten allein. Das ist kein Geheimnis, sondern Teil des Erfolgsrezepts. Ziel einer Microservice-basierten Architektur ist es, durch ein passendes Servicedesign, eine möglichst große Unabhängigkeit der einzelnen Services untereinander zu erreichen. Wie sieht es aber mit dem Thema Sicherheit aus? Gilt auch hier das Prinzip der größtmöglichen Unabhängigkeit? Und wenn ja, muss sich ein Client dann bei jedem Service oder gar bei jedem Service-Aufruf separat mit seinen User Credentials (z.B. Username und Passwort) authentifizieren und autorisieren?

JWT Quick Guide

Im Umfeld verteilter Services hat sich in den letzten Jahren der auf OpenID Connect basierende JSON-Web-Tokens-Standard [1] (siehe auch JWT.io Introduction [2]) als der Standard etabliert.

Vereinfacht gesprochen authentifiziert sich bei diesem Verfahren ein Client einmalig bei einem Authentication-Server (Issuer) und erhält im Gegenzug ein zeitlich begrenztes, personalisiertes und in der Regel signiertes Token (JWT mit JWS [3]). Personalisiert bedeutet in diesem Zusammenhang, dass das Security-Token sogenannte Claims enthält, also Key-Value-Paare, welche unter anderem . Informationen zu dem authentifizierten Nutzer (Subject) beinhalten.

Mit Hilfe des Tokens kann sich der Client nun gegenüber externer Services (Resource Server) mittels Bearer Authentication authentifizieren. Dazu schickt er einfach in jedem Request das Token im Authorization-Header mit:

GET /resource/123 HTTP/1.1
Host: openknowledge.com
Authorization: Bearer mF_9.B5f-4.1JqM

Dank Signatur können die aufgerufenen Services das Token auf Echtheit und Unverfälschtheit verifizieren. Da das Token Informationen über den Client enthält, sind die aufgerufenen Service zusätzlich in der Lage, eine rollenbasierte Zugriffskontrolle (RBAC; role based access control) – Autorisierung - durchzuführen.

Der Vorteil dieses Verfahrens liegt klar auf der Hand. Dank Token und den darin enthaltenen Informationen kann ein Service sowohl Authentifizierung als auch Autorisierung durchführen, ohne zusätzlich Informationen von einer dritten Partei wie einem User-Management oder Identity-Service erfragen zu müssen. Dies erspart unnötige Roundtrips. Dies gilt übrigens auch dann, wenn der aufgerufene Service einen weiteren Service aufruft (Service Chaining). In diesem Fall reicht der ursprünglich aufgerufene Service das Token inklusive der enthaltenen Nutzerinformation einfach im Request-Header weiter (Security Context Propagation).

MicroProfile und JWT

Seit Version 1.2 unterstütz auch das MicroProfile mit der Spezifikation MP-JWT 1.0 JWT-basierte Security. Die Spezifikation setzt dabei gleich an mehreren Punkten an und versucht folgende Aufgaben zu unterstützen:

  1. Token aus dem Request extrahieren,
  2. Token verifizieren und validieren,
  3. Claims des Token zugreifbar machen und
  4. JavaEE-Security-Context erzeugen und setzen.

Zu diesem Zweck definiert die MP-JWT Spezifikationen einen Satz von „non-optional“ Claims, also Pflichtfeldern, die ein spezifikationskonformes Token beinhalten muss:

  • typ: Header-Parameter für das Token-Format („JWT“)
  • alg: Header-Parameter für den Verschlüsselungsalgorithmus („RS256“)
  • kid: Header-Parameter mit Hinweis für die eindeutige Key ID
  • iss: Token-Issuer
  • sub: Subject des Tokens (Principle/User)
  • aud: angedachte Empfängergruppe
  • exp: Gültigkeit
  • iat: Ausstellungszeitpunkt
  • jti: eindeutiter Identifier
  • upn: eindeutiger Principle Name (für java.security.Principle)
  • groups: Liste von Gruppennamen für das Mapping mit Application-Roles

Ein minimales Beispiel eines MP-JWT in JSON-Format könnte wie folgt aussehen:

{ 
"typ": "JWT",
"alg": "RS256",
"kid": "abc-1234567890"
}
{
"iss": "https://auth.openknowledge.com",
"aud": "kNowLedGe",
"jti": "ok-12345",
"exp": 1311281970,
"iat": 1311280970,
"sub": "13579",
"upn": "lars.roewekamp@auth.openknowledge.com",
"groups": ["first-group", "second-group", "admin"],
}

Damit eine automatische Extraktion des Tokens aus dem Authorization-Header des Request erfolgen kann, muss der JAX-RS-Anwendung zunächst signalisiert werden, dass zur Authentifizierung und Autorisierung der MP-JWT JASPI (Java Authentication SPI for Containers) verwendet werden soll. Das erfolgt mit der Annotation LoginConfig aus dem Package org.eclipse.microprofile.jwt.


import org.eclipse.microprofile.auth.LoginConfig;

// Sets the authentication method to the MP-JWT for the MicroProfile JWT.
// The optional parameter realName is only needed, if authMethod
// is set to "BASIC" or for vendor specific configurations.
@LoginConfig(authMethod = "MP-JWT", realName="...")
@ApplicationScoped
@ApplicationPath("/myapi")
public class MyJaxrsApp extends Application { }

Anmerkung: Die Annotation LoginConfig wurde eingeführt, da das MicroProfile keinerlei Aussagen zu möglichen Deployment-Formaten trifft und somit auch nicht von dem Vorhandensein eines Servlet Containers bzw. einer web.xml ausgegangen werden kann. Ist eine web.xml vorhanden, kann alternativ zur Verwendung der Annotation auch der gleichnamige Eintrag login-config innerhalb der web.xml-Datei genutzt werden.

Die anschließende Verifizierung des Tokens erfolgt automatisch im Hintergrund. Zu diesem Zweck muss lediglich der Public Key des Token-Issuers in der Konfiguration des MicroProfile-Runtime-Container hinterlegt sein. Damit ein Token als gültiges MP-JWT angesehen wird, muss es zusätzlich mindestens die folgenden Bedingungen erfüllen:

  • JOSE (JavaScript Object Signing and Encryption) Header, der angibt, dass das Token via RS256 signiert wurde
  • iss-Claim, der denselben Token-Issuer beinhaltet, wie im MicroProfile-Runtime-Container konfiguriert

CDI Integration

Einmal extrahiert und verifiziert kann innerhalb des Microservice via CDI auf das Token beziehungsweise auf einzelne Claims des Tokens zugegriffen werden. Der Zugriff kann dabei via Raw-Typen, ClaimValue-Wrapper, javax.enterprise.inject.Instance oder JSON-P-Typen erfolgen:

@Path(/endpoint) 
@DenyAll
@RequestScoped
public class SomeEndpoint {

// 1) JWT object with @RequestScoped scoping
@Inject
private JsonWebToken callerPrincipal;

// 2) JWT as raw String
@Inject
@Claim(standard = Claim.raw_token)

private String rawToken;

// 3) IAT claim as Long value
@Inject
@Claim(standard=Claims.iat)

private Long issuedAt;

// 4) ISS claim as ClaimValue of type String
@Inject
@Claim(standard=Claims.iss)

private ClaimValue<String> issuer;

// 5) JTI claim as optional ClaimValue of type String
@Inject
@Claim(standard=Claims.jti)

private ClaimValue<Optional<String>> optJti;

// 6) JTI claim as JsonString
@Inject
@Claim(standard=Claims.jti)

private JsonString jsonJti;

// 7) custom claim "roles" as JsonArray
@Inject
@Claim("roles")

private JsonArray jsonRoles;

// 8) custom claim "customObject" as JsonArray
@Inject
@Claim("customObject")

private JsonObject jsonCustomObject;
...
}

Anmerkung: Die im obigen Listing gezeigte Klasse SomeEndpoint muss zwingendermaßen vom Scope @ReqiestScoped sein, das in ihr non-proxyable Typen (String und Long) aus dem Token injected werden.

Der aktuell angemeldete Caller bzw. das zugehörige Token kann mittels @lnject JsonWebToken mit dem Scope @RequestScoped injected werden (1). Das von Principal abgeleitete Interface JsonWebToken bietet eine Reihe von Convenient-Methoden, um gezielt und typenssicher auf die wichtigsten Claims des Tokens (Name, Issuer, Audience, Subject, TokenID, ExperiationTime, IssuedAtTime, Groups) zugreifen zu können.

Alternativ können die Claims aber auch direkt injected werden. Geschieht dies als non-proxyable Raw Typ, wie zum Beispiel String (2) oder Long (3), muss die umliegende Bean vom Scope @RequestScoped sein. Statt den Claim als Raw-Typen zu injecten, können alternativ auch ClaimValue- und/oder Optional-Wrapper verwendet werden (4 und 5). Und auch ein Zugriff via in JSON-P definierter Typen ist möglich (6, 7 und 8).

Um Tippfehler zu verhindern, sollte bei dem Zugriff auf Standard-Claims immer die Claims-Enumeration verwendet werden. Für den Zugriff auf Custom-Claims dagegen, können Strings oder eigene Enumerations genutzt werden.

JAX-RS Container Integration

Nachdem wir nun in der Lage sind, das JSON Web Token automatisch aus dem Request zu extrahieren und im Anschluss zu verifizieren, wäre es natürlich schön, wenn wir innerhalb der JAX-RS Ressourcen auf gewohnte JavaEE-Security-Mechanismen zurückgreifen könnten. Und auch das sieht die MP-JWT Spezifikation vor.

Ein Aufruf der Methode getUserPrinciple() der Klasse javax.ws.rs.core.SecurityContext liefert uns eine Instanz des aktuellen JsonWebToken zurück. Entsprechend können wir mit einem Aufruf der Methode isUserInRole(someRole) testen, ob die angegebene Rolle in dem Claim groups des Tokens enthalten ist oder nicht. Zusätzlich lässt sich mit Hilfe der Annotation @RollesAllowed(…) der Zugriff auf einzelne Methoden entsprechend der angegebenen Rolle(n) sperren bzw. freigeben.

Fazit und Ausblick

Wer schon einmal das „Glück“ hatte, die notwendigen Schritte zum Extrahieren, Validierung und Verifizieren eines JSON Web Tokens - inkl. der Überführung in einen JavaEE Security Context - implementieren zu dürfen, der weiß die Vorteile einer integrierten und standardisierten Lösung zu schätzen. Dies gilt insbesondere auch für die innerhalb des Tokens zu erwartenden Claims.

Das ganze Konzept steht und fällt allerdings damit, dass es am Ende hinreichend Identity Provider und Service Provider geben wird, die sich auf das MP-JWT Format einlassen. Um die Wahrscheinlichkeit zu erhöhen, hat man bei der Auswahl der „non-optional“ Claims bewusst darauf verzichtet, das Rad neu zu erfinden und stattdessen ein Subset von fünf der im IANA JWT Assignement [4] standardisierten Claims gewählt. Lediglich die zwei der "non-optional" Claims - upn (user principle name) und groups (Token Subject‘s Gruppen, welche auf JavaEE Security-Rollen gemappt werden) - sind proprietär.

Für zukünftige Versionen sind noch einige weitere Claims angedacht. So sollen mit Hilfe des Claims resouce_access servicespezifische Rollen angegeben werden können. Weiterhin wird darüber nachgedacht, neben dem bereits vorhanden Claim groups auch einen Claim roles einzuführen. Während groups dafür gedacht ist, dass die enthaltenen Werte auf das Rollenmodell der Ziel-Ressource gemappt werden, sollen die in roles enthaltenen Werte eins zu eins weitergereicht und in @RolesAllowed verwendet werden können.

Was ein wenig verwundert ist die Tatsache, dass die Art und Weise der Konfiguration, also zum Beispiel der Zurgiff auf den Public Key, den jeweiligen Runtime-Container-Herstellern überlassen wird, anstatt auf die MP Config API [5] zurückzugreifen. Entsprechende Überlegungen zur Vereinheitlichung gibt es aber bereits. Man darf gespannt sein.


URL dieses Artikels:
http://www.heise.de/-3973746

Links in diesem Artikel:
[1] https://tools.ietf.org/html/rfc7519
[2] https://jwt.io/introduction
[3] https://tools.ietf.org/html/rfc7515
[4] https://www.iana.org/assignments/jwt/jwt.xhtml
[5] https://www.heise.de/developer/artikel/MicroProfile-unter-der-Lupe-Teil-1-Config-API-3928886.html

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Continuous Architecture

Technische Schulden entstehen einfach so

Von heise online — 14. Februar 2018 um 18:59

zurück zum Artikel

Kaum eine Metapher ist wichtiger für Softwareentwicklung als "technische Schulden". Aber sie hat leider einige Schwächen. Vor allem gehen Teams meistens die Schulden nicht bewusst ein.

Wie gut die Qualität des Codes einer Anwendung ist, können Benutzer oder Projektleiter kaum erkennen. Schließlich merken nur Entwickler, ob der Code besonders einfach geändert werden kann oder nicht. Leider ist das Spiel mit der Qualität aber gefährlich, denn schlechte Qualität bringt im Extremfall ein Projekt zum vollständigen Stillstand. Technische Schulden sollen als Metapher das Problem mit der Qualität besser vermittelbar machen. So können Benutzer oder Projektleiter besser verstehen, warum nicht jedes Feature schnell mal so implementiert werden sollte.

Wikipedia

Wikipedia[1] beschreibt technische Schulden folgendermaßen: Ein Team, das in einem Softwareprojekt ohne besondere Rücksicht auf die Qualität Code sofort in Produktion bringt, liefert erst mal schneller. Dafür baut das Team aber Schulden auf. Genau wie bei Geldschulden müssen Zinsen gezahlt werden: Die Produktivität sinkt, denn die schlechte Codequalität hält das Team auf. Diese Beschreibung passt gut zu der Metapher: Wer einen Kredit aufnimmt, baut Schulden auf, um sich etwas schneller zu kaufen und muss die Schulden später mit Zinsen zurückzahlen.

Ward Cunningham

Ursprünglich hat Ward Cunningham die Metapher der technischen Schulden aus der OOPSLA-Konferenz [2]1992 eingeführt. Er erklärt auf YouTube[3] den Begriff anders: Code repräsentiert immer das aktuelle Verständnis des durch die Software gelösten Problems. Wenn das Team Neues lernt, dann muss der Code durch Refactorings konsolidiert werden, sodass das Gelernte optimal repräsentiert ist. Wenn die Refactorings unterbleiben, entstehen technische Schulden und der Code ist schwieriger zu ändern. Cunningham schließt explizit aus, dass das Teams bei der Qualität Kompromisse macht und widerspricht damit eindeutig dem Wikipedia-Artikel. Das Team baut keine Schulden auf, sondern die Schulden entstehen unwillkürlich.

Martin Fowler

Martin Fowler hat eine andere Perspektive: Entweder das Projekt ist umsichtig (prudent) und trifft Entscheidungen über die Qualität oder es geht so rücksichtslos (reckless) vor, dass es die Qualität nicht beachtet. Außerdem geht das Team bewusst (deliberate) einen Qualitätskompromiss ein oder technische Schulden entstehen unbeabsichtigt (inadvertent). Aus den Eigenschaften umsichtig/ ücksichtlos auf der einen Seite und bewusst/unbeabsichtigt auf der anderen Seite entstehen vier Quadranten[4]. Der Wikipedia-Definition entspricht umsichtig/bewusst: Das Team kennt die Qualität (umsichtig) und trifft bewusst die Entscheidung, einen Qualitätskompromiss einzugehen. Cunninghams Erklärung ist umsichtig, weil das Team die Qualität kennt, aber die technischen Schulden entstehen nicht bewusst, sondern unbeabsichtigt, weil das Team lernt und der Code das Gelernte noch nicht abbildet.

Meiner Meinung nach gibt es noch eine weitere Quelle technischer Schulden: der technische Fortschritt. Neue Architekturen und Technologien machen das alte Vorgehen obsolet. Wenn der Code nicht passend aktualisiert wird, entstehen technische Schulden. Auch das ist unbeabsichtigt, weil es sich nicht verhindern lässt.

Wie mit technischen Schulden umgehen?

Das Wichtigste an technischen Schulden ist aber, wie man mit ihnen umgeht. Kein System ist perfekt. Es gibt immer etwas zu optimieren. Das bedeutet, dass Teams praktisch unbegrenzt optimieren können. Wenn das Team durch eine Optimierung keine Verbesserung der Produktivität erwartet, die mehr bringt, als die Optimierung an Aufwand kostet, dann sollte die Optimierung unterbleiben. Dafür können Investitionen[5] eine gute Metapher sein. Die Qualität ist kein Ziel an sich, sondern nur ein Mittel für bessere Produktivität. Auch bei diesem Vorgehen hat die Metapher der technischen Schulden einen Vorteil: Die Qualitätskompromisse können problematisch sein, weil sie für Benutzer oder Projektleiter nicht leicht zu erkennen sind und zum Stillstand des Projekts führen können. Der Begriff "technische Schulden" stellt genau das dar.

tl;dr

Technische Schulden sind eine Metapher für die Qualität in Softwareprojekten mit einigen Schwächen und unterschiedlichen Interpretationen. Am wichtigsten ist jedoch, wie Teams mit den technischen Schulden umgehen.


URL dieses Artikels:
http://www.heise.de/-3969279

Links in diesem Artikel:
[1] https://en.wikipedia.org/wiki/Technical_debt
[2] http://c2.com/doc/oopsla92.html
[3] https://www.youtube.com/watch?v=pqeJFYwnkjE
[4] https://martinfowler.com/bliki/TechnicalDebtQuadrant.html
[5] https://www.infoq.com/articles/no-more-technical-debt

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Neuigkeiten von der Insel

12 YouTube-Kanäle, die du 2018 nicht verpassen solltest

Von heise online — 23. Januar 2018 um 10:00

zurück zum Artikel

YouTube ist schon lange keine reine Unterhaltungsplattform mehr. Es gibt inzwischen auch eine Vielzahl hochwertiger Inhalte über Java, Java EE und allgemeinere Softwareentwicklungsthemen.

Ich schaue inzwischen immer häufiger kurze Trainingsvideos oder auch ganze Konferenzvorträge auf YouTube. Es gibt keinen einfacheren und komfortableren Weg von den Besten unserer Branche zu lernen.

Hier sind, in ungeordneter Reihenfolge, ein paar Kanäle die mir in den letzten Monaten durch die regelmäßige Veröffentlichung qualitativ hochwertiger Videos aufgefallen sind:

1. Java[1]

Oracles YouTube Kanal dürfte vielen Java-Entwicklern bereits durch die aufgezeichneten Vorträge der JavaOne bekannt sein. Das Team veröffentlicht außerdem Vortragsmitschnitte des JVM Language Summit und Interviews mit bekannten Größen aus der Java-Community.

2. Adam Bien[2]

Adam zeigt in seinen Videos, wie einfach, effizient und leichtgewichtig die Entwicklung mit Java EE sein kann. In seiner sehr sehenswerten monatlichen Fragestunde beantwortet er außerdem die Fragen seiner Zuschauer und Leser.

3. Thoughts on Java[3]

Wenn du JPA oder Hibernate in deinen Projekten einsetzt, solltest du den "Thoughts on Java"-Kanal kennen. Hier veröffentliche ich jede Woche zwei neue Videos, in denen ich zeige, wie du deine Persistenzschicht einfach und effizient implementieren kannst.

4. Devoxx[4]

Der offizielle Kanal der Devoxx veröffentlicht Vortragsmitschnitte der bekannten Devoxx- und Voxxed-Days-Konferenzen. Damit kannst du dir die besten Redner und interessantesten Vorträge direkt zu dir nach Hause holen.

5. vJUG[5]

Einfacher als bei der virtual Java User Group kann man nicht an einem JUG-Treffen teilnehmen. Mit regelmäßigen Livestreams, einer 24-stündigen Onlinekonferenz und einem Buchklub bietet der Kanal der vJUG jede Menge interessanter Inhalte.

6. Sebastian Daschner[6]

Auf seinem Kanal veröffentlicht Sebastian sehr interessante Videos zu Java EE sowie zur Steigerung der Entwicklerproduktivität.

7. InfoQ[7]

Das InfoQ-Team stellt auf seinem Kanal Vortragsmitschnitte zu verschiedenen Architektur- und Softwareentwicklungsthemen von den QCon-Konferenzen zur Verfügung.

8. NightHacking[8]

Wer sich für Interviews und Diskussionspanels zu verschiedenen Java-Themen interessiert, findet auf dem NightHacking-Kanal viele sehenswerte Videos.

9. GOTO-Konferenzen[9]

Die GOTO-Konferenzen zeichnen ebenfalls viele Vorträge auf und stellen diese auf ihrem YouTube-Kanal kostenlos zur Verfügung.

10. JetBrainsTV[10]

Der JetBrains-YouTube-Kanal bietet eine schöne Mischung aus Vortragsmitschnitten der KotlinConf, Webinaren zu verschiedenen Softwareentwicklungsthemen und Trainingsvideos zu ihren eigenen Entwicklungswerkzeugen.

11. Spring Developer[11]

Wer mit Spring arbeitet, sollte auch den Spring-Developer-Kanal kennen. Das Team von Pivotal veröffentlicht dort eine Vielzahl hochwertiger Konferenzvorträge, Webinare und Schulungsvideos.

12. SouJava[12]

Die brasilianische SouJava-Organisation bietet auf ihrem Kanal eine Mischung aus Interviews und Webinaren in englischer und portugiesischer Sprache.


URL dieses Artikels:
http://www.heise.de/-3937979

Links in diesem Artikel:
[1] https://www.youtube.com/user/java
[2] https://www.youtube.com/user/bienadam
[3] https://www.youtube.com/channel/UCYeDPubBiFCZXIOgGYoyADw
[4] https://www.youtube.com/channel/UCCBVCTuk6uJrN3iFV_3vurg
[5] https://www.youtube.com/user/virtualJUG
[6] https://www.youtube.com/channel/UCG21GE2Go3vkj7mrs675ysA
[7] https://www.youtube.com/user/MarakanaTechTV
[8] https://www.youtube.com/channel/UCT0bL2CQIk1eANeXk57mxaA
[9] https://www.youtube.com/user/GotoConferences
[10] https://www.youtube.com/user/JetBrainsTV
[11] https://www.youtube.com/user/SpringSourceDev
[12] https://www.youtube.com/channel/UCH0qj1HFZ9jy0w87YfMSA7w

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Continuous Architecture

Microservices? Oder lieber Monolithen?

Von heise online — 19. Januar 2018 um 08:36

zurück zum Artikel

Microservices sind ein Hype. So dauert es nicht lange, bis sich die Kritiker melden und wieder zurück zu Monolithen wollen. Aber hilft das weiter?

Microservices teilen ein System in kleine, unabhängig deploybare Module auf. Die Alternative sind Deployment-Monolithen. Dann wird die gesamte Anwendung mit allen Modulen als Ganzes auf einmal deployt. Intern können Deployment-Monolithen aus Modulen wie Java-Packages, Namespaces oder Bibliotheken aufgebaut sein.

Aktuell ziehen Microservices Kritik auf sich, weil Microservice-System oft keine gute Struktur aufweisen. Aber Microservices definieren nur, wie die Struktur umgesetzt wird. Wie gut die Struktur ist, hängt nicht davon ab, ob die Module Microservices sind oder klassische Module. Domain-driven Design (DDD) und Bounded Context sind nützliche Techniken, um eine gute Struktur zu erreichen. Sie erleben dank Microservices gerade eine Renaissance. Wenn aus der Microservices-Diskussionein Fokus auf DDD und besser strukturierte Software entsteht, ist das schon ein wichtiger Erfolg – egal ob als Module Microservices genutzt werden oder nicht.

Monolithen: meistens schlecht strukturiert

Ausgerechnet Deployment-Monolithen als Lösung für schlecht strukturierte Systeme zu propagieren, erscheint mir aber widersinnig. Ich habe viele Reviews von Deployment-Monolithen erstellt. Die Strukturen der untersuchten Monolithen ließ fast immer zu wünschen übrig. Meine Erklärung: Zu leicht schleichen sich im Sourcecode unbeabsichtigte Abhängigkeiten zwischen Modulen ein. Die einzige Ausnahme ist, wenn im Projekt ein Architekturmanagement-Werkzeug genutzt wird oder andere Maßnahmen ergriffen werden, um die Modulgrenzen zu erzwingen. Das war aber nur bei wenigen von mir untersuchten Deployment-Monolithen der Fall.

Da Microservices eigene Sourcecode-Projekte haben und Schnittstellen zwischen den Microservices zum Beispiel als REST-Schnittstellen implementiert sind, schleichen sich bei Microservices Abhängigkeiten nicht so einfach ein. Schließlich muss man eine Abhängigkeit zu einem anderen Sourcecode-Projekt erzeugen und eine Schnittstelle bedienen. Das ist viel aufwendiger als beispielsweise die Nutzung einer Klasse aus einem anderen Java-Package. Die Aufteilung in Microservices unterstützt also das Einhalten der Modulgrenzen.

Wenn eine gute Struktur festgelegt worden ist, lässt sie sich mit Microservices umsetzen. Deployment-Monolithen erfordern weitere Maßnahmen, um die Struktur dauerhaft abzusichern.

Jenseits der Struktur

Es scheint so, als wäre von diesen beiden Alternativen ein Deployment-Monolith wegen der niedrigeren Komplexität die bessere Wahl. Nur ein System muss betrieben und ausgeliefert werden. Aber Microservices sind als Architekturansatz entstanden, um reale Probleme zu lösen:

  • Jeder Microservices lässt sich unabhängig deployen. Das Deployment eines einzelnen, kleinen Microservice ist einfacher und schneller als das Deployment eines vollständigen Deployment-Monolithen. Auch das Risiko sinkt, weil die Änderungen nur ein Microservice und damit ein Modul betreffen. Die Änderungen sind daher nicht so groß. Damit gibt es weniger Möglichkeiten für Fehler. Das Zurückrollen von Änderungen und Strategien wie Blue/Green Deployment oder Canary Releasing sind ebenfalls aufgrund der geringen Größe der Microservices einfacher als bei einem Deployment-Monolithen. Wenn Continuous Delivery für einen Deployment-Monolithen umgesetzte werden soll, lohnt es sich immer, zumindest eine teilweise Migration zu Microservices in Betracht zu ziehen, weil das die Komplexität der Continuous Delivery Pipeline erheblich reduzieren kann.
  • Es gibt Technologiefreiheit. Wenn ein System langfristig weiterentwickelt werden soll, dann steht irgendwann eine Migration auf eine aktuellere Technologie an. Bei einem Deployment Monolithen muss das gesamte System mit einem Schritt auf eine neue technologische Basis gestellt werden. Microservices lassen sich hingegen einzeln migrieren.
  • Wenn jeder Microservice von einem Team entwickelt wird, können die Teams unabhängig voneinander Microservices und damit neue Features deployen. Ebenso können sie weitgehend unabhängig voneinander technische Entscheidungen treffen. Diese Unabhängigkeit erlaubt es den Teams, sehr autonom zu arbeiten. Das ist gerade bei komplexen Projekten sehr willkommen, um Koordinationsaufwand zu sparen.

Letztlich stehen Microservices für eine konsequente Entkopplung der Module: Technische Entscheidungen oder Deployment sind auf ein Microservice begrenzt. Ebenso führt der Ausfall eines Prozesses nur zum Absturz eines Microservices. Zwischen Microservices können beispielsweise durch Firewall zusätzliche Sicherheitsbarrieren errichtet werden und sie können unabhängig voneinander skaliert werden. Es entsteht also eine Entkopplung bezüglich Technologien, Deployment, Ausfall und Sicherheit. Auch die softwaretechnische Entkopplung kann sehr weit gehen, wie ein früherer Blog-Post[1] gezeigt hat.

So unterstützen Microservices Entkopplung und damit ein Hauptziel von Modulen.

Mehr oder weniger Aufwand?

Natürlich führen Microservices zu einer erhöhten Komplexität beispielsweise bei Tests oder im Betrieb. Diese zusätzliche Komplexität muss gegen die bessere Modularisierung, die stärkere Entkopplung und das unabhängige Deployment aufgewogen werden. Schließlich ist es nur sinnvoll, einen Architekturansatz zu wählen, wenn er für das Szenario die einfachste Lösung darstellt. Ursprünglich sind Microservices erfunden worden, weil sie nicht nur eine einfach Lösung sind, sondern große Teams und schnelles Deployment nur so möglich waren.

Microservices von Anfang an als "zu komplex" auszuschließen ist dabei genauso wenig hilfreich, wie Deployment-Monolithen grundsätzlich zu verdammen. Und wichtig bleibt, nicht nur die Frage nach der Modularisierungstechnologie zu stellen, sondern vor allem die fachliche Aufteilung vernünftig umzusetzen.

tl;dr

Microservices und Deployment-Monolithen sind unterschiedliche Modularisierungsansätze. Sie haben Vor- und Nachteile und passen zu verschiedenen Szenarien. Noch wichtiger als der Modularisierungsansatz ist, dass Struktur der Software gut ist.


URL dieses Artikels:
http://www.heise.de/-3944829

Links in diesem Artikel:
[1] https://www.heise.de/developer/artikel/Microservices-lassen-Komplexitaet-verschwinden-3194643.html

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Neuigkeiten von der Insel

Effective Java - Pflichtlektüre für den professionellen Java-Entwickler

Von heise online — 16. Januar 2018 um 10:00

zurück zum Artikel

Das Warten hat ein Ende. Seit Ende letzten Jahres gibt es die 3. Auflage von Joshua Blochs Buch "Effective Java[1]". Die neue Auflage des in englischer Sprache erschienen Buchs umfasst nun auch Best Practices und Empfehlung für die mit Java 7, 8 und 9 eingeführten Features und Programmierparadigmen.

Kurzrezension

Bloch beschreibt in seinem Buch detailliert und gut verständlich, wann und wie verschiedene Java-Features eingesetzt werden sollten. "Effective Java[2]" sollte zur Pflichtlektüre eines jeden professionellen Java-Entwicklers gehören.

Wer sollte das Buch lesen

Jeder professionelle Java-Entwickler, der effizienten und wartbaren Code schreiben möchte.

Detaillierte Rezension

Es gibt viele gute Bücher über Java, die die verschiedenen Sprachfeatures erklären. Das ist aber bekanntlich nur der erste Schritt. Um effiziente und wartbare Anwendungen entwickeln zu können, muss man nicht nur die einzelnen Features kennen, sondern auch verstehen, wann und wie diese einzusetzen sind.

Dabei hat Joshua Bloch vielen Entwicklern, mich eingeschlossen, bereits mit den vorherigen Auflagen seines Buchs "Effective Java" geholfen. Seine hervorragenden Erklärungen verdeutlichen die Funktionsweise und Auswirkungen verschiedener Sprachfeatures und zeigen Best Practices für die Erstellung von leicht verständlichem und zukunftssicherem Code. Dies setzt er nun mit der 3. Auflage seines Buchs fort, das er für die Verwendung der mit Java 7, 8 und 9 eingeführten Paradigmen und Sprachfeatures aktualisiert hat. Insbesondere die Kapitel zum Design von Interfaces sowie der Verwendung von Generics und Lambdas sollten allen Entwicklern bekannt sein.

90 Items mit geballtem Java-Wissen

Während der vergangenen zwei Woche, habe ich das Buch vollständig gelesen und kann dies nur jedem empfehlen. Es war unterhaltsam und sehr lehrreich. Aber es gibt auch gute Nachrichten für alle, die nicht die Zeit haben, das ganze Buch auf einmal zu lesen. Blochs Buch ist in 90 Items unterteilt, die gezielte Ratschläge und Erläuterungen für spezifische Aufgaben und Sprachfeatures bieten. Die Items verweisen zwar aufeinander, können jedoch auch gut einzeln gelesen werden.

Durch die Unterteilung kann das Buch auch als Nachschlagewerk bei der täglichen Entwicklungsarbeit verwendet werden. Ich bin mir bereits jetzt sicher, dass ich in naher Zukunft die komplexere Items zu Lambdas und Generics noch das eine oder andere Mal lesen werde. Wie auch bereits die vorherige Auflage, wird die 3. Auflage von "Effective Java" mein Begleiter bei der Entwicklung komplexer Aufgaben und der Erstellung neuer APIs werden.

Die im Buch enthaltenen 90 Items sind thematisch in folgende Kapitel unterteilt:

  • Creating and destroying objects
  • Methods common to all objects
  • Classes and interfaces
  • Generics
  • Enums and annotations
  • Lambdas and Streams
  • Methods
  • General programming
  • Exceptions
  • Concurrency
  • Serialization

Einige Kapitel mögen auf den ersten Blick grundlegende Themen der Java-Entwicklung behandeln. Ich empfehle aber trotzdem, diese vollständig zu lesen. Auch mit mehr als 15 Jahren Erfahrung als Entwickler und Architekt habe ich aus jedem Kapitel neue Ideen und Erkenntnisse gewonnen.

Gerade deshalb möchte ich jedem professionellen Java-Entwickler die 3. Auflage[3] empfehlen.


URL dieses Artikels:
http://www.heise.de/-3937945

Links in diesem Artikel:
[1] https://www.amazon.de/Effective-Java-Joshua-Bloch/dp/0134685997/
[2] https://www.amazon.de/Effective-Java-Joshua-Bloch/dp/0134685997/
[3] https://www.amazon.de/Effective-Java-Joshua-Bloch/dp/0134685997/

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Neuigkeiten von der Insel

MicroProfile unter der Lupe, Teil 2: Health Check und Metrics API

Von heise online — 15. Januar 2018 um 12:56

zurück zum Artikel

Um ein verteiltes System verlässlich (a.k.a. reliable) zur Verfügung zu stellen, ist es wichtig, essenzielle Metriken zu monitoren. MicroProfile hat seit der Version 1.2 mit Health Check und Metrics gleich zwei passende APIs im Gepäck.

Microservice-Anwendungen zeichnen­ sich durch die Unabhängigkeit ihrer Services und einer damit verbundenen Verteiltheit des Gesamtsystems aus. Während bei einer klassischen Enterprise-Java-Anwendung ein Deployment-Artefakt in einem Server beziehungsweise einem Server-Cluster läuft und somit recht gut unter Kontrolle zu halten ist, setzt sich eine Microservice-Anwendung in der Regel aus einer Vielzahl von Services zusammen, die jeweils in eigenen Prozessen – zum Beispiel in Docker-Containern – laufen. Um ein solches Szenario in den Griff zu bekommen, sind ein ausgereiftes Monitoring zum Aufdecken aufkommender Problemsituationen sowie die automatisierte Reaktion auf die Ergebnisse des Monitorings notwendig.

Es kommt also nicht von ungefähr, dass das Eclipse-Projekt MicroProfile bereits in Version 1.2 entsprechend APIs zum Monitoren von Microservices in die Spezifikation aufgenommen hat: HealthCheck API, Metrcis APIs.

Warum aber gleich zwei APIs? Hätte denn eine nicht auch ausgereicht? Die beiden zur Verfügung stehenden APIs sprechen tendenziell unterschiedliche Bereiche des Monitorings an. Mithilfe der Health Check API[1] soll von außen festgestellt werden können, ob ein Service beziehungsweise eine Anwendung noch so läuft, wie geplant. Auf die einfache Frage "geht es dir gut?" bekommt der Anfragende ein genauso einfaches "Ja" oder "Nein" beziehungsweise die Statusmeldung "UP" oder "DOWN" als Antwort zurück. Diese Information lässt sich von Tools wie Kubernetes[2] nutzen, um den entsprechenden Service oder einzelne Komponenten des Service gezielt zu ersetzen oder zu beenden und im Anschluss neu zu starten. Die zweite API, Metrics API[3], dagegen dient dazu, gezielt Detailinformationen zum aktuellen "Gesundheitszustand" eines Service und dessen Verlauf abfragen zu können. Mithilfe von Langzeitmetriken lassen sich so zum Beispiel Wachstumspläne für die genutzte Infrastruktur aufstellen oder proaktiv auf sich abzeichnende Engpässe reagieren.

Erfinden wir hier das Rad nicht neu, wird sich jetzt der eine oder andere fragen? Wir haben doch bereits seit Jahren mit JMX und JSR 77 zwei mehr oder minder etablierte Standards im Enterprise-Java-Umfeld. Ja und nein. Insbesondere in einer per Definition als polyglott angelegten Welt – und das ist die Welt der Microservices – ist es wichtig, einen gemeinsamen und vor allem einfachen Standard für das Monitoren des Gesundheitszustandes der Services und das regelmäßige Abfragen von Metriken zu etablieren. Hierbei spielen, wie wir gleich noch sehen werden, Aspekte, wie ein standardisierter REST-Ressourcenpfad, einheitliche Datentypen oder aber auch die Definition der zu verwendenden HTTP Return-Codes eine wichtige Rolle.

Alles gesund und munter?

Mithilfe der Eclipse MicroProfile Health Check API soll die generelle Verfügbarkeit sowie der Status ("UP" oder "DOWN") einer MicroProfile-Instanz – also eines auf dem MicroProfile basierenden Microservices – geprüft werden können. Die API ist weniger für den manuellen Gebrauch als vielmehr für Szenarien im Umfeld von Container-basierten Umgebungen gedacht (M2M). So wundert es nicht, dass als Vorbild für die API proprietäre Lösungen, wie Cloud Foundry Health Check[4] oder Kubernetes Liveness and Readiness Probes[5], herangezogen wurden. Dank der Health Check API können Monitoring- und Managment-Tools durch einen einfachen GET-REST-Call des Endpoints /health automatisiert feststellen, ob ein Service wie gewünscht läuft oder gegebenenfalls ersetzt oder neu gestartet werden muss.

GET /health 

200 OK
{
"outcome" : "UP"
"checks": []
}

Besteht der Service aus mehreren Teilkomponenten, kann die Antwort des Service bei Bedarf noch weiter aufgeschlüsselt werden. Im folgenden Beispiel wird der Status des Customer REST Endpoints sowie der zugehörigen Datenbank separat durchgeführt.

200 OK 
{
"outcome": "UP",
"checks": [
{
"name": "datasource",
"state": "UP",
"data": {
"dbConnection": "...",
"dbName": "...",
"freeSpace": "..."
},
},
{
"name": "resources",
"state": "UP"
"data": {
"customers": "/customers",
"addresses": "/customers/{id}/addresses"
}
}]
}

Der aktuelle "Gesundheitszustand" des Service setzt sich in diesem Beispiel also aus zwei Komponenten zusammen. Nur wenn alle Checks den Status "UP" aufweisen, ist auch der Gesamtstatus des Services "UP", was mit einem HTTP-Status-Code 200 und entsprechender Payload quittiert wird. Andernfalls wird der Status von der Health Check API automatisch als "DOWN" interpretiert (HTTP-Status-Code 503). Konnte der gewünschte Gesundheits-Check aus irgendwelchen Gründen nicht durchgeführt werden, wird dies der aufrufenden Partei mit dem HTTP-Status-Code 500 signalisiert. In diesem Fall gilt der Status des Service als unbestimmt.

Die Implementierung und Einbindung der eben gezeigten Checks in den eigenen Microservice ist denkbar einfach. Die Health Check API stellt für diese Aufgabe sowohl ein entsprechendes Interface – HealthCheck – als auch eine Annotation - @Health - zur Verfügung.

@Health
@ApplicationScoped
public class ResourcesHealthCheck implements HealthCheck {

public HealthCheckResponse call() {
return HealthCheckResponse
.named("resources")
.withData("customers","/customers" )
.withData("addresses","/customers/{id}/addresses" )
.state(checkCustomersResource()
&& checkAddressesResource ())
.build();
}

private boolean checkCustomersResource() { return … }

private boolean checkAddressesResource() { return … }

Die Annotation werden im Kontext von CDI automatisch erkannt und die entsprechenden Beans beziehungsweise deren call()-Methoden aufgerufen, sobald ein externer Aufruf des /health-Endpoints auf dem Service erfolgt.

Mehr Details, bitte

Was aber, wenn wir nicht nur wissen wollen, ob ein Service ordnungsgemäß läuft oder eben nicht? Was, wenn uns zum Beispiel die aktuelle CPU- oder Speicherauslastung oder aber die Anzahl der derzeit verwendeten Threads interessiert? Und was, wenn wir aus historischen Daten und deren aktuellen Pendants Rückschlüsse darauf treffen möchten, wie sich unser Systemzustand entwickelt, um so zum Beispiel bei Bedarf mehr Plattenplatz zur Verfügung zu stellen oder neue Service-Instanzen zu starten beziehungsweise bestehende Instanzen zu stoppen.

Die MicroProfile Metrcis API bietet eine genormte und individuell erweiterbare Schnittstelle zur Beantwortung genau dieser Fragestellungen – und vieler anderer mehr. Mithilfe eines REST-Calls gegen den Endpoint /metrics beziehungsweise einen von drei untergeordneten Metrik-Scopes (Sub-Ressourcen: base, vendor, application) lassen sich die gewünschten Telemetrie-Daten via HTTP abfragen und über Tools, wie Prometheus[6], automatisch auswerten, um so im Anschluss entsprechende Aktionen anzustoßen.

Die Rückgabe erfolgt dabei entweder im JSON-Format, bei Angabe des Accept-Headers "application/json" oder alternativ im Prometheus Text Format (bei fehlendem Accept-Header). Es ist davon auszugehen, dass zukünftig noch weitere Formate durch die Spezifikation oder aber durch herstellerspezifische Erweiterungen unterstützt werden.

Bei dem ersten Scopes – base – handelt es sich um Telemetriedaten, die jede MicroProfile-Implementierung beim Aufruf des allgemeinen Endpoints /metrics beziehungsweise des Scope-spezifischen Endpoints /metrics/base zur Verfügung stellen muss. Hier finden sich hauptsächlich JVM-relevante Informationen:

GET /metrics/base
Accept: application/json
Authorization: Basic ....

200 OK
{
"classloader.totalLoadedClass.count": 12595,
"cpu.systemLoadAverage": 3.88525390625,
"gc.PSScavenge.time": 262,
"thread.count": 30,
"classloader.currentLoadedClass.count": 12586,
"jvm.uptime": 4795005,
"memory.committedHeap": 740818944,
"thread.max.count": 46,
"cpu.availableProcessors": 4,
"gc.PSMarkSweep.count": 3,
"thread.daemon.count": 28,
"classloader.totalUnloadedClass.count": 9,
"gc.PSScavenge.count": 13,
"memory.maxHeap": 3817865216,
"cpu.processCpuLoad": 0.00571799781527977,
"memory.usedHeap": 238923968,
"gc.PSMarkSweep.time": 448
}

Anmerkung: Wie der Beispielaufruf zeigt, geht die Spezifikation davon aus, dass der /metrics-Endpoint in irgendeiner Weise abgesichert werden kann. In welcher Art und Weise dies passiert, ist aktuell nicht spezifiziert und somit dem jeweiligen Hersteller überlassen.

Zusätzlich zu diesen universellen Metriken hat jeder Hersteller optional die Möglichkeit, eigene, in der Regel nicht portable Metriken via /metrics beziehungsweise /metrics/vendor anzubieten. Dies könnten zum Beispiel Informationen zum Zustand eines intern verwendeten Cache oder eines Messaging-Systems sein.

Besonders interessant, aus Sicht eines Microservices-Entwicklers, ist der dritte und letzte Scope: application. Auch dieser Scope ist optional und kann zur Bereitstellung von anwendungsspezifische Metriken genutzt werden.

Im folgenden Beispiel kann die Anzahl an Einschreibungen sowie die jeweils für die Einschreibungen benötigte Zeitspanne als Metrik abgefragt werden. Das Beispiel zeigt ebenfalls, dass sich, je nach gewählter Metrik, neben den aktuellen Werten auch Durchschnitts- und Trendwerte abfragen lassen:

GET /metrics/application
Accept: application/json
Authorization: Basic ....

200 OK
{
"microprofile.demo.subscriptions": 6,
"microprofile.demo.doSubscribe": {
"fiveMinRate": 0.18984199379480962,
"max": 1949047687,
"count": 6,
"p50": 901908241,
"p95": 1949047687,
"p98": 1949047687,
"p75": 1909288320,
"p99": 1949047687,
"min": 423270500,
"fifteenMinRate": 0.19664645980623557,
"meanRate": 0.12968582020280628,
"mean": 1164575631.8269844,
"p999": 1949047687,
"oneMinRate": 0.148852445426026,
"stddev": 589520048.3135717
}
}

Der Abfrage von Metriken mittels Metrics API kann auf drei unterschiedlichen Ebenen erfolgen:

  1. GET /metrics: liefert alle Metriken für alle Scopes
  2. GET /metrics/: liefert alle Metriken für den angegebenen Scope
  3. GET /metrics//: liefert die Metrik für den angegebenen Namen und Scope

Jede Metrik ist optional mit einer Reihe von Metadaten verbunden. Sie sollen aufrufenden Tools, aber auch Menschen (Operators) dabei helfen, die gelieferten Wert besser interpretieren zu können. Neben Informationen wie description und displayName sind vor allem die beiden Metadaten type (counter, gauge, meter, timer, histogram) und unit von besonderem Interesse.

Welche Metadaten einer Metrik zugeordnet sind, lässt sich leicht erfragen, indem statt eines GET- ein OPTIONS-Request gegen den entsprechenden REST-Endpoint abgesetzt wird.

Während die Metadaten bei den Scopes base von der Spezifikation vorgegeben sind, können sie bei den beiden anderen Scopes – vendor und application – frei zugeordnet werden.

Gezielte Abfragen via Tags

In dynamischen Welten, wie denen der Microservices, spielen Label beziehungsweise Tags eine besondere Rolle. Während sich die ID eines Service durch automatisches (Re-)Deployment ändern kann, können eindeutige Tags als gemeinsamer Aufhänger für gezielte Abfragen von Metriken durch Tools, wie Kubernetes und Prometheus, genutzt werden. So wäre es zum Beispiel denkbar, dass man die Metriken einer bestimmten Anwendung (app=myApp) oder alternativ einer bestimmten Schicht einer Anwendung (app=myApp && tier=database) abfragen und visuell darstellen beziehungsweise verdichtet auswerten möchte.

Damit dies möglich wird, erlaubt die Metrics API die Angabe von Tags. Dies kann entweder mithilfe der MicroProfile Config API [7]und dem Key MP_METRIC_TAGS geschehen oder alternativ über das Application Metrics Programming Model erfolgen.

Application Metrics Programming Model

Die Metrics API erlaubt es, neben den allgemeinen und herstellerspezifischen Metriken auch eigene, anwendungsspezifische Metriken im Scope application zu registrieren. Dies sind genau diejenigen Metriken, die bei einem Aufruf von /metrics/application zurückgeliefert werden.

Zur einfachen Handhabung gibt es für jeden Metrik-Typen eine eigene Annotation (@Counted, @Gauge, @Metered, @Metric, @Timed), die je nach Typ auf Klassen, Konstruktoren, Methoden oder Parametern angewandt werden können.

Das folgende Beispiel zeigt eine REST-Ressource zum Einschreiben in beziehungsweise Ausschreiben aus einem Online-Kurs. Mittels Metric API lässt sich die Anzahl der aktuellen Einschreibungen sowie Telemetrie-Daten zur dafür benötigten Zeit abfragen. Das Resultat des Aufrufs haben wir bereits weiter oben gesehen:

@Path("subscriptions")
public class SubscriptionResource {

@Inject
@Metric
(absolute = true,
name = "microprofile.demo.subscriptions",
description = "number of subscriptions ",
displayName = "current subscriptions for online course",
unit = MetricUnits.NONE)
Counter subscriptionCounter;

@POST
@Produces(MediaType.APPLICATION_JSON)
@Timed(absolute = true,
name = "microprofile.demo.doSubscribe",
displayName = "Subscription time",
description = "Time of subscription in ns",
unit = MetricUnits.NANOSECONDS)
public Response subscribe(...) {
// subscribe to online course
...
subscriptionCounter.inc();
return Response.ok()… build();
}

@DELETE
@Produces(MediaType.APPLICATION_JSON)
@Timed(absolute = true,
name = "microprofile.demo.doUnsubscribe",
displayName = "Unsubscription time",
description = "Time of unsubscription in ns",
unit = MetricUnits.NANOSECONDS)
public Response unsubscribe() {
// unsubscribe to online course
...
subscriptionCounter.dec();
return Response.ok()… build();
}
}

Wer jetzt denkt, dass ihm das Ganze bekannt vorkommt, der hat wahrscheinlich recht. Die Macher der Metrics API haben bewusst versucht, das Rad nicht neu zu erfinden und sich stattdessen an der etablierten DropWIzard Metrics API orientiert.

Wie das Beispiel zeigt, ist die Wahl des Metriknamens (name = "...") nicht ganz unwichtig. Und dies gilt gleich in zweierlei Hinsicht. Zum einen erleichtert die Wahl eines geeigneten Namens inklusive eindeutigem Namensraum, das gezielte Abfragen und Filtern von Metriken durch angebundene Tools enorm. Zum anderen verhindern versehentlich doppelt vergebene Namen das Deployment eines Microservices, da CDI dies zum Zeitpunkt des Scannings feststellt und eine IllegealArgumentException wirft. Eine Ausnahme ist nur dann erlaubt, wenn eine Metrik bewusst mit dem Attribut reusable markiert wird. In diesem Fall müssen aber alle Varianten vom selben Typ sein.

Fazit

Um ein verteiltes System verlässlich (a.k.a. reliable) zur Verfügung zu stellen, ist es wichtig, essenzielle Metriken zu monitoren. MicroProfile hat seit der Version 1.2 mit Health Check und Metrics gleich zwei passende APIs im Gepäck. Während die Health Check API lediglich die Frage nach dem allgemeinen Gesundheitszustand eines Service klärt ("UP" oder "DOWN"), lassen sich dank Metrics API Rückschlüsse auf die allgemeine Entwicklung des Service und seiner Umgebung anstellen und so proaktiv auf Tendenzen, wie die negative Entwicklung von Speicherverbrauch oder Antwortzeiten, reagieren.

Metrics unterstützt als Austauschformat zur Anbindung von Monitoring- und Management- Tools sowohl JSON und auch das Prometheus Text Format[8]. Über weitere Formate wird bereits nachgedacht. Man darf gespannt sein.


URL dieses Artikels:
http://www.heise.de/-3940913

Links in diesem Artikel:
[1] https://github.com/eclipse/microprofile-health
[2] https://kubernetes.io
[3] https://github.com/eclipse/microprofile-metrics
[4] https://docs.cloudfoundry.org/devguide/deploy-apps/healthchecks.html
[5] https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes
[6] https://prometheus.io
[7] https://www.heise.de/developer/artikel/MicroProfile-unter-der-Lupe-Teil-1-Config-API-3928886.html
[8] https://prometheus.io/docs/instrumenting/exposition_formats

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

✇ FreshRSS.org

FreshRSS 1.8.0

Von Alkarex — 11. Januar 2018 um 20:11
✇ Developer-Blog - Neuigkeiten von der Insel

Hibernate-Tipps: Einfache Möglichkeiten zur Abbildung nativer Abfrageergebnisse auf Entitäten

10. Januar 2018 um 17:14

zurück zum Artikel

Die Hibernate-Tipps-Serie bietet schnelle und einfache Lösungen zu verbreiteten Hibernate-Fragen. Dieses Mal geht es um Ergebnisse komplexer Abfragen und deren Abbildung auf managed Entitäten.

Frage:

Ich musste meine Abfrage als native SQL Abfrage[1] implementieren, da sie zu komplex für JPQL[2] ist. Gibt es eine Möglichkeit das Abfrageergebnis auf Entitäten abzubilden, ohne diese separat laden zu müssen?

Lösung:

Wenn die Abfrage alle von der Entität abgebildeten Datenbankspalten selektiert, gibt es 2 Möglichkeiten das Ergebnis auf Entitäten abzubilden:

  1. Wenn die Ergebnismenge dieselben Spaltennamen verwendet wie die durch die Entität abgebildete Datenbanktabelle, kann eine einfache, implizite Abbildung verwendet werden.
  2. Wenn die Spaltennamen der Ergebnismenge von denen der Datenbanktabelle abweichen, muss eine explizite Abbildung definiert werden.
Implizite Abbildung von Abfrageergebnissen

Für die meisten Abfragen stellt eine implizite Umwandlung des Abfrageergebnisses die einfachste und schnellste Lösung dar. Dazu muss lediglich die Klasse der selektierten Entität als zusätzlicher Parameter an die createNativeQuery Methode übergeben werden.

Book b = (Book) em.createNativeQuery("SELECT * FROM book b WHERE id = 1",
Book.class).getSingleResult();

Der EntityManager verwendet dabei die für die Entität definierten Abbildungen der Spaltennamen auf deren Eigenschaften. Daher müssen die Spaltennamen der Ergebnismenge der nativen Abfrage den Spaltennamen der durch die Entität abgebildeten Datenbanktabelle entsprechen.

Explizite Abbildung von Abfrageergebnissen

Wenn die Spaltennamen des Abfrageergebnisses von denen der Tabelle abweichen, kann eine explizite Abbildung mit Hilfe einer @SqlResultSetMapping Annotation definiert werden.

@SqlResultSetMapping(
name = "BookMapping",
entities = @EntityResult(
entityClass = Book.class,
fields = {
@FieldResult(name = "id", column = "id"),
@FieldResult(name = "version", column = "version"),
@FieldResult(name = "title", column = "title"),
@FieldResult(name = "publishingDate",
column = "publishingDate"),
@FieldResult(name = "publisher", column = "publisherid")}))

Dabei muss der Name, über den das Mapping später referenziert werden kann, und eine @EntityResul-Annotation angegeben werden. Die @EntityResult-Annotation spezifiziert, welche Klasse für jeden Datensatz instanziiert werden soll und beschreibt über eine Liste von @FieldResult-Annotationen wie die Spalten des Ergebnisses auf die Eigenschaften der Entität abgebildet werden.

Um diese Abbildung zu verwenden, muss dann lediglich der im @SqlResultSetMapping definierte Name als 2. Parameter an die createNativeQuery-Methode übergeben werden.

em.createNativeQuery("SELECT * FROM book b WHERE id = 1", 
"BookMapping").getSingleResult();

Auf diese Art und Weise kann das Ergebnis einer nativen SQL Abfrage auch auf mehrere Entitäten[3] oder auf nicht durch den Persistenzkontext verwaltete POJOs[4] abgebildet werden.

Hibernate Tips – das Buch

Mehr als 70 solcher Rezepte zu Themen wie einfache und komplexe Mappingdefinitionen, Logging, Unterstützung von Java 8, Caching sowie die statische und dynamische Erzeugung von Abfragen gibt es in meinem Buch "Hibernate Tips: More than 70 solutions to common Hibernate problems". Es ist als Taschenbuch und E-Book auf Amazon[5] und als PDF auf hibernate-tips.com[6] erhältlich.


URL dieses Artikels:
http://www.heise.de/-3937917

Links in diesem Artikel:
[1] https://www.thoughts-on-java.org/jpa-native-queries/
[2] https://www.thoughts-on-java.org/jpql/
[3] https://www.thoughts-on-java.org/result-set-mapping-complex-mappings/
[4] https://www.thoughts-on-java.org/result-set-mapping-constructor-result-mappings/
[5] https://www.amazon.de/Hibernate-Tips-solutions-common-problems/dp/1544869177
[6] http://www.hibernate-tips.com/

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Neuigkeiten von der Insel

MicroProfile unter der Lupe, Teil 1: Config API

30. Dezember 2017 um 17:52

zurück zum Artikel

Das Eclipse-MicroProfile-Projekt ist angetreten, eine portable Lösung für Microservices im Enterprise-Java-Umfeld zu liefern. Neue APIs sollen die Lücke zwischen dem Java-EE-Standard und den Praxisanforderungen von Microservices-Architekturen schließen.

Microservices und Java EE (a.k.a. EE4J)? Das passt nicht wirklich! So zumindest die landläufige Meinung, wenn es darum geht, Microservice-Anwendungen auf Grundlage des Java-Enterprise-Standard umzusetzen. Dabei bietet Java EE mit JAX-RS, CDI, JPA und JSON-P alles, was es braucht, um RESTful-Microservices zu implementieren. Und auch asynchrone, auf Messages oder Events basierende Services lassen sich dank JMS, WebSockets und Server-Sent Events (seit Java EE 8) mit wenigen Zeilen Code realisieren. Wo also liegt das Problem?

Microservice-Anwendungen zeichnen sich in der Regel dadurch aus, dass eine Vielzahl von Services, die jeweils in eigenen Prozessen laufen, miteinander interagieren und so ein großes Ganzes ergeben. Nicht selten werden diese Services zusätzlich in Containern verpackt und in der Cloud deployt. Unterm Strich haben wir es also mit einem hoch dynamischen, stark verteilten System zu tun.

Die eigentliche Herausforderung liegt somit weniger in der Umsetzung der (fachlichen) Logik eines einzelnen Service als vielmehr in der Realisierung des reibungslosen Zusammenspiels der Gesamtheit aller Services. Und genau hier liegt das Problem beziehungsweise die Schwachstelle von Java EE. Denn Java EE ist darauf ausgerichtet, dass die einzelnen Artefakte – in diesem Fall also die Services – innerhalb eines Application Server deployt werden, damit dieser übergreifende Dienste (Cross-Cutting Concerns) wie Configuration, Monitoring, Logging, Security et cetera übernehmen kann. Fällt der Server weg oder gibt es mehrere autarke Server-Instanzen, von denen jede einen eigenen Microservice verwaltet, fehlt die koordinierende Schaltzentrale.

Genau dieses Manko hat auch eine Reihe von Application-Server-Anbietern erkannt und 2016 die Initiative MicroProfile.io[1] ins Leben gerufen. Die inzwischen in der Eclipse Foundation beheimatete Initiative ist angetreten, die Lücke zwischen dem Java-Enterprise-Standard und den Praxisanforderungen Microservices-basierter Architekturen zu schließen. Laut eigener Aussagen möchte man das bestehende Momentum der Java-EE-Community als Hebel nutzen und organisch um den Bedarf der Microservices-Community ergänzen. Der Plan scheint aufzugehen. In nur wenigen Monaten ist es gelungen, eine Reihe sinnvoller Microservices-relevanter APIs mit bestehenden Java-EE-7/8-APIs zu kombinieren und diese in regelmäßigen MicroProfile-Releases zu veröffentlichen. Egal ob Health Check, Metrics, Fault Tolerance, JWT Propagation, Configuration, Tracing oder Open API, MicroProfile scheint die richtigen Antworten – sprich APIs – im Gepäck zu haben.

Dieser Blogbeitrag ist der erste Teil einer kleinen Serie, die sich mit den Microservice-spezifischen APIs des MicroProfiles beschäftigt. Also den APIs, die nicht Bestandteil der Java-EE-Spezifikation sind. Den Anfang macht die Config API, die erst vor wenigen Tagen in der Version 1.2 veröffentlicht wurde.

Das kleine Einmaleins der Config API

Die Idee, Anwendungslogik und Konfiguration voneinander zu trennen, ist nicht wirklich neu. Mithilfe einer ausgelagerten Konfiguration lässt sich die Anwendung beziehungsweise der Service von außen auf die jeweilige Laufzeitumgebung anpassen. Für die lokale Testumgebung nutzt man zum Beispiel im Test-Quellcode vorgegebene Einstellungen, während die Laufzeitumgebung des Containers in einer produktiven Umgebung innerhalb eines Containers in der Cloud die notwendigen Werte für die Konfiguration setzt.

Was einfach klingt, kann in der Praxis zu unerwarteten Herausforderungen führen. So stammen die einzelnen Werte für die Konfiguration einer Anwendung beziehungsweise eines Service in der Regel aus mehreren verschiedenen Quellen, wie System Properties, Umgebungsvariablen, Dateien, Datenbanken oder proprietären Konfigurationsquellen. Auch das Format, in dem die Werte abgelegt sind, ist oftmals nicht einheitlich und entspricht normalerweise nicht dem Objektformat, in dem die Konfigurationswerte innerhalb der Anwendung beziehungsweise des Service verwendet werden sollen. Während es bei statischen Konfigurationswerten ausreicht, diese einmalig beim Start zu laden, sind dynamische Werte permanent auf ihre Aktualität zu prüfen und bei Bedarf neu einzulesen. Und natürlich sollte eine Anwendung auch dann noch sinnvoll funktionieren, wenn eine Konfiguration einmal nicht gefunden werden kann.

All diese Aspekte und noch etliche mehr berücksichtigt die MicroProfile Config API (im Folgenden Config API). Sie bietet einen vereinheitlichen Zugriff auf verschiedenste Konfigurationsquellen an. Die einzelnen Quellen lassen sich dabei mit Prioritäten versehen, sodass ein gezieltes Überschreiben von Konfigurationen möglich wird. Von Haus aus kennt die Config API drei verschiedene Quellen:

  • System Properties via System.getProperties( ) (ordinal = 400 )
  • Umgebungsvariablen via System.getenv( ) (ordinal = 300)
  • lokale Konfigurationsdatei via META-INF/microproifile-config.properties (ordinal = 100)

Standardwerte für die Konfiguration können so in einer Datei mit dem Namen microproifile-config.properties im Verzeichnis META-INF abgelegt und bei Bedarf in den jeweiligen Deployment-Umgebungen überschrieben werden. Natürlich ist es auch möglich, eigene Quellen einzubinden und mit einer individuellen Priorität zu belegen. Zum Beispiel ließe sich ein zentraler Key-Value-Store als weitere Konfigurationsquelle verwenden.

Und "action" ...

Die Config API bietet zwei unterschiedliche Wege zum Zugriff auf die im Hintergrund verwalteten Konfigurationen. Zum einen kann der Zugriff programmatisch erfolgen, zum anderen via CDI Injection.

Der programmatische Zugriff erfolgt mithilfe einer Instanz der Config-Klasse, die sich im einfachsten Fall via ConfigProvider erzeugen lässt:

// get access to the Config instance via ConfigProvider 
Config config = ConfigProvider.getConfig();

// access config properties via Config instance
String someStringValue = config.getValue("SOME_STRING_KEY", String.class);
Boolean someBooleanValue = config.getValue("SOME_BOOL_KEY", Boolean.class);

Möchte man beim Erstellung der Config-Instanz mehr Einfluss nehmen, kann anstelle des ConfigProvider auf einen ConfigBuilder zurückgegriffen werden. Der Builder erlaubt die eine oder andere individuelle Anpassung. Der oben gezeigte Code würde mit einem ConfigBuilder wie folgt aussehen:

// get access to the Config instance via ConfigBuilder
ConfigBuilder builder = ConfigProviderResolver.getBuilder();
builder.addDefaultSources();
Config config = builder.build();

// access config properties via Config instance
String someStringValue = config.getValue("SOME_STRING_KEY", String.class);
Boolean someBooleanValue = config.getValue("SOME_BOOL_KEY", Boolean.class);

Anmerkung: Bei der Verwendung des ConfigProvider wird die beim Aufruf der getConfig()-Methode zurückgelieferte Config-Instanz aus Gründen der Effizienz automatisch gecacht. Das ist bei der Verwendung des ConfigBuilder beziehungsweise des ConfigProviderResolver nicht der Fall.

Deutlich einfacher als der ebene gezeigte programmatische Zugriff ist der via CDI Injection:

@Inject @ConfigProperty("SOME_STRING_KEY")
String someStringValue;

@Inject @ConfigProperty("SOME_BOOL_KEY")
String someBooleanValue;

Was aber, wenn sich der gesuchte Schlüssel in keiner der Konfigurationsquellen finden lässt? Im obigen Beispiel würde das automatisch zu einer Exception führen. Im ersten Beispiel, dem programmatischen Zugriff, wäre es eine NoSuchElementExeption zur Laufzeit. Im zweiten Beispiel dagegen, im Falle der CDI Injection, würde eine DeploymentException während des Start-ups geworfen werden.

Optionale Konfiguration

Soll eine Konfiguration lediglich optional sein, um so zum Beispiel nur in speziellen Umgebungen Standardwerte zu überschreiben, in anderen dagegen nicht, ist dies ebenfalls für beide gezeigten Zugriffsmechanismen möglich. Im Falle des programmatischen Zugriffs sieht das wie folgt aus:

// get access to the Config instance 
Config config = ConfigProvider.getConfig();

// access optional string property
String someStringValue = config.getOptionalValue("SOME_KEY", String.class)
.orElse("someDefaultValue");

Bei CDI Injection dagegen reicht die einfache Angabe eines Default-Werts vom richtigen Typ:

// inject optional property
@Inject @ConfigProperty("SOME_KEY", defaultValue="someDefaultValue")
String someValue;

Just-in-Time-Konfiguration

Auch wenn Microservice-basierte Anwendungen so entworfen sein sollten, dass sie einen Restart einzelner Services problemlos überleben, macht es sicherlich keinen Sinn, einen Service jedes Mal neu zu starten, nur weil sich ein Wert einer Konfiguration geändert hat. Aus diesem Grund sieht die Config API einen Mechanismus vor, Konfigurationswerte dynamisch in dem Moment der Verwendung zu laden.

Das macht natürlich wenig Sinn, wenn die Konfigurationsquelle eine gemeinsam mit dem WAR deployte Properties-Datei ist. Anders dagegen sieht es schon aus, wenn als Quelle eine Datenbank oder ein Konfigurationsserver angebunden wird.

Um in dem Moment der Nutzung einer Property tatsächlich immer ihren aktuellen Wert und nicht den Wert zum Zeitpunkt der Injection zu erhalten, muss anstelle der ConfigProperty ein Provider injiziert werden. Mithilfe des Providers und dessen get()-Methode kann anschließend eine Just-in-Time-Konfiguration erfolgen.

// inject property provider
@Inject @ConfigProperty("SOME_KEY")
Provider someValueProvider;
...
// get property value "just-in-time" via provider
String someValue = someValueProvider.get();

Der Begriff "Just-in-Time" ist in diesem Fall allerdings eher relativ zu sehen und bedeutet lediglich, dass der gerade in der Konfigurationsquelle hinterlegte Wert herangezogen wird. Wie die Quelle wiederum die Werte aktualisiert und wann auf ihr ein Refresh durchgeführt wird, ist nicht spezifiziert und somit dem Autor der ConfigSource-Klasse überlassen. Die Implementierung von OpenLiberty zum Beispiel erlaubt die Angabe einer Refresh-Rate via System-Property microprofile.config.refresh.rate für die Konfigurationsquellen. Der Standardwert liegt bei 500 (ms), sodass bei Bedarf alle halbe Sekunde ein Refresh erfolgt.

Converter

Die Config API unterstützt, wie im ersten Beispiel gezeigt, nicht nur Properties vom Typ String. Dank sogenannter Converter lassen sich die in den Konfigurationsquellen hinterlegten String-Werte in beliebige Java-Typen überführen.

Für eine Reihe von Java-Typen existieren bereits sogenannte Build-in Converter. Neben den bisher gezeigten Typen String und Boolean werden unter anderem auch Integer, Long, Double, Float sowie Duration, LocalTime, LocalDate, LocalDateTime, Instant und URL "out of the box" unterstützt. Und auch die Verwendung von Arrays ist seit Version 1.2 möglich:

// injection list property via array converter 
@Inject @ConfigProperty("SOME_LIST_KEY")
private List someListValues;

...

// get access to the Config instance via ConfigProvider
Config config = ConfigProvider.getConfig();
// access config properties via Config instance
private String[] someArrayValues = config.getValue("SOME_ARRAY_KEY", String[].class);

Was aber, wenn nicht unterstützte oder eigene Datentypen via Config API gesetzt werden sollen? In diesem Fall lässt sich ein spezifischer Custom-Converter, der das Converter-Interface implementiert, nutzen. Das folgende Beispiel zeigt einen einfachen Converter für eine Klasse namens Email:

@Priority(200)
public class EmailConverter implements Converter {

@Override
public Email convert(String email) throws IllegalArgumentException {
return new Email(email);
}
}

Damit der Converter zur Laufzeit automatisch herangezogen werden kann, muss er zusätzlich registriert werden. Dies kann entweder via Java ServiceLocator – durch Angabe des voll qualifizierten Klassennamens des Converters in einer entsprechenden Datei META-INF/services/org.eclipse.microprofile.config.spi.Converter – geschehen oder alternativ programmatisch mithilfe des ConfigBuilder:

// get access to the Config instance via ConfigBuilder
ConfigBuilder builder = ConfigProviderResolver.getBuilder();
builder.addDefaultSources();

// add custom converter for Email class
Converter emailConverter = new EmailConverter();
builder.withConverters(emailConverter);
Config config = builder.build();

// read email property into email object
Optional emailOpt = config.getOptionalValue("ADMIN_EMAIL", Email.class);
...

Wie das Listing des EmailConverter zeigt, lassen sich auch Converter mit einer Priorität versehen. Sind also mehrere Converter für denselben Typ registriert, dann überschreibt der Converter mit der höheren Priorität diejenigen mit geringerer Priorität. Der Standardwert ist 100.

Fazit

Alles in allem macht die Config API einen runden Eindruck, was aber auch nicht wirklich verwundert, wenn man einmal einen genaueren Blick auf die Ursprünge der API wirft:

  • DeltaSpike Config[2]
  • Apache Tamaya[3]

Wer ein wenig Lust bekommen hat, die API einmal auszuprobieren, kann das mit folgenden Implementierungen tun:

  • Apache Geronimo Config[4]
  • WebSphere Liberty [5]
  • Payara Server 174/Payara Micro 174[6]
  • WildFly/WildFly Swarm[7]

Für die Zukunft sind bereits weitere Features geplant. Ein Hauptaugenmerk wird darauf liegen, dynamische Konfigurationsänderungen besser zu unterstützen. Man darf gespannt sein.


URL dieses Artikels:
http://www.heise.de/-3928886

Links in diesem Artikel:
[1] https://microprofile.io
[2] https://deltaspike.apache.org/documentation/configuration.html
[3] http://tamaya.incubator.apache.org/index.html
[4] https://github.com/apache/geronimo-config
[5] https://developer.ibm.com/wasdev/
[6] https://docs.payara.fish/documentation/microprofile/config.html
[7] https://github.com/wildfly-extras/wildfly-microprofile-config/

Copyright © 2017 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Tales from the Web side

Features von übermorgen: die Payment Request API

Von heise online — 19. Oktober 2017 um 11:19

zurück zum Artikel

Das Implementieren von Bestell- beziehungsweise Bezahlprozessen innerhalb von Webanwendungen kann mitunter recht komplex sein. Die sogenannte Payment Request API [1], die momentan beim W3C ausgearbeitet wird und vor etwa einem Monat zusammen mit den Payment Method Identifiers [2] als "Candidate Recommendation" veröffentlicht wurde, soll hier Abhilfe schaffen.

Die API sieht vor, den Browser als Vermittler zwischen folgenden bei einem Bestellprozess involvierten Akteuren einzusetzen: dem Zahlungsempfänger (beispielsweise einem Online-Händler), dem Zahlungssender (also dem Käufer) und demjenigen, der die Hilfsmittel für eine Zahlung bereitstellt (Kreditkarte etc.).

Folgende Typen werden durch die API bereitgestellt:

  • PaymentRequest: repräsentiert eine Anfrage für einen Bestellprozess.
  • PaymentAddress: repräsentiert eine Rechnungsadresse.
  • PaymentResponse: repräsentiert die Antwort für einen Bestellprozess.
  • PaymentRequestUpdateEvent: Event, das ausgelöst wird, wenn sich die Details einer Bestellanfrage ändern.

Browser-Support

Ob die API vom aktuellen Browser unterstützt wird, lässt sich innerhalb einer Website wie gewohnt über Feature Detection prüfen, beispielsweise durch Überprüfung auf das PaymentRequest-Objekt:

if (window.PaymentRequest) {
// Payment Request API wird unterstützt
} else {
// Payment Request API wird nicht unterstützt
}

Momentan unterstützen lediglich Chrome, Opera und Microsoft Edge die API [3], in Firefox kann die API als experimentelles Feature über das Flag "dom.payments.request.enabled" unter "about:config" aktiviert werden.

Bezahlanfragen formulieren

Um eine Bezahlanfrage zu formulieren, erstellt man eine Instanz von PaymentRequest, wobei dem Konstruktor drei Konfigurationsobjekte als Parameter übergeben werden können:

const methodData = { /* siehe Listings unten */ };
const details = { /* siehe Listings unten */ };
const options = { /* siehe Listings unten */ };
const paymentRequest = new PaymentRequest(
methodData,
details,
options
);

Über methodData lassen sich die zur Verfügung stehenden Bezahlmethoden angeben. Der Eigenschaft supportedMethods kann dabei ein Array von Kennzeichnern für unterstützte Bezahlmethoden hinterlegt werden:

// Konfiguration der Bezahlmethoden
const methodData = [
{
supportedMethods: ['basic-card'],
data: {
supportedNetworks: ['visa', 'mastercard'],
supportedTypes: ['debit', 'credit'],
}
}
];

Nähere Angaben zu der Bestellung wie etwa Identifikationsnummer einer Bestellung, die zu bestellenden Artikel, Versandkosten etc. lassen sich über das Konfigurationsobjekt details konfigurieren:

// Konfiguration der Bestelldetails
const details = {
id: 'order-123-12312',
displayItems: [
{
label: 'Summe',
amount: { currency: 'EUR', value: '25.00' },
},
{
label: 'Mehrwertsteuer',
amount: { currency: 'EUR', value: '4.75' },
},
],
shippingOptions: [
{
id: 'standard',
label: 'Standardversand',
amount: { currency: 'EUR', value: '5.00' },
selected: true,
},
{
id: 'express',
label: 'Expressversand',
amount: { currency: 'EUR', value: '11.00' },
},
],
total: {
label: 'Gesamtsumme',
amount: { currency: 'EUR', value: '34.75' },
},
};

Über das dritte Konfigurationsobjekt options lässt sich definieren, welche Informationen der Nutzer während des Bestellvorgangs eingeben muss, beispielsweise Name, E-Mail-Adresse oder Telefonnummer:

// Konfiguration der Pflichtangaben
const options = {
requestPayerEmail: true,
requestPayerName: true,
requestPayerPhone: true,
requestShipping: true,
};

Bezahlanfragen absenden

Um eine Bezahlanfrage zu starten und damit den entsprechenden Dialog zu öffnen, verwendet man die Methode show() am PaymentRequest-Objekt. Zurück gibt die Methode ein Promise-Objekt, das erfüllt wird, wenn der Nutzer den Bezahlprozess über den Dialog abschließt. Innerhalb des darauf folgenden Callbacks lässt sich dann auf die vom Nutzer eingegebenen Daten zugreifen, üblicherweise um sie zur Überprüfung an den Server zu senden (im Folgenden durch den Aufruf von verify() symbolisiert).

// Hier normalerweise Überprüfung durch Server
const verify = (paymentResponse) => Promise.resolve(true);

Der Aufruf der Methode complete() teilt dem Browser anschließend mit, dass der Bezahlprozess abgeschlossen wurde. Als Parameter lassen sich hier die Werte "success" für eine erfolgreiche Bezahlung oder "failure" bei Auftreten eines Fehlers übergeben. Dem Browser steht es laut Spezifikation dann frei, ob er eine entsprechende Meldung anzeigt oder nicht.

paymentRequest.show()
.then((paymentResponse) => {
// Zugriff auf die vom Nutzer
// eingegebenen Daten.
const {
requestId,
methodName,
details,
shipping,
shippingOption,
payerName,
payerEmail,
payerPhone
} = paymentResponse;
// verify() als imaginäre Funktion, mit der
// die Bezahlanfrage mit der Serverseite überprüft wird
verify(paymentResponse).then((success) => {
if (success) {
console.log('Bezahlung erfolgreich durchgeführt');
return paymentResponse.complete('success');
} else {
console.error('Fehler bei Bezahlung');
return paymentResponse.complete('failure');
}
});
})
.catch((error) => {
console.error('Fehler:', error);
});

Fazit

Die Payment Request API will Bestell- bzw. Bezahlprozesse innerhalb von Webanwendungen vereinfachen und vereinheitlichen. Wer die API heute schon testen möchte, kann den oben gezeigten Code in einem der zuvor genannten Browser ausführen. Anmerkungen und Verbesserungsvorschläge zur API kann man übrigens über die Issue-Seite [4] des entsprechenden GitHub-Projekts loswerden.


URL dieses Artikels:
http://www.heise.de/-3694012

Links in diesem Artikel:
[1] https://www.w3.org/TR/payment-request/
[2] https://www.w3.org/TR/payment-method-id/
[3] http://caniuse.com/#feat=payment-request
[4] https://github.com/w3c/browser-payment-api/issues

Copyright © 2017 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Continuous Architecture

Collective Code Ownership: Ein Anti-Pattern?

Von heise online — 06. Dezember 2017 um 07:15

zurück zum Artikel

Gemeinsame Verantwortung für Code hört sich nach einer gute Idee an. Aber sie ignoriert wichtige Konzepte der Softwareentwicklung.

Collective Code Ownership stammt aus dem Extreme Programming (XP), einer frühen agilen Methode. Es bedeutet, dass alle Entwickler jedes Problem beheben müssen, das sie im Code finden. Gemeinsam die Verantwortung für ein System zu übernehmen, sorgt dafür, das Probleme beseitigt werden, statt sie einfach hinzunehmen. Moderne Ansätze für Projektarbeit setzten auf eigenverantwortliche Teams. Dafür ist bei Softwareentwicklung die Verantwortung für den Code sicherlich zentral.

Woher wissen die Entwickler, was verbessert werden muss und wie das geschehen soll? Im Buch "Extreme Programming Explained" von Kent Beck steht, dass nicht alle Entwickler Experten für jeden Codeteil sein können, aber sie müssen zumindest ein grundlegendes Verständnis für den gesamten Code haben.

Information Hiding

Wissen über den gesamten Code widerspricht dem Information Hiding, das schon in einem anderen Beitrag[1] eine Rolle gespielt hat. Information Hiding bedeutet, dass Nutzer eines Moduls nur die Schnittstelle kennen, aber nicht die Interna. Das erleichtert die Nutzung des Modul, weil Nutzer weniger über das Modul wissen muss. Das Modul ist auch einfacher änderbar. Änderungen sind ohne Beeinträchtigung der Nutzer des Moduls möglich, so lange die Schnittstelle unverändert bleibt.

Collective Code Ownership fordert aber mehr als nur Wissen über die Schnittstelle. Jeder muss die Interna aller Module zumindest oberflächlich verstehen. Welche Alternativen gibt es?

Alternativen

Für jedes Modul könnte ein Entwickler verantwortlich sein. Das hat entscheidende Nachteile. Wenn die zuständigen Entwickler Urlaub haben oder krank werden, wird es schwierig, das Modul zu ändern, weil nur sie das Modul verstehen.

Eine Lösung ist, dass mehrere Entwickler jedes Modul kennen, aber nicht alle Entwickler jedes Modul kennen. Die Organisation spielt dabei eine wichtige Rolle: Das Gesetz von Conway[2] besagt, dass die Softwarearchitektur den Kommunikationsbeziehungen unter den Entwicklern entspricht. Die These: Entwickler sind jeweils für ein oder mehrere Module zuständig und müssen miteinander reden, wenn sie Module anderer Entwickler nutzen wollen. Auch das widerspricht dem Collective Code Ownership, weil nicht jeder Entwickler jeden Code versteht oder gar ändern kann

Kommunikation innerhalb eines Teams ist einfacher. Sie arbeiten oft in denselben Räumlichkeiten und haben gemeinsame Meetings. Das erleichtert die Kommunikation. Bessere Kommunikation kann nach dem Gesetz von Conway Auswirkungen auf die Architektur haben. Wenn Entwickler aus einem Team den Code anderer Teammitglieder kennen, kann das ein Zeichen guter Zusammenarbeit im Team sein. Wenn die Entwickler die Module anderer Teams kennen müssen, dann ist dazu aufwendige Kommunikation wie während extra organisierter Meetings notwendig. Also sollte Collective Code Ownership auf Teams beschränkt sein und nicht die gesamte Organisation umfassen.

tl;dr

Collective Code Ownership bedeutet, Verantwortung für Code zu übernehmen und Code zu verbessern. Das ist ein gute Sache. Den gesamten Code zu verstehen, ist dank Modularisierung zum Glück nicht notwendig.


URL dieses Artikels:
http://www.heise.de/-3909449

Links in diesem Artikel:
[1] https://www.heise.de/developer/artikel/Meine-Datenbank-gehoert-mir-3608372.html
[2] http://www.melconway.com/Home/Conways_Law.html

Copyright © 2017 Heise Medien

Let's block ads! (Why?)

✇ Developer-Blog - Continuous Architecture

Independent System Architecture: Prinzipien für Microservices

16. November 2017 um 10:15

zurück zum Artikel

Die Independent System Architecture (ISA) stellt Prinzipien für Microservices auf. ISA definiert grundlegende Eigenschaften von Microservices, die erhebliche Probleme aufwerfen, wenn sie nicht eingehalten werden.

Das Ziel ist, die fundamentalen Konzepte von Microservices darzustellen und nicht nur einen bestimmten Ansatz, Microservices umzusetzen, wie dies Self-contained Systems[1] (SCS) tun. SCS waren schon Thema eines anderen Blog-Beitrags[2].

Die Prinzipien

Es gibt neun Prinzipien:

1. Das System ist in Module aufgeteilt. Module sind eine alte Idee. Das erste Prinzip stellt Microservices in diese Tradition. So wird deutlich, dass andere Modularisierungsansätze Alternativen zu Microservices sein können. Wegen des Modulbegriff treffen auch Konzepte wie Information Hiding auf Microservices zu. Microservices dürfen daher nicht von den Interna anderer Microservices abhängen. Beispiel: Wie Klassen in einem OO-System keine internen Daten anderer Klassen (Instanzvariablen) nutzen dürfen, so dürfen Microservices nicht Daten anderer Microservices direkt auslesen, indem sie beispielsweise auf die Datenbank-Schemata des Microservice zugreifen.

2. Die Module laufen als Docker-Container, Prozesse oder virtuelle Maschinen. Also würde ein Bestellprozess-Modul beispielsweise in einem eigenen Docker-Container laufen. Diese Implementierung unterscheidet ISA fundamental von anderen Modularisierungen und hat einige Vorteile. Beispielsweise können Module in unterschiedlichen Programmiersprachen geschrieben sein oder unabhängig voneinander deployt werden.

3. Die Architektur wird in die Mikro-Architektur, die nur einzelne Module betrifft, und die Makro-Architektur unterteilt, die das gesamte System umfasst. Die Makro-Architektur gibt die minimalen Regeln vor, um die langfristige Evolution sicherzustellen und zu garantieren, dass das System nach außen wie ein System erscheint. Die weiteren Prinzipien sind Teile der Makro-Architektur.

4. Die Integration der Module muss definiert sein. Die Module können synchron, asynchron oder auf der UI-Ebene integriert werden. Das ist notwendig, damit das System am Ende tatsächlich ein System ist und nicht etwa nur Module ohne Zusammenhalt.

5. Kommunikation beispielsweise per RESTful HTTP oder Messaging muss ebenfalls standardisiert sein, damit die Module miteinander kommunizieren können.

6. Jedes Modul hat eine eigene Continuous Delivery Pipeline. Die Module können prinzipiell unabhängig voneinander deployt werden, weil sie als Container umgesetzt sind. Mit einer getrennten Continuous Delivery Pipeline ist ein getrenntes Deployment auch tatsächlich möglich. Da die Pipeline vor allem Tests umfasst, müssen also insbesondere die Test der Module unabhängig voneinander sein.

7. Der Betrieb sollte standardisiert sein. Das betrifft zum Beispiel Logs, Monitoring, Konfiguration und Deployment. Die Standardisierung reduziert den Aufwand, weil so zwar die Anzahl der Containern steigt, aber sie zumindest einheitlich behandelt werden können.

8. Alle Standards sollen auf Ebene der Schnittstelle definiert sein. Eine Kommunikation per RESTful HTTP mit einem festen Datenschema oder ein bestimmtes Monitoring-System auf einem bestimmten Server sind Standardisierungen auf Ebene der Schnittstelle. Wenn die konkrete REST-Bibliothek oder eine Bibliothek für Monitoring vorgegeben wird, wird die Technologie standardisiert. Das schränkt die mit ISA gewonnenen Freiheiten ein. In einem Projekt kann sich natürlich dennoch ein einheitlicher Technologie-Stack durchsetzen und so Aufwände einsparen. Langfristig kann der Stack bei der Evolution des Systems durch einen anderen Stack abgelöst oder ergänzt werden, ohne die Standards zu verletzen. So kann der Technologie-Stack aktualisiert werden, und das System bleibt zukunftssicher.

9. Resilience ist die Fähigkeit eines Moduls, bei einem Ausfall eines anderen Moduls weiter zu funktionieren - gegebenenfalls mit schlechteren Ergebnissen. Das unterbindet Fehlerkaskaden, bei denen der Ausfall eines Moduls andere Module ebenfalls zum Ausfall bringt und so das gesamte System letztendlich ausfällt. Ebenso müssen Module damit umgehen können, dass sie auf einen anderen Server neu gestartet werden. Das erleichtert den Betrieb im Cluster, bei dem Module auf unterschiedlichen Servern laufen müssen und gegebenenfalls Server ausfallen oder gewartet werden müssen.

Weitere Informationsquellen

Dieser Blog-Beitrag bietet nur eine Einführung in die ISA-Prinzipien. Weitere Informationen finden sich unter isa-principles.org[3]. Insbesondere die Begründungen sind für ein besseres Verständnis interessant.
Die gesamte Website steht unter Creative Commons Attribution Share Alike. Der Quellcode der Website findet sich auf GitHub[4] wieder. Wer Verbesserungsvorschläge oder Kritik hat, kann einen Issue einstellen, einen Pull Request erstellen oder an der Diskussion[5] teilnehmen. Ebenso gibt es eine Präsentation[6], die man auch als PowerPoint[7] herunterladen kann und die ebenfalls unter Creative Commons Attribution Share Alike steht.


URL dieses Artikels:
http://www.heise.de/-3889160

Links in diesem Artikel:
[1] http://scs-architecture.org
[2] https://www.heise.de/developer/artikel/Self-contained-Systems-ein-Architekturstil-stellt-sich-vor-3038718.html
[3] http://isa-principles.org
[4] https://github.com/ISA-Principles/isa-principles.org/
[5] http://isa-principles.org/discussion.html
[6] http://isa-principles.org/slidedeck/ISA.pptx
[7] https://speakerdeck.com/isaprinciples/isa-principles

Copyright © 2017 Heise Medien

Let's block ads! (Why?)

✇ iX news ff.org

Newsticker | iX Magazin | heise online

13. April 2026 um 14:40

iX mit 30 % Rabatt lesen2 Ausgaben iX mit 30 % Rabatt

iX richtet sich an IT-Profis, gibt tiefe Einblicke und Orientierung in aktuelle IT-Entwicklungen. Jetzt im Abo testen – Sie entscheiden, ob gedruckt, digital oder kombiniert mit Zugriff auf das Artikel-Archiv.iX richtet sich an IT-Profis, gibt tiefe Einblicke und Orientierung in aktuelle IT-Entwicklungen. Jetzt im Abo testen – Sie entscheiden, ob gedruckt, digital oder kombiniert mit Zugriff auf das Artikel-Archiv.

Adblock test (Why?)

✇ iX news ff.org

Google erweitert ARCore und verabschiedet sich endgültig von Tango

Von heise online — 18. Dezember 2017 um 09:45

zurück zum Artikel

Google erweitert ARCore und verabschiedet sich endgültig von Tango

Die zweite Developer Preview von ARCore bringt neben erweiterten Funktionen eine C-API für Android. Das Projekt Tango ist nun endgültig Geschichte: Der Internetriese stellt den Support für das ambitionierte, frühe AR-Projekt ein.

Nachdem Google bereits im Sommer beschlossen hatte[1], die AR-Plattform (Augmented Reality) Tango durch das deutlich einfachere ARCore zu ersetzen, verkündet ein Blogbeitrag[2] nun das endgültige Aus für Tango mit dem Einstellen des Supports für das bereits 2014 offiziell gestartete AR-System. Die Erfahrungen aus dem Projekt, das mit Johnny Chung Lee einen ausgewiesenen Experten für Mensch-Computer-Interaktion als Leiter hatte, sind in ARCore eingeflossen. Lee war zuvor maßgeblich in Microsofts Kinect-Entwicklung eingebunden, ist aber wohl nicht in Googles aktuelle AR-Plattform involviert.

Mit dem Plattformwechsel verspiele der Internetriese auch den Vorsprung gegenüber Apple: ARKit ist zwar erst seit iOS 11 verfügbar, dafür läuft es inzwischen funktionsfähig auf mehreren Millionen Geräten. Google hat von ARCore dagegen noch keine Variante für Android-Endanwender, sondern veröffentlicht nun die zweite Developer Preview der Plattform. Allerdings wird der Internetriese wohl das Tempo noch weiter anziehen, um ebenfalls eine breite Palette an Endgeräten zu bedienen. Der Vorteil von ARCore gegenüber Tango ist, dass die Plattform keine spezielle Hardware benötigt, sondern lediglich die standardmäßig verfügbaren Sensoren und die Kamera nutzt.

Anbindung an Android NDK und AR-Pause

Die zweite Developer Preview von ARCore bringt zudem erstmals eine Anbindung an die C-API für Android, sodass Entwickler AR-Anwendungen künftig mit dem Android NDK (Native Development Kit) schreiben können. ARCore lässt sich bereits mit Java sowie den Game-Engines Unity[3] und Unreal[4] verwenden. Auch Telerik entwickelt ein AR-Plug-in für NativeScript [5], das sowohl mit ARKit als auch mit ARCore zusammenarbeitet. Ebenfalls neu in der zweiten Developer Preview ist die Möglichkeit, AR-Sessions zu pausieren, um beispielsweise Anrufe anzunehmen. Außerdem vermeldet der Blogbeitrag eine erhöhte Genauigkeit und eine bessere Effizienz.

Ein genaues Datum für die Veröffentlichung von ARCore v1.0 bleibt der Blogbeitrag schuldig, stattdessen heißt es vage "innerhalb der nächsten Monate". Die ARCore-Projektseite[6] zeigt einige erste Anwendungen, und Google AR-Entwickler-Site[7] bietet Einstiegshilfen für Programmierer. Gerade die Anbindung an Unity und Unreal dürfte für Entwickler spannend sein, da sie damit ihre Mixed-Reality-Spiele plattformübergreifend für Apples und Googles Mobilsystem sowie möglicherweise zusätzlich für Windows Mixed Reality schreiben können.


URL dieses Artikels:
http://www.heise.de/-3920207

Links in diesem Artikel:
[1] https://www.heise.de/meldung/Googles-Augmented-Reality-Tango-ist-tot-es-lebe-ARCore-3817226.html
[2] https://www.blog.google/products/google-vr/arcore-developer-preview-2/
[3] https://www.heise.de/meldung/Spiele-Engine-Unity-2017-2-zielt-vor-allem-auf-2D-Entwicklung-und-Extended-Reality-3860769.html
[4] https://www.heise.de/meldung/Unreal-Engine-4-18-bringt-verbesserte-Lichteffekte-3871165.html
[5] https://www.heise.de/meldung/Cross-Platform-Entwicklung-NativeScript-bekommt-ein-AR-Plug-in-3829393.html
[6] https://thisisarcore.com/
[7] https://developers.google.com/ar/
[8] mailto:rme@ct.de

Copyright © 2017 Heise Medien

Let's block ads! (Why?)

✇ iX news ff.org

Google gibt AR-Plattform Tango auf

Von heise online — 16. Dezember 2017 um 12:19

(Bild: Google)

Google stellt die Entwicklung seiner Augmented-Reality-Umgebung "Tango" für Smartphones wie erwartet ein. Der Support endet am 1. März 2018. Das Nachfolgeprojekt "ARCore" stand bereits fest.

Das Augmented-Reality-Projekt "Tango" ist bald Geschichte: Google hat die Weiterentwicklung eingestellt und wird den Support am 1. März 2018 beenden [1], wie es im Entwicklerblog heißt. Dass Google seine ambitionierte AR-Plattform aufgeben wird [2], hatte sich bereits seit Längerem abgezeichnet. In Gestalt von ARCore [3] steht auch schon ein Nachfolger fest – ein technisch einfacheres System, das offensichtlich besser für den Massenmarkt taugt, da es auf zahlreichen Android-Geräten funktioniert.

Mit ARCore versucht Google, mit Apples ARKit [4] Schritt zu halten, das auf allen aktuellen iPhones funktioniert. Für Tango hingegen sind spezielle Smartphones notwendig. Doch es mangelte offenbar an Hardware-Herstellern, die sich von den Vorzügen dieser speziellen Plattform zum Einblenden virtueller Objekte in die Darstellung der realen Umgebung auf dem Mobilgerät überzeugen ließen.


URL dieses Artikels:
https://www.heise.de/ix/meldung/Google-gibt-AR-Plattform-Tango-auf-3919801.html

Links in diesem Artikel:
  [1] https://plus.google.com/+ProjectTango/posts/SE8SHaDKLmu
  [2] https://www.heise.de/ix/meldung/Googles-Augmented-Reality-Tango-ist-tot-es-lebe-ARCore-3817226.html
  [3] https://developers.google.com/ar/
  [4] https://www.heise.de/ix/meldung/ARKit-Schlaegt-Apple-Google-3771409.html
  [5] mailto:un@ix.de

Let's block ads! (Why?)

✇ iX news ff.org

BlackBerry liefert keine Updates mehr für PRIV

Von heise online — 15. Dezember 2017 um 13:08

zurück zum Artikel

heise online
BlackBerry liefert keine Updates mehr für PRIV

(Bild: Volker Weber )

Die größte Befürchtung der BlackBerry-Kritiker trifft ein. Genau zwei Jahre nach Vorstellung des PRIV beendet BlackBerry die Versorgung mit monatlichen Updates. Alternativen gibt es nicht.

BlackBerry stellt keine Smartphones mehr her. Von den BlackBerry-10-Geräten gibt es noch Restbestände, die ersten drei Android-Geräte PRIV[1], DTEK50[2] und DTEK60[3] sind im Abverkauf. Und nun lässt Alex Thurber die Bombe platzen. Er ist als Senior Vice-President and General Manager für die Mobility Solutions Division bei BlackBerry verantwortlich. Für den PRIV enden die monatlichen Updates[4]. Man kann sich ausrechnen, dass es den beiden anderen Geräten DTEK50 und DTEK60 genauso gehen wird, wenn die 24 Monate erreicht sind.

Als uns Thurber vor 14 Monaten ein Interview[5] gab, klang das alles noch ganz anders: "Wir unterstützen alle Produkte mindestens zwei Jahre über EOL (End of life) hinaus. Und dieser EOL liegt irgendwann in der Zukunft, er ist gar nicht abzusehen." Updates auf Nougat stellte Thurber ebenfalls in Aussicht. "Es läuft bereits in unserem Labor und wir arbeiten eng mit Google an unserer Weiterentwicklung." Auch das ist nicht passiert[6].

Mit dem Auslaufen der Sicherheits-Updates sind die Geräte keineswegs mehr so sicher, wie BlackBerry gerne in Anspruch nimmt. Und Alternativen gibt es nicht, da sich keine andere Firmware auf die Geräte spielen lässt. Das einzige Angebot, dass Thurber in Aussicht stellt, ist ein Upgrade-Programm auf KEYone[7] und Motion[8], die Geräte von TCL-Partner BlackBerry Mobile. Aber auch die haben nichts anderes versprochen als 24 Monate ab Vorstellung und ein Oreo Update nächstes Jahr. (Volker Weber) /


URL dieses Artikels:
http://www.heise.de/-3919087

Links in diesem Artikel:
[1] https://www.heise.de/preisvergleich/blackberry-priv-schwarz-a1341632.html?hocid=newsticker&wt_mc=intern.newsticker.textlink-pvg.pvg_a1341632
[2] https://www.heise.de/preisvergleich/blackberry-dtek50-schwarz-a1482972.html?hocid=newsticker&wt_mc=intern.newsticker.textlink-pvg.pvg_a1482972
[3] https://www.heise.de/preisvergleich/blackberry-dtek60-schwarz-a1517352.html?hocid=newsticker&wt_mc=intern.newsticker.textlink-pvg.pvg_a1517352
[4] http://blogs.blackberry.com/2017/12/status-of-priv-monthly-updates/
[5] https://www.heise.de/meldung/BlackBerry-verspricht-Android-weitere-Updates-3341461.html
[6] https://www.heise.de/meldung/Keine-Upgrades-mehr-fuer-BlackBerry-PRIV-3827231.html
[7] https://www.heise.de/preisvergleich/blackberry-keyone-silber-a1584430.html?hocid=newsticker&wt_mc=intern.newsticker.textlink-pvg.pvg_a1584430
[8] https://www.heise.de/preisvergleich/blackberry-motion-schwarz-a1706993.html?hocid=newsticker&wt_mc=intern.newsticker.textlink-pvg.pvg_a1706993
[9] mailto:vowe@vowe.net

Copyright © 2017 Heise Medien

Let's block ads! (Why?)

✇ iX news ff.org

heise-Angebot: parallel 2018: Programm online – Registrierung eröffnet

Von heise online — 15. Dezember 2017 um 11:46

zurück zum Artikel

parallel 2018: Programm online – Registrierung eröffnet

Mit der Freigabe des Programms der Konferenz zur Parallelprogrammierung wurde auch die Registrierung eröffnet. Mehr als ein Monat besteht nun Zeit, sich inklusive Frühbucherrabatt zu registrieren.

Das Programm der parallel 2018[1] steht nun online. Damit verbunden können sich interessierte Entwickler ab sofort für die Konferenz zur Parallelprogrammierung zum Frühbucherrabattpreis registrieren[2]. Die von heise Developer, iX und dem dpunkt.verlag von 6. bis 8. März 2018 organisierte Veranstaltung findet bereits zum siebten Mal statt – erneut in der Heidelberger Print Media Academy.

In ihrer siebten Auflage knüpft die parallel 2018 programmatisch am Charakter der bisherigen Ausgaben der Konferenz an. Im Programm finden sich verteilt auf zwei Tage über 30 Lang- und Kurzvorträge[3] zu Best Practises bei paralleler Programmierung, dem High-Performance Computing sowie aus dem spannenden Bereich des Deep beziehungsweise Machine Learning, wo sich einige der interessantesten Anwendungsszenarien im Bereich des parallelen Rechnens auftun. Einen Schwerpunkt bilden Vorträge zur Performance paralleler Anwendungen. Abgerundet wird das Programm durch zwei Keynotes.

Best Practices und Workshops

Bis 20. Januar gilt für den Kauf des Konferenztickets noch ein Frühbucherpreis von 790 Euro: Statt des regulären Preises von 930 Euro lassen sich also für die zwei Konferenztage ganze 140 Euro sparen. Weiteren Rabatt gibt es bei der zusätzlichen Buchung eines von fünf Workshops am Vortag der Hauptkonferenz. Bei ihnen geht es um Themen wie die Programmiersprachen C++ und Java, die Wahl der richtigen Technik und Architektur für Projekte zur parallelen Programmierung sowie eine Schulung zur Entwicklung von robusten, nebenläufigen Systemen hoher Parallelität mit Erlang/OTP.

Wer über den weiteren Fortgang der Konferenz auf dem Laufenden gehalten werden möchte, kann sich über einen Newsletter[4] vormerken lassen oder den Veranstaltern auf Twitter[5] folgen.

Die Veranstalter der parallel sind heise Developer, iX und der dpunkt.verlag, die Teil der Heise Gruppe sind.


URL dieses Artikels:
http://www.heise.de/-3918227

Links in diesem Artikel:
[1] https://www.parallelcon.de/index.php
[2] https://www.parallelcon.de/anmeldung.php
[3] https://www.parallelcon.de/programm.php
[4] https://www.parallelcon.de/benachrichtigen.php
[5] https://twitter.com/parallelConf
[6] mailto:map@heise.de

Copyright © 2017 Heise Medien

Let's block ads! (Why?)

✇ iX news ff.org

Root-Lücke in Firewalls von Palo Alto Networks

Von heise online — 15. Dezember 2017 um 11:33

zurück zum Artikel

Root-Lücke in Firewalls von Palo Alto Networks

(Bild: Palo Alto Networks)

Kombinieren Angreifer drei Sicherheitslücken, könnten sie Firewalls von Palo Alto Networks kompromittieren, warnt ein Sicherheitsforscher.

Verschiedene Firewalls mit PAN-OS von Palto Alto Networks sind unter gewissen Umständen angreifbar. Das ist der Fall, wenn Admins das Management Interface so eingestellt haben, dass es aus dem Internet erreichbar ist. Das kommt häufig vor, warnt[1] ein Sicherheitsforscher. Derzeit sind fast 7000 Firewalls öffentlich erreichbar[2].

Angreifer könnten drei Sicherheitslücken zu einem gefährlichen Cocktail kombinieren. So sollen Attacken aus der Ferne ohne Authentifizierung möglich sein, die damit enden, dass Angreifer Code mit Root-Rechten auf betroffenen Firewalls ausführen können.

Die auf den Firewalls laufenden Betriebssystemversionen PAN-OS 6.1.19, 7.0.19, 7.1.14 und 8.0.6-h3 sind abgesichert. Alle vorigen Ausgaben sind bedroht, warnt[3] Palo Alto Networks.

[UPDATE, 15.12.2017 12:00 Uhr]

Weitere PAN-OS-Versionen hinzugefügt.


URL dieses Artikels:
http://www.heise.de/-3918909

Links in diesem Artikel:
[1] http://seclists.org/fulldisclosure/2017/Dec/38
[2] https://www.shodan.io/report/mPWsUHOS
[3] https://securityadvisories.paloaltonetworks.com/Home/Detail/102?AspxAutoDetectCookieSupport=1
[4] mailto:des@heise.de

Copyright © 2017 Heise Medien

Let's block ads! (Why?)

❌