Skip to content
Aitor Magán García edited this page Jun 7, 2013 · 34 revisions

RuSH (HTTP Relayer) v.1.0

1 - OVERVIEW

  • Would you like to make effortless Async HTTP request?
  • Do yo want to track the state of your relayed requests?
  • Add automatic retransmissions/retries of your request?
  • Do you need callbacks when your request is finished?
  • Keep an historic record of custom information related to the request?

Rush implements an scalable mechanism to provide such functionality, with minor client impact (Header stamping HTTP API).

Rush has been developed using:

WebStorm

Ask us for your OpenSource License

2 - API REFERENCE

2.1 - General Notes

Rush exploits the header stamping mechanisn in order to configure every relayed request. That is you may add predefined headers to your http request in order to define the request expected behaviour.

2.1.1 - URI Structure

The main Rush entry point is defined by the Host itself. In general no path is needed in order to exploit Rush functionality.

The exception to this rule is the retrieve response method, defined as a readonly resource:

http://[RUSHHOST]/response/[id]
2.1.2 - HTTP/S methods

From a resource perspective it could be summarized as:

  • You may request http/https GET/POST/PUT/DELETE actions to http://[RUSHHOST] in order to relay a request

  • You may request http GET action to http://[RUSHHOST]/response/[id] n order to obtain stored persistent responses

2.1.3 - Security

Rush enables secure communication between Clients and Target endpoints vía HTTPS protocol. Custom security headers will be bypassed to the Target endpoint. Look at oAuth Usage Example

2.1.4 - Errors

Rush http error codes are not linked to Target endpoint responses. That is:

  • HTTP 200 Ok means that the relayed request has been successfully accomplished by Rush

  • HTTP 400 Error means that Rush itself is having some problems with your request

  • HTTP 500 Error means that Rush endpoint is in trouble

Information related to the relayed error will be located as part of the Rush response body. So you may find a HTTP 200 OK response (Rush has successfully relayed de request) while the Target endpoint gives us a HTTP 403 Error (in response body).

You will find detailed info at Detailed Resource View

2.1.5 - Encoding

Rush returns all its responses in a JSON file following a UTF-8 encondig. If you want to send some content to a Target Host you should set the content-type header properly (it will be bypassed to target host, Rush will ignore it).

If you want to retrieve and store binary content you mush use the "x-relayer-enconding" header and set it to "base64" so the content of the request will be coded in base 64 and stored in Redis. Later, you will be able to retrieve the original content uncoding the response returned by Rush.

2.2 - Resources & Operations

Resource HTTP/HTTPS Description
[RushHost]/ GET [[Relays a GET request to Target Endpoint
[RushHost]/ POST [[Relays a POST request to Target Endpoint
[RushHost]/ PUT [[Relays a PUT request to Target Endpoint
[RushHost]/ DELETE [[Relays a DELETE request to Target Endpoint
[RushHost]/response/:id GET [[Retrieves :id response persistent data

Follow the link for more info related to Header Stamping options for every [RushHost]/ request.

2.3 - Header Stamping Model

The different policies may be included in the request header (header stamping).

All the policies may (should) be mixed as desired.

Header/Policie Value Description
[[X-relayer-host Detailed-Header-View]] TARGET_URL
[[X-relayer-persistence Detailed-Header-View]] "STATUS"/"HEADER"/"BODY"
[[x-relayer-httpcallback Detailed-Header-View]] CALLBACK_URL
[[x-relayer-httpcallback-error Detailed-Header-View]] CALLBACK_URL
[[X-relayer-retry Detailed-Header-View]] "interval1, interval2,…"
[[X-relayer-topic Detailed-Header-View]] TOPIC
[[X-relayer-proxy Detailed-Header-View]] HOST:PORT
[[X-relayer-encoding Detailed-Header-View]] "base64"

3 - GETTING STARTED

####Instalation Guide In order to install Rush (as a component), you should follow the next steps:

  1. Download one stable version
  2. Later you have to install Rush dependencies. To do this, you have to execute the following command in your project directory:
npm install --production
  1. Then you have to set up the databases editing the config file located in /src/configBase.js. Redis location and MongoDB location (if used) must be set.
  2. Once, you have set Redis hostname, you have to run it. Go to the source folder of your own installation of Redis and execute the following command:
./redis-server
  1. MongoDB must be active in the host set in the config file. If you have selected your own MongoDB server, you must go the binary folder of your installation and execute the following commands (according to the README file of MongoDB):
mkdir /data/db
./mongod

Probably, you will need administrator privileges. 6. When you have executed the databases, you are able to run Rush. First of all you have to run a listener which will receive all the petitions. Then you must run one or more consumer which will process all the petitions received by the listener. The listener and the consumer are located in the src folder:

cd src
node listener.js //Can be executed more than once
node consumer.js //Can be executed more than once

4 - CONTRIBUTE

4.1 - Development Environment Setup

(...)

4.2 - How to Run the Tests (e2e and acceptance)

Rush uses mocha as its testing suite.

Tests files are located in test/e2e. If you want to run a single test the command will be:

./mocha [name_of_the_test]

Notice that in this case you will have to install mocha globally:

npm install -g mocha

Otherwise, if you want to run all the tests together the command is:

grunt test

#####Running benchmarks

There are different benchmark depending on the server conditions.

Blockin Server: This benchmark controls the number of queued services when the server takes some time to answer the petitions. This time can be configured in the 'config.js' file. Different tests will be executed with different delays: from the start time to the max delay increasing at the set interval.

Flusing Queues: This benchmark controls the time that takes the completion of a service. The number of services to be completed can be set in the 'config.js' file. In addition you can set the payload of the services. Different tests will be executed with differents payloads: from the start payload to the max payload increasing at the set interval.

No Lag Server: This benchmark controls the number of queued services when the server answers without any delays. You can set the number of bytes that the server will emit, the test time and the number of services to be completed.

4.3 - TIP & TRICKS

5. - ANNEX

5.1 - ARCHITECTURE

Rush Implements a Producer&Consumer (+Worker) architecture. Where we may have several Producer nodes (node listener.js) and Consumer nodes (node consumer.js). Both kind of nodes implemented by node.js processes which intercommunicate thanks to a buffer/queue hosted by REDIS. Every consumer will manage a pool of workers implementing Rush behaviour. They will also provide AddOns in order to extend policies or include new functionality associated to internal events. HTTP Header stamping is used in order to pre-program the expected behaviour of each request.

5.2 Implementing AddOns

Rush gives you the option of implementing your own addons to increase its funcionality. This feature is allowed since the system emits multiple events.

Subscribing to an event

The first step to implement your addons is to subscribe to a channel that emits events. In Rush there are two channels:

  • State of Request Channel: If you subscribe to this channel you will receive an event when a request changes its state (E.g: the request is completed).
  • Request Error Channel: If you subscribe to this channel you will receive an event if an error has ocurred. You can be subscribed to one channel or both.
Returned data

The data received if you subscribed to a channel is an object with the following shared fields:

  • id: The id of the request.
  • topic: The topic header of the request.
  • date: The date when the event has been emitted.

If you are subscribed to the error channel there is an error field in which the error that has ocurred is returned.

Example of a returned object from the error channel:

{ id: "bdfa8730-b708-11e2-b48d-97685854ef78",
  topic: { /*Your client info */ }, /*bypass from x-relayer-topic policy */
  date: Tue May 07 2013 13:24:55 GMT+0200 (CEST),
  err: 
   { error: "ENOTFOUND(getaddrinfo)" } }

On the other hand, if you are subscribed to the state channel these fields will be returned in addition to the shared ones:

  • state: The state of the request (completed, pending, error...).
  • task: The task that is being processed.
  • idConsumer: The id of its consumer (emitted only if the request has been assigned to a consumer).
  • result: The result of the request (emitted only if the request has beend assigned to a consumer).

Example of a returned object from the state channel:

{ id: "ed086a00-b704-11e2-b48d-97685854ef78",
  topic: { /*Your client info */ }, /*bypass from x-relayer-topic policy */
  state: "completed",
  date: Tue May 07 2013 12:57:36 GMT+0200 (CEST),
  task: 
   { url: "/", /* Relayed request URL */
     headers: 
      { /*task headers*/ },
  result: 
   { statusCode: 200,
     headers: 
      { /*result headers*/ },
     body: "This is the result from the relayed request" } }
Implementing your Addon

First of all, you need to add the following depencency to your module.

var MG = require("./myGlobals").C;

Example of subscribing to the state channel:

function init(emitter) {
  "use strict";
  return function(callback) {
    emitter.on(MG.EVENT_NEWSTATE, function onNewEvent(data) {
      // code of your addon
    }
    callback(null, 'nameOfYourAddon OK');
  }
}

If you want to subscribe to the error channel you only need to change the first parameter of the subscribing function for MG.EVENT_ERR. You can be subscribed to both events. For example:

function init(emitter) {
  "use strict";
  return function(callback) {
    emitter.on(MG.EVENT_NEWSTATE, function onNewEvent(data) {
      // code of your addon
    }
    emitter.on(MG.EVENT_ERR, function onNewEvent(data) {
      // code of your addon
    }
    callback(null, 'nameOfYourAddon OK');
  }
}

At last, you need to add your addon module to Rush config file:

exports.consumer.evModules = [
    {module: "./evCallback"}
    ,{module: "./evPersistence"}
    ,{module: "./nameOfYourAddon"}
];