कस्टम प्लग इन डेवलप करना

आपको Apigee Edge का दस्तावेज़ दिख रहा है.
Apigee X के दस्तावेज़ पर जाएं.
जानकारी

Edge Microgateway v. 3.1.5 और इसके बाद के वर्शन

ऑडियंस

यह विषय उन डेवलपर के लिए है जो कस्टम प्लगिन लिखकर, Edge Microgateway की सुविधाओं को बढ़ाना चाहते हैं. अगर आपको नया प्लगिन लिखना है, तो JavaScript और Node.js का अनुभव होना ज़रूरी है.

कस्टम Edge Microgateway प्लगिन क्या होता है?

प्लगिन, Node.js मॉड्यूल होता है. यह Edge Microgateway में सुविधाएं जोड़ता है. प्लगिन मॉड्यूल एक जैसे पैटर्न का पालन करते हैं और Edge Microgateway को पता होती है कि उन्हें कहां सेव किया गया है. इससे उन्हें अपने-आप खोजा जा सकता है और चलाया जा सकता है. Edge Microgateway इंस्टॉल करने पर, आपको पहले से तय किए गए कई प्लगिन मिलते हैं. इनमें पुष्टि करने, स्पाइक अरेस्ट, कोटा, और विश्लेषण के लिए प्लगिन शामिल हैं. इन मौजूदा प्लग इन के बारे में, प्लगिन इस्तेमाल करना लेख में बताया गया है.

कस्टम प्लगिन लिखकर, माइक्रोगेटवे में नई सुविधाएं और क्षमताएं जोड़ी जा सकती हैं. डिफ़ॉल्ट रूप से, Edge Microgateway एक सुरक्षित पास-थ्रू प्रॉक्सी है. यह अनुरोधों और जवाबों को टारगेट सेवाओं से बिना किसी बदलाव के पास करता है. कस्टम प्लगिन की मदद से, माइक्रोगेटवे से होकर गुज़रने वाले अनुरोधों और जवाबों के साथ प्रोग्राम के हिसाब से इंटरैक्ट किया जा सकता है.

कस्टम प्लगिन कोड कहां डालें

Edge Microgateway को इंस्टॉल करने के दौरान, कस्टम प्लगिन के लिए एक फ़ोल्डर शामिल किया जाता है. यह फ़ोल्डर यहां मौजूद होता है:

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

यहां [prefix], npm प्रीफ़िक्स डायरेक्ट्री है. इसके बारे में Edge Microgateway इंस्टॉल करना में "Edge Microgateway कहां इंस्टॉल किया जाता है" लेख में बताया गया है.

इस डिफ़ॉल्ट प्लगिन डायरेक्ट्री को बदला जा सकता है. देखें कि प्लगिन कहां मिलेंगे.

पहले से तय किए गए प्लगिन की समीक्षा करना

अपना प्लगिन बनाने से पहले, यह देख लें कि पहले से तय किए गए किसी भी प्लगिन से आपकी ज़रूरतें पूरी नहीं हो रही हैं. ये प्लगिन यहां मौजूद होते हैं:

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

इसमें [prefix], npm प्रीफ़िक्स डायरेक्ट्री है. Edge Microgateway इंस्टॉल करना में, "Edge Microgateway कहां इंस्टॉल किया जाता है" भी देखें.

ज़्यादा जानकारी के लिए, Edge Microgateway के साथ उपलब्ध कराए गए पहले से तय किए गए प्लगिन लेख भी पढ़ें.

कोई सामान्य प्लगिन लिखना

इस सेक्शन में, हम एक सामान्य प्लगिन बनाने के लिए ज़रूरी चरणों के बारे में जानेंगे. यह प्लगिन, जवाब के डेटा (चाहे वह कुछ भी हो) को "नमस्ते, दुनिया के लोगों!" स्ट्रिंग से बदल देता है और इसे टर्मिनल पर प्रिंट करता है.

  1. अगर Edge Microgateway चल रहा है, तो इसे अभी बंद करें:
    edgemicro stop
  2. cd को कस्टम प्लगिन डायरेक्ट्री में जोड़ें:

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

    यहां [prefix], npm प्रीफ़िक्स डायरेक्ट्री है. इसके बारे में Edge Microgateway इंस्टॉल करना में "Edge Microgateway कहां इंस्टॉल किया जाता है" लेख में बताया गया है.

  3. response-override नाम का एक नया प्लगिन प्रोजेक्ट बनाएं और cd उसमें जाएं:
    mkdir response-override && cd response-override
  4. नया Node.js प्रोजेक्ट बनाएं:
    npm init
    डिफ़ॉल्ट वैल्यू स्वीकार करने के लिए, Return बटन को कई बार दबाएं.
  5. टेक्स्ट एडिटर का इस्तेमाल करके, index.js नाम की नई फ़ाइल बनाएं.
  6. यहां दिए गए कोड को index.js में कॉपी करें और फ़ाइल सेव करें.
    '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. अब आपने एक प्लगिन बना लिया है. इसे Edge Microgateway के कॉन्फ़िगरेशन में जोड़ना होगा. $HOME/.edgemicro/[org]-[env]-config.yaml फ़ाइल खोलें. यहां org और env, आपके Edge संगठन और एनवायरमेंट के नाम हैं.
  8. नीचे दिए गए तरीके से, plugins:sequence एलिमेंट में response-override प्लगिन जोड़ें.
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
  9. Edge Microgateway को रीस्टार्ट करें.
  10. Edge Microgateway के ज़रिए किसी एपीआई को कॉल करना. (इस एपीआई कॉल में यह माना जाता है कि आपने एपीआई पासकोड की सुरक्षा के साथ, ट्यूटोरियल जैसा ही कॉन्फ़िगरेशन सेट अप किया है. इसके बारे में, Edge Microgateway सेट अप और कॉन्फ़िगर करना में बताया गया है:
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!

किसी प्लगिन की बनावट

Edge Microgateway के इस सैंपल प्लगिन में, अपने प्लगिन डेवलप करते समय फ़ॉलो किए जाने वाले पैटर्न के बारे में बताया गया है. इस सेक्शन में जिस सैंपल प्लगिन के बारे में बताया गया है उसका सोर्स कोड, plugins/header-uppercase/index.js.

  • प्लगिन, स्टैंडर्ड NPM मॉड्यूल होते हैं. इनके रूट फ़ोल्डर में package.json और index.js होते हैं .
  • किसी प्लगिन को init() फ़ंक्शन एक्सपोर्ट करना होगा.
  • init() फ़ंक्शन तीन आर्ग्युमेंट लेता है: config, logger, और stats. इन आर्ग्युमेंट के बारे में, Plugin init() फ़ंक्शन के आर्ग्युमेंट में बताया गया है.
  • init(), नाम वाले फ़ंक्शन हैंडलर वाला एक ऑब्जेक्ट दिखाता है. इन हैंडलर को तब कॉल किया जाता है, जब अनुरोध की लाइफ़टाइम के दौरान कुछ इवेंट होते हैं.

इवेंट हैंडलर फ़ंक्शन

किसी प्लगिन को इन इवेंट हैंडलर फ़ंक्शन में से कुछ या सभी को लागू करना होगा. इन फ़ंक्शन को लागू करना आपके ऊपर निर्भर करता है. कोई भी फ़ंक्शन वैकल्पिक होता है. आम तौर पर, प्लगिन इन फ़ंक्शन का कम से कम एक सबसेट लागू करता है.

फ़्लो इवेंट हैंडलर का अनुरोध करना

Edge Microgateway में इन फ़ंक्शन को अनुरोध पर होने वाले इवेंट कहा जाता है.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

onrequest फ़ंक्शन

क्लाइंट के अनुरोध की शुरुआत में कॉल किया जाता है. यह फ़ंक्शन तब ट्रिगर होता है, जब Edge Microgateway को अनुरोध का पहला बाइट मिलता है. इस फ़ंक्शन से, आपको अनुरोध हेडर, यूआरएल, क्वेरी पैरामीटर, और एचटीटीपी तरीके का ऐक्सेस मिलता है. अगर आपने पहले आर्ग्युमेंट के तौर पर कोई ट्रुथी वैल्यू (जैसे कि Error का कोई इंस्टेंस) पास करके कॉल किया है, तो अनुरोध को प्रोसेस करना बंद कर दिया जाता है. साथ ही, टारगेट अनुरोध शुरू नहीं किया जाता.

उदाहरण:

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

ondata_request फ़ंक्शन

जब क्लाइंट से डेटा का कोई हिस्सा मिलता है, तब इसे कॉल किया जाता है. यह प्लगिन, अनुरोध के डेटा को प्लगिन के क्रम में मौजूद अगले प्लगिन को पास करता है. सीक्वेंस में मौजूद आखिरी प्लगिन से मिली वैल्यू, टारगेट को भेजी जाती है. यहां इस्तेमाल का एक सामान्य उदाहरण दिया गया है. इसमें अनुरोध के डेटा को टारगेट पर भेजने से पहले बदला जाता है.

उदाहरण:

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

onend_request फ़ंक्शन

इस फ़ंक्शन को तब कॉल किया जाता है, जब क्लाइंट से अनुरोध का पूरा डेटा मिल जाता है.

उदाहरण:

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

onclose_request फ़ंक्शन

इससे पता चलता है कि क्लाइंट कनेक्शन बंद हो गया है. इस फ़ंक्शन का इस्तेमाल उन मामलों में किया जा सकता है जहां क्लाइंट कनेक्शन भरोसेमंद नहीं है. यह तब कॉल किया जाता है, जब क्लाइंट से सॉकेट कनेक्शन बंद हो जाता है.

उदाहरण:

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

onerror_request फ़ंक्शन

क्लाइंट के अनुरोध को पाने में कोई गड़बड़ी होने पर इस फ़ंक्शन को कॉल किया जाता है.

उदाहरण:

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

जवाब देने के फ़्लो के इवेंट हैंडलर

इन फ़ंक्शन को Edge Microgateway में रिस्पॉन्स इवेंट पर कॉल किया जाता है.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

onresponse फ़ंक्शन

इसे टारगेट रिस्पॉन्स की शुरुआत में कॉल किया जाता है. यह फ़ंक्शन तब ट्रिगर होता है, जब Edge Microgateway को जवाब की पहली बाइट मिलती है. इस फ़ंक्शन से, आपको रिस्पॉन्स हेडर और स्टेटस कोड का ऐक्सेस मिलता है.

उदाहरण:

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 फ़ंक्शन

जब टारगेट से डेटा का कोई हिस्सा मिलता है, तब इस फ़ंक्शन को कॉल किया जाता है.

उदाहरण:

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


onend_response फ़ंक्शन

इस फ़ंक्शन को तब कॉल किया जाता है, जब टारगेट से जवाब का पूरा डेटा मिल जाता है.

उदाहरण:

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

onclose_response फ़ंक्शन

इससे पता चलता है कि टारगेट कनेक्शन बंद हो गया है. इस फ़ंक्शन का इस्तेमाल उन मामलों में किया जा सकता है जहां टारगेट कनेक्शन भरोसेमंद नहीं है. यह तब कॉल किया जाता है, जब टारगेट से सॉकेट कनेक्शन बंद हो जाता है.

उदाहरण:

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


onerror_response फ़ंक्शन

अगर टारगेट रिस्पॉन्स पाने में कोई गड़बड़ी होती है, तो इस फ़ंक्शन को कॉल किया जाता है.

उदाहरण:

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

प्लगिन इवेंट हैंडलर फ़ंक्शन के बारे में ज़रूरी जानकारी

प्लगिन के इवेंट हैंडलर फ़ंक्शन, खास इवेंट के जवाब में कॉल किए जाते हैं. ये इवेंट तब होते हैं, जब Edge Microgateway किसी एपीआई अनुरोध को प्रोसेस करता है.

  • init() फ़ंक्शन हैंडलर (ondata_request, ondata_response वगैरह) में से हर एक को, प्रोसेसिंग पूरी होने पर next() कॉलबैक को कॉल करना होगा. अगर आपने next() को कॉल नहीं किया, तो प्रोसेसिंग रुक जाएगी और अनुरोध पूरा नहीं होगा.
  • next() फ़ंक्शन के पहले आर्ग्युमेंट में गड़बड़ी हो सकती है. इससे अनुरोध को प्रोसेस करने की प्रक्रिया बंद हो जाएगी.
  • ondata_ और onend_ हैंडलर को next() को कॉल करना होगा. इसमें दूसरा आर्ग्युमेंट, टारगेट या क्लाइंट को पास किया जाने वाला डेटा होगा. अगर प्लगिन बफ़र हो रहा है और उसके पास फ़िलहाल ट्रांसफ़ॉर्म करने के लिए काफ़ी डेटा नहीं है, तो इस आर्ग्युमेंट की वैल्यू शून्य हो सकती है.
  • ध्यान दें कि सभी अनुरोधों और जवाबों के लिए, प्लगिन के एक ही इंस्टेंस का इस्तेमाल किया जाता है. अगर किसी प्लगिन को कॉल के बीच, हर अनुरोध की स्थिति को बनाए रखना है, तो वह उस स्थिति को request ऑब्जेक्ट (req) में जोड़ी गई प्रॉपर्टी में सेव कर सकता है. इस प्रॉपर्टी का लाइफ़टाइम, एपीआई कॉल की अवधि के बराबर होता है.
  • सभी गड़बड़ियों को ठीक करें और गड़बड़ी के साथ next() को कॉल करें. next() को कॉल न करने पर, एपीआई कॉल रुक जाएगा.
  • मेमोरी लीक से बचें, क्योंकि इससे Edge Microgateway की परफ़ॉर्मेंस पर असर पड़ सकता है. साथ ही, आउट ऑफ़ मेमोरी होने पर यह क्रैश हो सकता है.
  • Node.js मॉडल का पालन करते समय, मुख्य थ्रेड में ज़्यादा कंप्यूटिंग वाले टास्क न करें. ऐसा करने से, Edge Microgateway की परफ़ॉर्मेंस पर बुरा असर पड़ सकता है.

प्लगिन के init() फ़ंक्शन के बारे में जानकारी

इस सेक्शन में, init() फ़ंक्शन को पास किए गए आर्ग्युमेंट के बारे में बताया गया है: config, logger, और stats.

कॉन्फ़िगरेशन

Edge Microgateway की कॉन्फ़िगरेशन फ़ाइल को Apigee Edge से डाउनलोड किए गए डेटा के साथ मर्ज करके, कॉन्फ़िगरेशन डेटा मिलता है. इस डेटा को config नाम के ऑब्जेक्ट में रखा जाता है.

response-override नाम के प्लगिन में, param नाम का कॉन्फ़िगरेशन पैरामीटर जोड़ने के लिए, default.yaml फ़ाइल में यह कोड डालें:

response-override:
    param: foo

इसके बाद, अपने प्लगिन कोड में पैरामीटर को इस तरह ऐक्सेस किया जा सकता है:

// 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);
    },

इस मामले में, आपको प्लगिन के डीबग आउटपुट में foo प्रिंट किया हुआ दिखेगा:

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

मर्ज किए गए माइक्रोगेटवे कॉन्फ़िगरेशन और डाउनलोड किए गए Apigee Edge डेटा को, चाइल्ड ऑब्जेक्ट config.emgConfigs में ऐक्सेस किया जा सकता है. उदाहरण के लिए, इस कॉन्फ़िगरेशन डेटा को init फ़ंक्शन में इस तरह ऐक्सेस किया जा सकता है:

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

यहां emgConfigs में मौजूद डेटा का उदाहरण दिया गया है:

{
    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: []
  }

लॉगर

सिस्टम लॉगर. फ़िलहाल इस्तेमाल किया जा रहा लॉगर, इन फ़ंक्शन को एक्सपोर्ट करता है. इसमें ऑब्जेक्ट, स्ट्रिंग, एचटीटीपी अनुरोध, एचटीटीपी रिस्पॉन्स या गड़बड़ी का इंस्टेंस हो सकता है.

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

आंकड़े

यह एक ऐसा ऑब्जेक्ट होता है जिसमें अनुरोधों, जवाबों, गड़बड़ियों, और अन्य एग्रीगेट किए गए आंकड़ों की संख्या होती है. ये आंकड़े, माइक्रोगेटवे इंस्टेंस से होकर गुज़रने वाले अनुरोधों और जवाबों से जुड़े होते हैं.

  • treqErrors - गड़बड़ियों वाले टारगेट अनुरोधों की संख्या.
  • treqErrors - गड़बड़ियों वाले टारगेट रिस्पॉन्स की संख्या.
  • statusCodes - यह एक ऑब्जेक्ट है, जिसमें रिस्पॉन्स कोड की संख्या शामिल होती है:
{
  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
  }
  
  • अनुरोध - अनुरोधों की कुल संख्या.
  • जवाब - जवाबों की कुल संख्या.
  • कनेक्शन - टारगेट किए गए चालू कनेक्शन की संख्या.

next() फ़ंक्शन के बारे में जानकारी

सभी प्लगिन तरीकों को next() को कॉल करना होगा, ताकि सीरीज़ में अगले तरीके को प्रोसेस किया जा सके. ऐसा न करने पर, प्लगिन प्रोसेस रुक जाएगी. अनुरोध की लाइफ़साइकल में, सबसे पहले onrequest() को कॉल किया जाता है. इसके बाद, ondata_request() को कॉल किया जाता है. हालांकि, ondata_request को सिर्फ़ तब कॉल किया जाता है, जब अनुरोध में डेटा शामिल हो. जैसे, POST अनुरोध के मामले में. इसके बाद, onend_request() को कॉल किया जाएगा. इसे अनुरोध प्रोसेस होने के बाद कॉल किया जाता है. onerror_* फ़ंक्शन सिर्फ़ गड़बड़ी होने पर कॉल किए जाते हैं. इनकी मदद से, अपनी पसंद के मुताबिक कोड का इस्तेमाल करके गड़बड़ियों को ठीक किया जा सकता है.

मान लें कि अनुरोध में डेटा भेजा गया है और ondata_request() को कॉल किया गया है. ध्यान दें कि फ़ंक्शन, दो पैरामीटर के साथ next() को कॉल करता है:

next(null, data);

परंपरा के मुताबिक, पहले पैरामीटर का इस्तेमाल गड़बड़ी की जानकारी देने के लिए किया जाता है. इसके बाद, इस जानकारी को चेन में मौजूद अगले फ़ंक्शन में मैनेज किया जा सकता है. इसे null पर सेट करके, हम यह बता रहे हैं कि कोई गड़बड़ी नहीं है और अनुरोध को सामान्य तरीके से प्रोसेस किया जाना चाहिए. अगर यह तर्क सही है (जैसे कि कोई गड़बड़ी वाला ऑब्जेक्ट), तो अनुरोध को प्रोसेस करना बंद कर दिया जाता है और अनुरोध को टारगेट पर भेज दिया जाता है.

दूसरा पैरामीटर, चेन में मौजूद अगले फ़ंक्शन को अनुरोध डेटा पास करता है. अगर आपको कोई अतिरिक्त प्रोसेसिंग नहीं करनी है, तो अनुरोध किए गए डेटा को एपीआई के टारगेट में बिना किसी बदलाव के पास कर दिया जाता है. हालांकि, इस तरीके में आपके पास अनुरोध के डेटा में बदलाव करने और बदले गए अनुरोध को टारगेट पर भेजने का विकल्प होता है. उदाहरण के लिए, अगर अनुरोध का डेटा एक्सएमएल है और टारगेट को JSON की ज़रूरत है, तो ondata_request() तरीके में कोड जोड़ा जा सकता है. इससे (a) अनुरोध के हेडर का कॉन्टेंट टाइप application/json में बदल जाता है और अनुरोध के डेटा को JSON में बदल दिया जाता है. इसके लिए, अपनी पसंद के तरीके का इस्तेमाल किया जा सकता है. उदाहरण के लिए, NPM से मिला Node.js xml2json कन्वर्टर इस्तेमाल किया जा सकता है.

आइए, देखते हैं कि यह कैसा दिखेगा:

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

इस मामले में, अनुरोध के डेटा (जिसे XML माना जाता है) को JSON में बदल दिया जाता है. इसके बाद, बदले गए डेटा को next() के ज़रिए अनुरोध चेन में मौजूद अगले फ़ंक्शन को पास किया जाता है. ऐसा बैकएंड टारगेट को पास करने से पहले किया जाता है.

ध्यान दें कि डीबग करने के लिए, बदला गया डेटा प्रिंट करने के लिए, एक और डीबग स्टेटमेंट जोड़ा जा सकता है. उदाहरण के लिए:

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);
},

प्लगिन हैंडलर के एक्ज़ीक्यूशन ऑर्डर के बारे में जानकारी

अगर आपको Edge Microgateway के लिए प्लगिन लिखने हैं, तो आपको यह समझना होगा कि प्लगिन इवेंट हैंडलर किस क्रम में लागू होते हैं.

यह ध्यान रखना ज़रूरी है कि Edge Microgateway की कॉन्फ़िगरेशन फ़ाइल में प्लगिन का क्रम तय करने पर, अनुरोध हैंडलर बढ़ते क्रम में काम करते हैं. वहीं, जवाब हैंडलर घटते क्रम में काम करते हैं.

नीचे दिए गए उदाहरण से, आपको इस क्रम को समझने में मदद मिलेगी.

1. तीन सामान्य प्लगिन बनाना

इस प्लगिन का इस्तेमाल करें. जब इसके इवेंट हैंडलर को कॉल किया जाता है, तब यह सिर्फ़ कंसोल आउटपुट को प्रिंट करता है:

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);
    }
  };
}

अब, एक ही कोड का इस्तेमाल करके दो और प्लगिन, plugin-2 और plugin-3 बनाएं. हालांकि, console.log() स्टेटमेंट को बदलकर plugin-2 और plugin-3 कर दें.

2. प्लगिन के कोड की समीक्षा करना

एक्सपोर्ट किए गए प्लगिन में मौजूद फ़ंक्शन, <microgateway-root-dir>/plugins/plugin-1/index.js में इवेंट हैंडलर होते हैं. ये अनुरोध और जवाब की प्रोसेसिंग के दौरान, तय किए गए समय पर काम करते हैं. उदाहरण के लिए, onrequest अनुरोध हेडर का पहला बाइट मिलता है. जबकि, onend_response को तब लागू किया जाता है, जब जवाब के डेटा का आखिरी बाइट मिल जाता है.

ondata_response हैंडलर देखें. जब भी जवाब के डेटा का कोई हिस्सा मिलता है, तब इसे कॉल किया जाता है. यह जानना ज़रूरी है कि जवाब का डेटा एक साथ नहीं मिलता. इसके बजाय, डेटा को किसी भी लंबाई के हिस्सों में भेजा जा सकता है.

3. प्लगिन को प्लगिन सीक्वेंस में जोड़ना

इस उदाहरण को जारी रखते हुए, हम Edge Microgateway की कॉन्फ़िगरेशन फ़ाइल (~./edgemicro/config.yaml) में प्लगिन के क्रम में प्लगिन जोड़ेंगे. इसके लिए, नीचे दिया गया तरीका अपनाएं. क्रम अहम है. इससे यह तय होता है कि प्लगिन हैंडलर किस क्रम में काम करेंगे.

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

4. डीबग आउटपुट की जांच करना

अब देखते हैं कि इन प्लगिन को कॉल करने पर क्या आउटपुट मिलेगा. यहां कुछ ज़रूरी बातें बताई गई हैं:

  • प्लगिन, Edge Microgateway की कॉन्फ़िगरेशन फ़ाइल (~./edgemicro/config.yaml) को क्रम से लगाता है. इससे यह तय होता है कि इवेंट हैंडलर को किस क्रम में कॉल किया जाएगा.
  • अनुरोध हैंडलर को बढ़ते क्रम में कॉल किया जाता है. यह क्रम, प्लगिन के क्रम (1, 2, 3) के हिसाब से होता है.
  • रिस्पॉन्स हैंडलर को घटते क्रम में कॉल किया जाता है -- 3, 2, 1.
  • ondata_response हैंडलर को, डेटा के हर उस चंक के लिए एक बार कॉल किया जाता है जो आता है. इस उदाहरण (नीचे दिखाया गया आउटपुट) में, दो चंक मिले हैं.

यहां एक सैंपल डीबग आउटपुट दिया गया है. यह तब जनरेट होता है, जब इन तीन प्लगिन का इस्तेमाल किया जा रहा हो और Edge Microgateway के ज़रिए कोई अनुरोध भेजा गया हो. बस इस बात पर ध्यान दें कि हैंडलर को किस क्रम में कॉल किया जाता है:

  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

खास जानकारी

जब आपको प्लगिन की कस्टम सुविधा लागू करनी हो, तब यह समझना बहुत ज़रूरी होता है कि प्लगिन हैंडलर को किस क्रम में कॉल किया जाता है. जैसे, अनुरोध या जवाब के डेटा को इकट्ठा करना और उसे बदलना.

बस यह ध्यान रखें कि अनुरोध हैंडलर, Edge Microgateway की कॉन्फ़िगरेशन फ़ाइल में प्लगिन के क्रम के हिसाब से लागू होते हैं. वहीं, जवाब हैंडलर इसके उलट क्रम में लागू होते हैं.

प्लगिन में ग्लोबल वैरिएबल इस्तेमाल करने के बारे में जानकारी

Edge Microgateway को भेजे गए हर अनुरोध को प्लगिन के एक ही इंस्टेंस पर भेजा जाता है. इसलिए, दूसरे क्लाइंट से मिले दूसरे अनुरोध की स्थिति, पहले अनुरोध की स्थिति को बदल देगी. प्लगिन की स्थिति को सेव करने के लिए, सिर्फ़ एक सुरक्षित जगह होती है. वह है अनुरोध या जवाब ऑब्जेक्ट की प्रॉपर्टी में स्थिति को सेव करना. इस ऑब्जेक्ट का लाइफ़टाइम, अनुरोध के लाइफ़टाइम तक ही सीमित होता है.

प्लगिन में टारगेट यूआरएल फिर से लिखना

इस वर्शन में जोड़ा गया: v2.3.3

अपने प्लगिन कोड में इन वैरिएबल में बदलाव करके, प्लगिन में डिफ़ॉल्ट टारगेट यूआरएल को डाइनैमिक रूप से बदला जा सकता है: req.targetHostname और req.targetPath.

v2.4.x में जोड़ा गया

आपके पास टारगेट एंडपॉइंट पोर्ट को बदलने का विकल्प भी होता है. साथ ही, एचटीटीपी और एचटीटीपीएस में से किसी एक को चुना जा सकता है. अपने प्लगिन कोड में इन वैरिएबल में बदलाव करें: req.targetPort और req.targetSecure. एचटीटीपीएस चुनने के लिए, req.targetSecure को true पर सेट करें. एचटीटीपी के लिए, इसे false पर सेट करें. अगर आपने req.targetSecure को true पर सेट किया है, तो ज़्यादा जानकारी के लिए इस चर्चा थ्रेड को देखें.

Edge Microgateway में eurekaclient नाम का एक सैंपल प्लगिन जोड़ा गया है. इस प्लगिन में, req.targetPort और req.targetSecure वैरिएबल इस्तेमाल करने का तरीका बताया गया है. साथ ही, इसमें यह भी बताया गया है कि Edge Microgateway, Eureka का इस्तेमाल करके डाइनैमिक एंडपॉइंट लुकअप कैसे कर सकता है. Eureka, सर्विस एंडपॉइंट कैटलॉग के तौर पर काम करता है.


प्लगिन के सैंपल

ये प्लगिन, Edge Microgateway के इंस्टॉलेशन के साथ उपलब्ध कराए जाते हैं. इन्हें Edge Microgateway के इंस्टॉलेशन में यहां देखा जा सकता है:

[prefix]/lib/node_modules/edgemicro/plugins

यहां [prefix], npm प्रीफ़िक्स डायरेक्ट्री है. इसके बारे में Edge Microgateway इंस्टॉल करना में "Edge Microgateway कहां इंस्टॉल किया जाता है" लेख में बताया गया है.

accumulate-request

यह प्लगिन, क्लाइंट से डेटा के हिस्सों को इकट्ठा करके, अनुरोध ऑब्जेक्ट से जुड़ी ऐरे प्रॉपर्टी में सेव करता है. अनुरोध का पूरा डेटा मिलने पर, ऐरे को Buffer में जोड़ दिया जाता है. इसके बाद, इसे क्रम में मौजूद अगले प्लगिन को पास कर दिया जाता है. यह प्लगिन, क्रम में पहला प्लगिन होना चाहिए, ताकि बाद के प्लगिन को इकट्ठा किया गया अनुरोध डेटा मिल सके.

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);

    }

  };

}

accumulate-response

यह प्लगिन, टारगेट से डेटा के हिस्सों को इकट्ठा करके, रिस्पॉन्स ऑब्जेक्ट से जुड़ी ऐरे प्रॉपर्टी में सेव करता है. जवाब का पूरा डेटा मिलने के बाद, कैटगरी को बफ़र में जोड़ दिया जाता है. इसके बाद, इसे क्रम में अगले प्लगिन को पास कर दिया जाता है. यह प्लगिन, जवाबों पर काम करता है. इन जवाबों को उल्टे क्रम में प्रोसेस किया जाता है. इसलिए, आपको इसे क्रम में आखिरी प्लगिन के तौर पर रखना चाहिए.

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);
    }

  };

}

header-uppercase प्लगिन

Edge Microgateway के डिस्ट्रिब्यूशन में, <microgateway-root-dir>/plugins/header-uppercase नाम का एक सैंपल प्लगिन शामिल होता है. इस सैंपल में, हर फ़ंक्शन हैंडलर के बारे में बताने वाले कमेंट शामिल हैं. इस सैंपल में, टारगेट रिस्पॉन्स के डेटा को कुछ हद तक बदला गया है. साथ ही, क्लाइंट के अनुरोध और टारगेट रिस्पॉन्स में कस्टम हेडर जोड़े गए हैं.

<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();
    }

  };

}

transform-uppercase

यह एक सामान्य ट्रांसफ़ॉर्मेशन प्लगिन है. इसमें बदलाव करके, अपनी ज़रूरत के हिसाब से ट्रांसफ़ॉर्मेशन किया जा सकता है. इस उदाहरण में, जवाब और अनुरोध के डेटा को सिर्फ़ बड़े अक्षरों में बदला गया है.

 */
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);
    }

  };

}