Benutzerdefinierte Plug-ins entwickeln

Sie sehen die Dokumentation zu Apigee Edge.
Zur Apigee X-Dokumentation
weitere Informationen

Edge Microgateway Version 3.3.x

Zielgruppe

Dieses Thema richtet sich an Entwickler, die Edge Microgateway-Features durch das Schreiben benutzerdefinierter Plug-ins erweitern möchten. Wenn Sie ein neues Plug-in schreiben möchten, sind Erfahrung mit JavaScript und Node.js erforderlich.

Was ist ein benutzerdefiniertes Edge Microgateway-Plug-in?

Ein Plug-in ist ein Node.js-Modul, das Edge Microgateway Funktionen hinzufügt. Plug-in-Module folgen einem einheitlichen Muster und werden an einem Ort gespeichert, der Edge Microgateway bekannt ist, damit sie automatisch erkannt und ausgeführt werden können. Beim Installieren von Edge Microgateway werden mehrere vordefinierte Plug-ins bereitgestellt. Dazu gehören Plug-ins für Authentifizierung, Spike Arrest, Kontingente und Analysen. Eine Beschreibung dieser vorhandenen Plug-ins finden Sie unter Plug-ins verwenden.

Sie können dem Microgateway neue Features und Funktionen hinzufügen, indem Sie benutzerdefinierte Plug-ins schreiben. Standardmäßig ist Edge Microgateway im Wesentlichen ein sicherer Passthrough-Proxy, der Anfragen und Antworten unverändert an Zieldienste weitergibt und von diesen weitergibt. Mit benutzerdefinierten Plug-ins können Sie programmatisch mit den Anfragen und Antworten interagieren, die über das Mikrogateway gesendet werden.

Benutzerdefinierten Plug-in-Code einfügen

Ein Ordner für benutzerdefinierte Plug-ins ist hier Teil der Edge Microgateway-Installation:

[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins

Dabei ist [prefix] das Präfixverzeichnis npm, wie unter Edge Microgateway installieren unter „Wo ist Edge Microgateway installiert?“ beschrieben.

Sie können dieses Standardverzeichnis des Plug-ins ändern. Siehe Plug-ins finden.

Vordefinierte Plug-ins überprüfen

Bevor Sie versuchen, ein eigenes Plug-in zu entwickeln, sollten Sie prüfen, ob keines der vordefinierten Plug-ins Ihren Anforderungen entspricht. Diese Plug-ins befinden sich in:

[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins

Dabei ist [prefix] das Präfixverzeichnis npm. Weitere Informationen finden Sie unter Edge Microgateway installieren unter „Wo ist Edge Microgateway installiert?“

Weitere Informationen finden Sie unter Mit Edge Microgateway bereitgestellte vordefinierte Plug-ins.

Einfaches Plug-in schreiben

In diesem Abschnitt werden die Schritte zum Erstellen eines einfachen Plug-ins beschrieben. Dieses Plug-in überschreibt die Antwortdaten (was auch immer sie sind) mit dem String „Hello, World!“ und gibt sie im Terminal aus.

  1. Wenn Edge Microgateway ausgeführt wird, beenden Sie es jetzt:
    edgemicro stop
    
  2. cd in das benutzerdefinierte Plug-in-Verzeichnis:

    cd [prefix]/lib/node_modules/edgemicro/plugins

    Dabei ist [prefix] das Präfixverzeichnis npm, wie unter Edge Microgateway installieren unter „Wo ist Edge Microgateway installiert?“ beschrieben.

  3. Erstellen Sie ein neues Plug-in-Projekt mit dem Namen response-override und cd dafür:
    mkdir response-override && cd response-override
    
  4. Erstellen Sie ein neues Node.js-Projekt:
    npm init
    
    Drücken Sie mehrmals die Eingabetaste, um die Standardwerte zu übernehmen.
  5. Erstellen Sie mit einem Texteditor eine neue Datei mit dem Namen index.js.
  6. Kopieren Sie den folgenden Code in index.js und speichern Sie die Datei.
    'use strict';
    var debug = require('debug')
    
    module.exports.init = function(config, logger, stats) {
    
      return {
       
        ondata_response: function(req, res, data, next) {
          debug('***** plugin ondata_response');
          next(null, null);
        },
        
        onend_response: function(req, res, data, next) {
          debug('***** plugin onend_response');
          next(null, "Hello, World!\n\n");
        }
      };
    }
    
  7. Jetzt haben Sie ein Plug-in erstellt und müssen es der Edge Microgateway-Konfiguration hinzufügen. Öffnen Sie die Datei $HOME/.edgemicro/[org]-[env]-config.yaml, wobei org und env Ihre Edge-Organisations- und Umgebungsnamen sind.
  8. Fügen Sie dem plugins:sequence-Element das response-override-Plug-in hinzu, wie unten gezeigt.
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
    
  9. Starten Sie Edge Microgateway neu.
  10. Rufen Sie eine API über Edge Microgateway auf. Bei diesem API-Aufruf wird davon ausgegangen, dass Sie die gleiche Konfiguration wie in der Anleitung mit API-Schlüsselsicherheit eingerichtet haben, wie unter Edge Microgateway einrichten und konfigurieren beschrieben:
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!
    

Aufbau eines Plug-ins

Das folgende Beispiel-Plug-in für Edge Microgateway veranschaulicht das Muster, das beim Entwickeln eigener Plug-ins zu befolgen ist. Der Quellcode für das in diesem Abschnitt beschriebene Beispiel-Plug-in befindet sich in der Datei plugins/header-uppercase/index.js..

  • Plug-ins sind Standard-NPM-Module mit einem package.json und index.js im Stammordner.
  • Ein Plug-in muss eine init()-Funktion exportieren.
  • Die Funktion init() verwendet drei Argumente: config, logger und stats. Diese Argumente werden in den Argumenten der Plug-in-Funktion init() beschrieben.
  • init() gibt ein Objekt mit benannten Funktions-Handlern zurück, die bei bestimmten Ereignissen während der Lebensdauer einer Anfrage aufgerufen werden.

Event-Handler-Funktionen

Ein Plug-in muss einige oder alle dieser Ereignis-Handler-Funktionen implementieren. Die Implementierung dieser Funktionen liegt bei Ihnen. Jede Funktion ist optional und ein typisches Plug-in implementiert mindestens einen Teil dieser Funktionen.

Anfragefluss-Ereignis-Handler

Diese Funktionen werden bei Anfrageereignissen in Edge Microgateway aufgerufen.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

onrequest-Funktion

Wird zu Beginn der Clientanfrage aufgerufen. Diese Funktion wird ausgelöst, wenn das erste Byte der Anfrage von Edge Microgateway empfangen wird. Mit dieser Funktion erhalten Sie Zugriff auf die Anfrageheader, die URL, die Abfrageparameter und die HTTP-Methode. Wenn Sie als Nächstes mit einem wahrheitsgemäßen ersten Argument aufrufen (z. B. eine Fehlerinstanz), wird die Anfrageverarbeitung beendet und keine Zielanfrage initiiert.

Beispiel:

onrequest: function(req, res, next) {
      debug('plugin onrequest');
      req.headers['x-foo-request-start'] = Date.now();
      next();
    }

ondata_request-Funktion

Wird aufgerufen, wenn ein Datenblock vom Client empfangen wird. Übergibt Anfragedaten an das nächste Plug-in in der Plug-in-Sequenz. Der vom letzten Plug-in in der Sequenz zurückgegebene Wert wird an das Ziel gesendet. Ein typischer Anwendungsfall (siehe unten) ist die Transformation der Anfragedaten, bevor sie an das Ziel gesendet werden.

Beispiel:

ondata_request: function(req, res, data, next) {
      debug('plugin ondata_request ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    }

onend_request-Funktion

Wird aufgerufen, wenn alle Anfragedaten vom Client empfangen wurden.

Beispiel:

onend_request: function(req, res, data, next) {
      debug('plugin onend_request');
      next(null, data);
    }

onclose_request-Function

Gibt an, dass die Clientverbindung beendet wurde. Sie können diese Funktion in Fällen verwenden, in denen die Clientverbindung unzuverlässig ist. Sie wird aufgerufen, wenn die Socket-Verbindung zum Client geschlossen wird.

Beispiel:

onclose_request: function(req, res, next) {
      debug('plugin onclose_request');
      next();
    }

onerror_request-Function

Wird aufgerufen, wenn beim Empfang der Clientanfrage ein Fehler auftritt.

Beispiel:

onerror_request: function(req, res, err, next) {
      debug('plugin onerror_request ' + err);
      next();
    }

Event-Handler für Antwortfluss

Diese Funktionen werden bei Antwortereignissen in Edge Microgateway aufgerufen.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

onresponse-Function

Wird zu Beginn der Zielantwort aufgerufen. Diese Funktion wird ausgelöst, wenn das erste Byte der Antwort von Edge Microgateway empfangen wird. Mit dieser Funktion erhalten Sie Zugriff auf die Antwortheader und den Statuscode.

Beispiel:

onresponse: function(req, res, next) {      
    debug('plugin onresponse');     
    res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start'])    
    next();    
}


ondata_response-Funktion

Wird aufgerufen, wenn ein Datenblock vom Ziel empfangen wird.

Beispiel:

ondata_response: function(req, res, data, next) {
      debug('plugin ondata_response ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    }


onend_response-Funktion

Wird aufgerufen, wenn alle Antwortdaten vom Ziel empfangen wurden.

Beispiel:

onend_response: function(req, res, data, next) {
      debug('plugin onend_response');
      next(null, data);
    }

onclose_response-Function

Gibt an, dass die Zielverbindung geschlossen wurde. Sie können diese Funktion verwenden, wenn die Zielverbindung unzuverlässig ist. Sie wird aufgerufen, wenn die Socket-Verbindung zum Ziel geschlossen wird.

Beispiel:

onclose_response: function(req, res, next) {
      debug('plugin onclose_response');
      next();
    }


onerror_response-Funktion

Wird aufgerufen, wenn beim Empfang der Zielantwort ein Fehler auftritt.

Beispiel:

onerror_response: function(req, res, err, next) {
      debug('plugin onerror_response ' + err);
      next();
    }

Wissenswertes zu den Plug-in-Event-Handler-Funktionen

Plug-in-Event-Handler-Funktionen werden als Reaktion auf bestimmte Ereignisse aufgerufen, die auftreten, während Edge Microgateway eine bestimmte API-Anfrage verarbeitet.

  • Jeder der init()-Funktions-Handler (ondata_request, ondata_response usw.) muss nach der Verarbeitung den next()-Callback aufrufen. Wenn Sie next() nicht aufrufen, wird die Verarbeitung beendet und die Anfrage bleibt hängen.
  • Das erste Argument für next() kann ein Fehler sein, der dazu führt, dass die Anfrageverarbeitung beendet wird.
  • Die Handler ondata_ und onend_ müssen next() mit einem zweiten Argument aufrufen, das die Daten enthält, die an das Ziel oder den Client übergeben werden sollen. Dieses Argument kann null sein, wenn das Plug-in eine Zwischenspeicherung durchführt und derzeit nicht genügend Daten für die Transformation hat.
  • Beachten Sie, dass eine einzelne Instanz des Plug-ins verwendet wird, um alle Anfragen und Antworten zu verarbeiten. Wenn ein Plug-in den Status pro Anfrage zwischen Aufrufen beibehalten möchte, kann es diesen Status in einem Attribut speichern, das dem bereitgestellten request-Objekt (req) hinzugefügt wird. Seine Lebensdauer ist die Dauer des API-Aufrufs.
  • Achten Sie darauf, alle Fehler abzufangen und next() mit dem Fehler aufzurufen. Wenn next() nicht aufgerufen wird, wird der API-Aufruf angehalten.
  • Achten Sie darauf, keine Speicherlecks einzuführen, da diese die Gesamtleistung von Edge Microgateway beeinträchtigen und zum Absturz führen können, wenn nicht mehr genügend Arbeitsspeicher vorhanden ist.
  • Folgen Sie dem Node.js-Modell, indem Sie keine rechenintensiven Aufgaben im Hauptthread ausführen, da dies die Leistung von Edge Microgateway beeinträchtigen kann.

Informationen zur Plug-in-Funktion init()

In diesem Abschnitt werden die Argumente beschrieben, die an die Funktion init() übergeben werden: config, logger und stats.

config

Konfigurationsdaten, die durch Zusammenführen der Edge Microgateway-Konfigurationsdatei mit den von Apigee Edge heruntergeladenen Daten abgerufen werden, werden in einem Objekt mit dem Namen config abgelegt.

Um dem Plug-in response-override einen Konfigurationsparameter namens param mit dem Wert foo hinzuzufügen, fügen Sie Folgendes in die Datei default.yaml ein:

response-override:
    param: foo

Anschließend können Sie wie folgt in Ihrem Plug-in-Code auf den Parameter zugreifen:

// Called when response data is received
    ondata_response: function(req, res, data, next) {
      debug('***** plugin ondata_response');
      debug('***** plugin ondata_response: config.param: ' + config.param);
      next(null, data);
    },

In diesem Fall wird in der Debug-Ausgabe des Plug-ins „foo“ angezeigt:

Sun, 13 Dec 2015 21:25:08 GMT plugin:response-override ***** plugin ondata_response: config.param: foo

Sie können auf die zusammengeführte Mikrogateway-Konfiguration und heruntergeladene Apigee Edge-Daten im untergeordneten Objekt config.emgConfigs zugreifen. So können Sie beispielsweise in der Funktion init auf diese Konfigurationsdaten zugreifen:

module.exports.init = function(config, logger, stats) {
   let emgconfigs = config.emgConfigs;

Im Folgenden finden Sie ein Beispiel für Daten, die emgConfigs enthalten:

{
    edgemicro:
    {
        port: 8000,
        max_connections: 1000,
        config_change_poll_interval: 600,
        logging:
        {
            level: 'error',
            dir: '/var/tmp',
            stats_log_interval: 60,
            rotate_interval: 24,
            stack_trace: false
        },
        plugins: { sequence: [Array] },
        global: { org: 'Your Org', env: 'test' }
    },
    headers:
    {
        'x-forwarded-for': true,
        'x-forwarded-host': true,
        'x-request-id': true,
        'x-response-time': true,
        via: true
    },
    proxies:
    [    {
                max_connections: 1000,
                name: 'edgemicro_delayed',
                revision: '1',
                proxy_name: 'default',
                base_path: '/edgemicro_delayed',
                target_name: 'default',
                url: 'https://httpbin.org/delay/10',
                timeout: 0
            }
    ],
    product_to_proxy: { EdgeMicroTestProduct: [ 'edgemicro-auth','edgemicro_delayed',] },
    product_to_scopes: {prod4: [ 'Admin', 'Guest', 'Student' ] },
    product_to_api_resource: { EdgeMicroTestProduct: [ '/*' ] },
    _hash: 0,
    keys: { key: 'Your key', secret: 'Your key ' },
    uid: 'Internally generated uuid',
    targets: []
  }

logger

Der Systemprotokollierung. Der aktuell verwendete Logger exportiert diese Funktionen, wobei das Objekt ein String, eine HTTP-Anfrage, eine HTTP-Antwort oder eine Fehlerinstanz sein kann.

  • info(object, message)
  • warn(object, message)
  • error(object, message)
  • trace(object, message)
  • debug(object, message)

stats

Ein Objekt, das die Anzahl von Anfragen, Antworten, Fehlern und andere aggregierte Statistiken in Bezug auf die Anfragen und Antworten enthält, die durch eine Mikrogateway-Instanz gesendet werden.

  • treqErrors – Die Anzahl der Zielanfragen mit Fehlern.
  • treqErrors – Die Anzahl der Zielantworten mit Fehlern.
  • statusCodes – Ein Objekt, das die Anzahl der Antwortcodes enthält:
{
  1: number of target responses with 1xx response codes
  2: number of target responses with 2xx response codes
  3: number of target responses with 3xx response codes
  4: number of target responses with 4xx response codes
  5: number of target responses with 5xx response codes
  }
  
  • requests – Die Gesamtzahl der Anfragen.
  • responses – Die Gesamtzahl der Antworten.
  • connections – Die Anzahl der aktiven Zielverbindungen.

Über die Funktion next()

Alle Plug-in-Methoden müssen next() aufrufen, um die nächste Methode in der Serie weiter zu verarbeiten (sonst der Plug-in-Prozess hängt). Im Anfragelebenszyklus ist die erste Methode "onrequest()" aufgerufen. Als Nächstes wird die Methode ondata_request() aufgerufen. ondata_request wird jedoch nur aufgerufen, wenn die Anfrage Daten enthält, wie es beispielsweise bei einer POST-Anfrage der Fall ist. Die nächste aufgerufene Methode ist onend_request(), die nach Abschluss der Anfrageverarbeitung aufgerufen wird. Die onerror_*-Funktionen werden nur im Fehlerfall aufgerufen und ermöglichen es Ihnen, die Fehler mit benutzerdefiniertem Code zu verarbeiten, wenn Sie möchten.

Angenommen, in der Anfrage werden Daten gesendet und ondata_request() wird aufgerufen. Die Funktion ruft next() mit zwei Parametern auf:

next(null, data);

Konventionsgemäß wird der erste Parameter verwendet, um Fehlerinformationen zu vermitteln, die Sie dann in einer nachfolgenden Funktion in der Kette verarbeiten können. Wenn Sie es auf null (ein falsches Argument) setzen, geben Sie an, dass keine Fehler vorliegen und die Verarbeitung der Anfrage normal fortgesetzt werden sollte. Wenn dieses Argument wahrheitsgemäß ist (z. B. ein Fehlerobjekt), wird die Verarbeitung der Anfrage beendet und die Anfrage an das Ziel gesendet.

Der zweite Parameter übergibt die Anfragedaten an die nächste Funktion in der Kette. Wenn Sie keine weitere Verarbeitung vornehmen, werden die Anfragedaten unverändert an das Ziel der API übergeben. Sie haben jedoch die Möglichkeit, die Anfragedaten innerhalb dieser Methode zu ändern und die geänderte Anfrage an das Ziel zu übergeben. Wenn die Anfragedaten beispielsweise XML sind und das Ziel JSON erwartet, können Sie der Methode ondata_request() Code hinzufügen, der (a) den Inhaltstyp des Anfrageheaders in application/json ändert und die Anfragedaten auf beliebige Weise in JSON konvertiert. Sie können beispielsweise einen Node.js-Konverter für xml2json verwenden, der von NPM abgerufen wird.

So könnte das aussehen:

ondata_request: function(req, res, data, next) {
  debug('****** plugin ondata_request');
  var translated_data = parser.toJson(data);
  next(null, translated_data);
},

In diesem Fall werden die Anfragedaten (bei denen davon ausgegangen wird, dass es sich um XML handelt) in JSON konvertiert und die transformierten Daten über next() an die nächste Funktion in der Anfragekette übergeben, bevor sie an das Back-End-Ziel übergeben werden.

Sie können eine weitere Debug-Anweisung hinzufügen, um die transformierten Daten zu Fehlerbehebungszwecken auszugeben. Beispiel:

ondata_request: function(req, res, data, next) {
  debug('****** plugin ondata_request');
  var translated_data = parser.toJson(data);
  debug('****** plugin ondata_response: translated_json: ' + translated_json);
  next(null, translated_data);
},

Ausführungsreihenfolge für Plug-in-Handler

Wenn Sie Plug-ins für Edge Microgateway schreiben, müssen Sie wissen, in welcher Reihenfolge Plug-in-Event-Handler ausgeführt werden.

Wichtig: Wenn Sie eine Plug-in-Sequenz in der Edge Microgateway-Konfigurationsdatei angeben, werden die Anfrage-Handler in aufsteigender Reihenfolge und die Antwort-Handler in absteigender Reihenfolge ausgeführt.

Das folgende Beispiel soll Ihnen das Verständnis dieser Ausführungssequenz verdeutlichen.

1. Drei einfache Plug-ins erstellen

Betrachten Sie das folgende Plug-in. Wenn die zugehörigen Event-Handler aufgerufen werden, wird lediglich die Konsolenausgabe ausgegeben:

plugins/plugin-1/index.js

module.exports.init = function(config, logger, stats) {

  return {

    onrequest: function(req, res, next) {
      console.log('plugin-1: onrequest');
      next();
    },

    onend_request: function(req, res, data, next) {
      console.log('plugin-1: onend_request');
      next(null, data);
    },

    ondata_response: function(req, res, data, next) {
      console.log('plugin-1: ondata_response ' + data.length);
      next(null, data);
    },

    onend_response: function(req, res, data, next) {
      console.log('plugin-1: onend_response');
      next(null, data);
    }
  };
}

Erwägen Sie nun, zwei weitere Plug-ins, plugin-2 und plugin-3, mit demselben Code zu erstellen (außer, Sie ändern die console.log()-Anweisungen entsprechend in plugin-2 und plugin-3).

2. Plug-in-Code überprüfen

Die exportierten Plug-in-Funktionen in <microgateway-root-dir>/plugins/plugin-1/index.js sind Event-Handler, die zu bestimmten Zeiten während der Verarbeitung von Anfragen und Antworten ausgeführt werden. Beispielsweise führt onrequest das erste Byte der empfangenen Anfrageheader aus. Währenddessen wird onend_response ausgeführt, nachdem das letzte Byte der Antwortdaten empfangen wurde.

Sehen Sie sich den Handler ondata_response an. Er wird jedes Mal aufgerufen, wenn ein Block von Antwortdaten empfangen wird. Wichtig ist zu wissen, dass die Antwortdaten nicht unbedingt alle auf einmal empfangen werden. Vielmehr können die Daten in Blöcken beliebiger Länge empfangen werden.

3. Plug-ins in die Plug-in-Sequenz aufnehmen

In diesem Beispiel fügen wir die Plug-ins der Plug-in-Sequenz in der Edge Microgateway-Konfigurationsdatei (~./edgemicro/config.yaml) wie folgt hinzu. Die Reihenfolge ist wichtig. Sie definiert die Reihenfolge, in der die Plug-in-Handler ausgeführt werden.

  plugins:
    dir: ../plugins
    sequence:
      - plugin-1
      - plugin-2
      - plugin-3
  

4. Debug-Ausgabe untersuchen

Sehen wir uns nun die Ausgabe an, die beim Aufruf dieser Plug-ins erzeugt wird. Hier sind einige wichtige Punkte:

  • Die Plug-in-Sequenz, in der die Edge Microgateway-Konfigurationsdatei (~./edgemicro/config.yaml) verwendet wird, gibt die Reihenfolge an, in der Event-Handler aufgerufen werden.
  • Anfrage-Handler werden in aufsteigender Reihenfolge aufgerufen, also in der Reihenfolge, in der sie in der Plug-in-Sequenz angezeigt werden: 1, 2, 3.
  • Antwort-Handler werden in absteigender Reihenfolge aufgerufen: 3, 2, 1.
  • Der Handler ondata_response wird für jeden ankommenden Datenblock einmal aufgerufen. In diesem Beispiel (Ausgabe unten) werden zwei Blöcke empfangen.

Hier sehen Sie eine Beispielausgabe zur Fehlerbehebung, die erzeugt wird, wenn diese drei Plug-ins verwendet werden und eine Anfrage über Edge Microgateway gesendet wird. Beachten Sie die Reihenfolge, in der die Handler aufgerufen werden:

  plugin-1: onrequest
  plugin-2: onrequest
  plugin-3: onrequest

  plugin-1: onend_request
  plugin-2: onend_request
  plugin-3: onend_request

  plugin-3: ondata_response 931
  plugin-2: ondata_response 931
  plugin-1: ondata_response 931

  plugin-3: ondata_response 1808
  plugin-3: onend_response

  plugin-2: ondata_response 1808
  plugin-2: onend_response

  plugin-1: ondata_response 1808
  plugin-1: onend_response

Zusammenfassung

Wenn Sie benutzerdefinierte Plug-in-Funktionen wie das Sammeln und Transformieren von Anfrage- oder Antwortdaten implementieren möchten, ist es sehr wichtig zu wissen, in welcher Reihenfolge Plug-in-Handler aufgerufen werden.

Denken Sie daran, dass Anfrage-Handler in der Reihenfolge ausgeführt werden, in der die Plug-ins in der Edge Microgateway-Konfigurationsdatei angegeben sind. Antwort-Handler werden in entgegengesetzter Reihenfolge ausgeführt.

Globale Variablen in Plug-ins verwenden

Jede Anfrage an Edge Microgateway wird an dieselbe Instanz eines Plug-ins gesendet. Daher überschreibt der Status einer zweiten Anfrage von einem anderen Client die erste. Der einzige sichere Ort zum Speichern des Plug-in-Status ist das Speichern des Status in einer Property des Anfrage- oder Antwortobjekts, dessen Lebensdauer auf diejenige der Anfrage beschränkt ist.

Ziel-URLs in Plug-ins neu schreiben

Hinzugefügt in: Version 2.3.3

Sie können die Standard-Ziel-URL in einem Plug-in dynamisch überschreiben, indem Sie die folgenden Variablen in Ihrem Plug-in-Code ändern: req.targetHostname und req.targetPath.

Hinzugefügt in: Version 2.4.x

Sie können auch den Port des Zielendpunkts überschreiben und zwischen HTTP und HTTPS auswählen. Ändern Sie die Variablen req.targetPort und req.targetSecure in Ihrem Plug-in-Code. Wenn Sie HTTPS auswählen möchten, setzen Sie req.targetSecure auf true und für HTTP false. Wenn Sie „req.targetSecure“ auf „true“ setzen, finden Sie in diesem Diskussionsthread weitere Informationen.

Ein Beispiel-Plug-in namens eurekaclient wurde Edge Microgateway hinzugefügt. Dieses Plug-in veranschaulicht, wie die Variablen „req.targetPort“ und „req.targetSecure“ verwendet werden und wie Edge Microgateway eine dynamische Endpunktsuche mit Eureka als Dienstendpunktkatalog ausführen kann.


Beispiel-Plug-ins

Diese Plug-ins werden mit Ihrer Edge Microgateway-Installation bereitgestellt. Sie finden sie hier in der Edge Microgateway-Installation:

[prefix]/lib/node_modules/edgemicro/plugins

Dabei ist [prefix] das Präfixverzeichnis npm, wie unter Edge Microgateway installieren unter „Wo ist Edge Microgateway installiert?“ beschrieben.

Anfrage akkumulieren

Dieses Plug-in sammelt Datenblöcke vom Client in einem Array-Attribut, das an das Anfrageobjekt angehängt ist. Wenn alle Anfragedaten empfangen werden, wird das Array zu einem Zwischenspeicher verkettet, der dann an das nächste Plug-in in der Sequenz übergeben wird. Dieses Plug-in sollte das erste Plug-in in der Sequenz sein, damit nachfolgende Plug-ins die akkumulierten Anfragedaten erhalten.

module.exports.init = function(config, logger, stats) {

  function accumulate(req, data) {

    if (!req._chunks) req._chunks = [];
    req._chunks.push(data);

  }

  return {

    ondata_request: function(req, res, data, next) {

      if (data && data.length > 0) accumulate(req, data);

      next(null, null);

    },


    onend_request: function(req, res, data, next) {

      if (data && data.length > 0) accumulate(req, data);

      var content = null;

      if (req._chunks && req._chunks.length) {

        content = Buffer.concat(req._chunks);

      }

      delete req._chunks;

      next(null, content);

    }

  };

}

Akkumulationsantwort

Dieses Plug-in sammelt Datenblöcke vom Ziel in ein Array-Attribut, das an das Antwortobjekt angehängt ist. Wenn alle Antwortdaten empfangen werden, wird das Array zu einem Zwischenspeicher verkettet, der dann an das nächste Plug-in in der Sequenz übergeben wird. Da dieses Plug-in mit Antworten arbeitet, die in umgekehrter Reihenfolge verarbeitet werden, sollten Sie es als letztes Plug-in in der Sequenz positionieren.

module.exports.init = function(config, logger, stats) {

  function accumulate(res, data) {
    if (!res._chunks) res._chunks = [];
    res._chunks.push(data);
  }

  return {

    ondata_response: function(req, res, data, next) {
      if (data && data.length > 0) accumulate(res, data);
      next(null, null);
    },

    onend_response: function(req, res, data, next) {
      if (data && data.length > 0) accumulate(res, data);
      var content = Buffer.concat(res._chunks);
      delete res._chunks;
      next(null, content);
    }

  };

}

Plug-in für Header in Großbuchstaben

Edge Microgateway-Distributionen enthalten ein Beispiel-Plug-in namens <microgateway-root-dir>/plugins/header-uppercase. Das Beispiel enthält Kommentare, die jeden der Funktions-Handler beschreiben. In diesem Beispiel wird eine einfache Datentransformation der Zielantwort durchgeführt und der Clientanfrage und der Zielantwort benutzerdefinierte Header hinzugefügt.

Hier ist der Quellcode für <microgateway-root-dir>/plugins/header-uppercase/index.js:

'use strict';

var debug = require('debug')('plugin:header-uppercase');

// required
module.exports.init = function(config, logger, stats) {

  var counter = 0;

  return {

    // indicates start of client request
    // request headers, url, query params, method should be available at this time
    // request processing stops (and a target request is not initiated) if
    // next is called with a truthy first argument (an instance of Error, for example)
    onrequest: function(req, res, next) {
      debug('plugin onrequest');
      req.headers['x-foo-request-id'] = counter++;
      req.headers['x-foo-request-start'] = Date.now();
      next();
    },

    // indicates start of target response
    // response headers and status code should be available at this time
    onresponse: function(req, res, next) {
      debug('plugin onresponse');
      res.setHeader('x-foo-response-id', req.headers['x-foo-request-id']);
      res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start']);
      next();
    },

    // chunk of request body data received from client
    // should return (potentially) transformed data for next plugin in chain
    // the returned value from the last plugin in the chain is written to the target
    ondata_request: function(req, res, data, next) {
      debug('plugin ondata_request ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    },

    // chunk of response body data received from target
    // should return (potentially) transformed data for next plugin in chain
    // the returned value from the last plugin in the chain is written to the client
    ondata_response: function(req, res, data, next) {
      debug('plugin ondata_response ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    },

    // indicates end of client request
    onend_request: function(req, res, data, next) {
      debug('plugin onend_request');
      next(null, data);
    },

    // indicates end of target response
    onend_response: function(req, res, data, next) {
      debug('plugin onend_response');
      next(null, data);
    },

    // error receiving client request
    onerror_request: function(req, res, err, next) {
      debug('plugin onerror_request ' + err);
      next();
    },

    // error receiving target response
    onerror_response: function(req, res, err, next) {
      debug('plugin onerror_response ' + err);
      next();
    },

    // indicates client connection closed
    onclose_request: function(req, res, next) {
      debug('plugin onclose_request');
      next();
    },

    // indicates target connection closed
    onclose_response: function(req, res, next) {
      debug('plugin onclose_response');
      next();
    }

  };

}


Umwandlung in Großbuchstaben

Dies ist ein allgemeines Transformations-Plug-in, das Sie für beliebige Arten von Transformationen ändern können. In diesem Beispiel werden die Antwort- und Anfragedaten einfach in Großbuchstaben umgewandelt.

 */
module.exports.init = function(config, logger, stats) {

  // perform content transformation here
  // the result of the transformation must be another Buffer
  function transform(data) {
    return new Buffer(data.toString().toUpperCase());
  }

  return {

    ondata_response: function(req, res, data, next) {
      // transform each chunk as it is received
      next(null, data ? transform(data) : null);
    },

    onend_response: function(req, res, data, next) {
      // transform accumulated data, if any
      next(null, data ? transform(data) : null);
    },

    ondata_request: function(req, res, data, next) {
      // transform each chunk as it is received
      next(null, data ? transform(data) : null);
    },

    onend_request: function(req, res, data, next) {
      // transform accumulated data, if any
      next(null, data ? transform(data) : null);
    }

  };

}