Benutzerdefinierte Plug-ins entwickeln

Sie sehen die Apigee Edge-Dokumentation.
Rufen Sie die Apigee X-Dokumentation auf.
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, müssen Sie mit JavaScript und Node.js vertraut sein.

Was ist ein benutzerdefiniertes Edge Microgateway-Plug-in?

Ein Plug-in ist ein Node.js-Modul, das Edge Microgateway-Funktionen erweitert. 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. Wenn Sie Edge Microgateway installieren, 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 Mikrogateway 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 und von Zieldiensten weiterleitet. Mit benutzerdefinierten Plug-ins können Sie programmatisch mit den Anfragen und Antworten interagieren, die durch 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 Standard-Plug-in-Verzeichnis ändern. Weitere Informationen finden Sie unter 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. Sie finden diese Plug-ins hier:

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

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

Weitere Informationen finden Sie unter Vordefinierte Plug-ins für Edge Microgateway.

Einfaches Plug-in schreiben

In diesem Abschnitt werden die Schritte zum Erstellen eines einfachen Plug-ins beschrieben. Dieses Plug-in überschreibt die Antwortdaten (je nachdem, welche Art von Daten 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 zum benutzerdefinierten 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:
    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 Plug-in response-override 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 bei der Entwicklung eigener Plug-ins zu befolgen ist. Der Quellcode für das in diesem Abschnitt beschriebene Beispiel-Plug-in befindet sich im 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 aufgerufen werden, wenn bestimmte Ereignisse während der Lebensdauer einer Anfrage auftreten.

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.

Ablaufereignis-Handler anfordern

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. einer 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) besteht darin, die Anfragedaten vor dem Senden an das Ziel zu transformieren.

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-Funktion

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 beendet wird.

Beispiel:

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

onerror_request-Funktion

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-Funktion

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-Funktion

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

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() ist möglicherweise ein Fehler, 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 zwischengespeichert wird und derzeit nicht genügend Daten zur Transformation vorhanden sind.
  • Für alle Anfragen und Antworten wird eine einzelne Instanz des Plug-ins verwendet. Wenn ein Plug-in den Anfragestatus 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, bleibt der API-Aufruf hängen.
  • Achten Sie darauf, dass keine Speicherlecks entstehen, da diese die Gesamtleistung von Edge Microgateway beeinträchtigen und zum Absturz führen können, wenn nicht genügend Arbeitsspeicher vorhanden ist.
  • Folgen Sie dem Node.js-Modell und führen Sie keine rechenintensiven Aufgaben im Hauptthread aus, da dies die Leistung von Edge Microgateway beeinträchtigen kann.

Über die 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 einem Plug-in namens 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 im 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“ ausgegeben:

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

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

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

Unten siehst du 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 Systemprotokollierungs-Tool. 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 der Anfragen, Antworten, Fehler 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 – 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. Andernfalls bleibt der Plug-in-Prozess hängen. Im Lebenszyklus der Anfrage wird onrequest() zuerst aufgerufen. Als Nächstes wird die Methode ondata_request() aufgerufen. ondata_request wird jedoch nur dann aufgerufen, wenn die Anfrage Daten enthält, wie z. B. bei einer POST-Anfrage. Die nächste aufgerufene Methode ist onend_request(), die aufgerufen wird, wenn die Anfrageverarbeitung abgeschlossen ist. Die onerror_*-Funktionen werden nur im Fehlerfall aufgerufen. Sie können die Fehler bei Bedarf mit benutzerdefiniertem Code verarbeiten.

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 zur Übermittlung von Fehlerinformationen verwendet, die Sie dann in einer nachfolgenden Funktion in der Kette verarbeiten können. Wenn Sie es auf null, ein falsches Argument, setzen, sagen wir, dass keine Fehler vorliegen und die Anfrageverarbeitung normal fortgesetzt werden sollte. Wenn dieses Argument wahrheitsgemäß ist (z. B. bei einem Fehlerobjekt), wird die Verarbeitung der Anfrage beendet und die Anfrage an das Ziel gesendet.

Der zweite Parameter übergibt die Anforderungsdaten an die nächste Funktion in der Kette. Wenn Sie keine weitere Verarbeitung ausführen, 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 mit einem beliebigen Zweck in JSON konvertiert. Sie können beispielsweise einen Node.js-Konverter 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 (wobei angenommen 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 von Plug-in-Handlern

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

Sie sollten unbedingt daran denken, dass beim Angeben einer Plug-in-Sequenz in der Edge Microgateway-Konfigurationsdatei die Anfrage-Handler in aufsteigender Reihenfolge ausgeführt werden, während die Antwort-Handler in absteigender Reihenfolge ausgeführt werden.

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

1. Drei einfache Plug-ins erstellen

Sehen Sie sich das folgende Plug-in an. Sie gibt lediglich die Konsolenausgabe aus, wenn ihre Event-Handler aufgerufen werden:

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 Ändern Sie die console.log()-Anweisungen entsprechend zu 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. Allerdings wird onend_response ausgeführt, nachdem das letzte Byte an Antwortdaten empfangen wurde.

Sehen Sie sich den Handler „ondata_response“ an. Er wird immer dann aufgerufen, wenn ein Teil von Antwortdaten empfangen wird. Wichtig ist, dass die Antwortdaten nicht unbedingt auf einmal empfangen werden. Vielmehr können die Daten in Blöcken beliebiger Länge empfangen werden.

3. Plug-ins der Plug-in-Sequenz hinzufügen

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 zu beachten:

  • Die Plug-in-Sequenz der Edge Microgateway-Konfigurationsdatei (~./edgemicro/config.yaml) gibt die Reihenfolge an, in der Event-Handler aufgerufen werden.
  • Anfrage-Handler werden in aufsteigender Reihenfolge (in der Reihenfolge, in der sie in der Plug-in-Sequenz angezeigt werden) aufgerufen: 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 ist ein Beispiel für eine Debug-Ausgabe, die erstellt wird, wenn diese drei Plug-ins verwendet 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 umgekehrter 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 einem Attribut des Anfrage- oder Antwortobjekts, dessen Lebensdauer auf diejenige der Anfrage beschränkt ist.

Ziel-URLs in Plug-ins neu schreiben

Hinzugefügt in: v2.3.3

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

Hinzugefügt in: v2.4.x

Sie können auch den Port des Zielendpunkts überschreiben und zwischen HTTP und HTTPS auswählen. Ändern Sie diese Variablen im Plug-in-Code: req.targetPort und req.targetSecure. Wenn Sie HTTPS auswählen möchten, setzen Sie req.targetSecure auf true und für HTTP auf 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 zeigt, wie die Variablen „req.targetPort“ und „req.targetSecure“ verwendet werden und wie Edge Microgateway mithilfe von Eureka als Dienstendpunktkatalog eine dynamische Endpunktsuche 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 wurden, wird das Array zu einem Puffer 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);

    }

  };

}

Akkumulatoren-Antwort

Dieses Plug-in sammelt Datenblöcke aus dem Ziel in einem Array-Attribut, das an das Antwortobjekt angehängt ist. Wenn alle Antwortdaten empfangen wurden, wird das Array zu einem Puffer 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 Reihenfolge platzieren.

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 „header-uppercase“

Edge Microgateway-Distributionen enthalten ein Beispiel-Plug-in namens <microgateway-root-dir>/plugins/header-uppercase. Das Beispiel enthält Kommentare, in denen die einzelnen Funktions-Handler beschrieben werden. In diesem Beispiel wird eine einfache Datentransformation der Zielantwort durchgeführt und der Clientanfrage und der Zielantwort werden 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();
    }

  };

}


Großschreibung umwandeln

Dies ist ein allgemeines Transformations-Plug-in, das Sie für eine beliebige Art von Transformation ä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);
    }

  };

}