ewd 3 training course part 44: creating microservices with qewd.js

136
Copyright © 2016 M/Gateway Developments Ltd EWD 3 Training Course Part 44 Creating MicroServices with QEWD.js Rob Tweed Director, M/Gateway Developments Ltd Twitter: @rtweed

Upload: rob-tweed

Post on 22-Jan-2018

158 views

Category:

Software


2 download

TRANSCRIPT

Page 1: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

EWD 3 Training CoursePart 44

Creating MicroServices with QEWD.js

Rob TweedDirector, M/Gateway Developments Ltd

Twitter: @rtweed

Page 2: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Using JSON Web Tokens with QEWD REST Services

• This part of the course assumes that you've taken, at least:

• Part 31: Using QEWD for Web and REST Services• http://www.slideshare.net/robtweed/ewd-3-training-course-part-31-ewdxpress-for-web-and-rest-services

• Part 43: Using JSON Web Tokens with QEWD REST Services

– https://www.slideshare.net/robtweed/ewd-3-training-course-part-43-using-json-web-tokens-with-qewd-rest-services

Page 3: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

MicroServices: Background

• For an introduction on MicroServices, what they are, how they work and when and why they should be considered, see this overview on QEWD.js and MicroServices:

• https://www.slideshare.net/robtweed/qewdjs-json-web-tokens-microservices

Page 4: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD MicroService Fabric

ewd-qoper8queue

Express

Node.js

socket.io

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

ewd-qoper8queue

Express

Node.js

socket.io

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

ewd-qoper8queue

Express

Node.js

socket.io

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

User authentication

Demographics

Pharmacy

ewd-qoper8queue

Express

Node.js

socket.io

CacheGT.M,YottaDBRedis

Node.jsWorkerProcess

CacheGT.M,YottaDBRedis

Node.jsWorkerProcess

CacheGT.M,YottaDBRedis

Node.jsWorkerProcess

Client Orchestration

HTTPSWebSocketConnections

Page 5: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD.js Solution

ewd-qoper8queue

Express

Node.js

socket.io

Equivalent toewd-client

socket.io-client

Incoming RESTrequest

Page 6: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD.js Solution

ewd-qoper8queue

Express

Node.js

socket.io

Equivalent toewd-client

socket.io-client

IncomingWebSocket

request

Page 7: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD.js Solution

ewd-qoper8queue

Express

Node.js

socket.io

Equivalent toewd-client

socket.io-client

IncomingWebSocket

request

ProcessLocally?

Page 8: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD.js Solution

ewd-qoper8queue

Express

Node.js

socket.io

Equivalent toewd-client

socket.io-client

IncomingWebSocket

request

Handledby remote

MicroService?

Page 9: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD.js Solution

ewd-qoper8queue

Express

Node.js

socket.io

PersistentBi-directionalWebSocketconnection

Securedover

HTTPS

ewd-qoper8queue

Express

Node.js

socket.io

Equivalent toewd-client

socket.io-client

Remote QEWD MicroService

Page 10: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD MicroService Architecture

• Incoming requests can be either from:– a browser over WebSockets or Ajax– REST over HTTP / HTTPS

• This tutorial will focus on REST

Page 11: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD MicroService Architecture

• MicroService routes are defined in the QEWD Startup file

• On startup, WebSocket connections are established between the primary orchestrating QEWD system(s) and the MicroService QEWD Systems

• MicroService Routing is handled by the QEWD Master Process

Page 12: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD MicroService Architecture

• Incoming requests to the orchestrating QEWD Server are over REST/HTTP(S)

• If the requests are destined for a MicroService, they are converted to QEWD WebSocket messages

• Incoming requests on MicroService QEWD systems are handled as QEWD WebSocket requests

Page 13: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD MicroService Architecture

• QEWD MicroServices rely on JWTs for authentication and Session/State management

• All participating QEWD systems must be configured with the same JWT secret

Page 14: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Let's Get Started!

Page 15: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Simple Example

• Two QEWD systems– One will be the primary orchestrating system

that will be the endpoint for incoming REST requests

• We'll refer to this as the Primary QEWD Server

– One will be used as a user authentication service

• We'll refer to this as the Login MicroService server

Page 16: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD MicroService Fabric

ewd-qoper8queue

Express

Node.js

socket.io

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

CacheGT.M,YottaDBRedisNode.js

WorkerProcess

User authentication

ewd-qoper8queue

Express

Node.js

socket.io

CacheGT.M,YottaDBRedis

Node.jsWorkerProcess

CacheGT.M,YottaDBRedis

Node.jsWorkerProcess

CacheGT.M,YottaDBRedis

Node.jsWorkerProcess

Client Primary Server

HTTPSWebSocketConnections

Login MicroService Server

Page 17: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Configuring the Primary Server

Page 18: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Startup file from Part 43var config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD REST Server', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

}};

var routes = [ {path: '/api', module: 'myRestService'}];

var qewd = require('qewd').master;qewd.start(config, routes);

Page 19: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionvar config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD REST Server', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {},

routes: []

}};

var routes = [ {path: '/api', module: 'myRestService'}];

var qewd = require('qewd').master;qewd.start(config, routes);

Page 20: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionvar config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD REST Server', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {},

routes: []

}};

var routes = [ {path: '/api', module: 'myRestService'}];

var qewd = require('qewd').master;qewd.start(config, routes);

Two parts to the MicroService Configuration:

-destinations: defines the endpoints-routes – assigns URL paths to destinations

Page 21: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionjwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: []

}};

Page 22: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionjwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: []

}};

You give each destination a name(your choice what it's called)

Page 23: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionjwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: []

}};

A destination defines:

-a QEWD host endpoint URL

Page 24: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionjwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: []

}};

A destination defines:

-The Application name assigned for this destination (ie the application on the remote machine that will handle incoming requests for this service destination)

Page 25: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionjwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

] }};

Page 26: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

Each Route is defined by an array element

Page 27: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

Each Route is defined by:

- A URL path (which can be templated)

Page 28: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

Each Route is defined by:

-optionally, an HTTP method

If not specified, the route will apply toall HTTP methods for the path

Page 29: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

Each Route is defined by:

-the MicroService destination to which the request will be routed

Page 30: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

Each Route is defined by:

-the MicroService destination to which the request will be routed

Page 31: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

MicroService Routes Override Local Routes

• Look in the Startup file and you'll see it also contains a route for locally processing all incoming REST requests starting /api:

var routes = [ {path: '/api', module: 'myRestService'}];

Page 32: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

MicroService Routes Override Local Routes

• Look in the Startup file and you'll see it also contains a route for locally processing all incoming REST requests starting /api:

• Our MicroService route for /api/login will take preference over this

var routes = [ {path: '/api', module: 'myRestService'}];

Page 33: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

You can define as many Routes andDestinations as you like

Page 34: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

},

info_service: {

host: 'http://192.168.1.115:8080',

application: 'info-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

Destinations can be at differentphysical endpoints

Page 35: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

},

info_service: {

host: 'http://192.168.1.114:8080',

application: 'info-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

The same physical endpoint can appearin more than one Destination

Page 36: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

},

info_service: {

host: 'http://192.168.1.114:8080',

application: 'info-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]}

The same physical endpoint can appearin more than one Destination

In which case the application will bedifferent

Page 37: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

},

info_service: {

host: 'http://192.168.1.115:8080',

application: 'info-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

},

{

path: '/api/info',

method: 'GET',

destination: 'info_service'

}

]}

Each Route can use different Destinations

Page 38: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add the MicroService Definitionu_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

},

{

path: '/api/userinfo',

method: 'GET',

destination: 'login_service'

}

]}

Each Route can use different Destinations

or the same ones

Page 39: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Our Example MicroService Definitionjwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

] }};

In our example we'll just define a singleDestination and Route

POST requests for /api/login will be routedto the MicroService QEWD systemat 192.168.1.114:8080, where they will behandled by the login-micro-serviceapplication

Page 40: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Our Example MicroService Definitionvar config = {

managementPassword: 'keepThisSecret!',

serverName: 'New QEWD Server',

port: 8080,

poolSize: 2,

database: {

type: 'gtm'

},

jwt: {

secret: 'someSecret123'

},

u_services: {

destinations: {

login_service: {

host: 'http://192.168.1.114:8080',

application: 'login-micro-service'

}

},

routes: [

{

path: '/api/login',

method: 'POST',

destination: 'login_service'

}

]

}

};

var routes = [

{

path: '/api',

module: 'myRestService',

errors: {

notfound: {

text: 'Resource Not Recognised',

statusCode: 404

}

}

}

];

var qewd = require('qewd').master;

var q = qewd.start(config, routes);

Save as ~/qewd/ms-startup.js

Change the IP address/domain name of thelogin_service hostproperty to match the serveryou'll be using

Page 41: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Next we'll configure the MicroService System

Page 42: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Next we'll configure the MicroService System

• Remember – we'll now be working on your second QEWD server

• As our starting point, we'll use that original startup file from Part 43 again…

Page 43: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Startup file from Part 43var config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD REST Server', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

}};

var routes = [ {path: '/api', module: 'myRestService'}];

var qewd = require('qewd').master;qewd.start(config, routes);

Page 44: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

MicroService Startup filevar config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD REST Server', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

}};

var routes = [ {path: '/api', module: 'myRestService'}];

var qewd = require('qewd').master;qewd.start(config, routes);

Important: we'll use the sameJWT Secret

Page 45: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

MicroService Startup filevar config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD REST Server', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

}};

var routes = [ {path: '/api', module: 'myRestService'}];

var qewd = require('qewd').master;qewd.start(config, routes);

We don't need this, however,even though this QEWDsystem will be handlingforwarded requests for/api/login

Page 46: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

MicroService Startup filevar config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD REST Server', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

}};

var qewd = require('qewd').master;qewd.start(config);

That's because the primaryQEWD system will re-formatthe /api/login REST requests to a WebSocket message

Page 47: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

MicroService Startup filevar config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD REST Server', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

}};

var qewd = require('qewd').master;qewd.start(config);

That's because the primaryQEWD system will re-formatthe /api/login REST requests to a WebSocket message

These messages will be handledby the login_micro-serviceapplication on this QEWD system

Page 48: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

MicroService Startup filevar config = { managementPassword: 'keepThisSecret!', serverName: 'QEWD Login MicroService', port: 8080, poolSize: 2, database: { type: 'gtm' },

jwt: {

secret: 'someSecret123'

}};

var qewd = require('qewd').master;qewd.start(config);

Save this file as:

~/qewd/loginservice.js

Page 49: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Start Up the Two QEWD Systems

• It doesn't matter which you start up first

• Let's start the main one first and see what happens

Page 50: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Start Up the Two QEWD Systems

On the primary QEWD machine:

cd ~/qewdnode ms-startup

Page 51: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Look at the QEWD Node Console Log

rtweed@ubuntu:~/qewd$ node microservicesSetting up micro-service connectionsAdding MicroService Client connection: url = http://192.168.1.114:8080; application = login-micro-servicestarting microService connection to http://192.168.1.114:8080webServerRootPath = /home/rtweed/qewd/www/route /api will be handled by qx.router

Page 52: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Look at the QEWD Node Console Log

rtweed@ubuntu:~/qewd$ node microservicesSetting up micro-service connectionsAdding MicroService Client connection: url = http://192.168.1.114:8080; application = login-micro-servicestarting microService connection to http://192.168.1.114:8080webServerRootPath = /home/rtweed/qewd/www/route /api will be handled by qx.router

QEWD hasn't fully started yet

It's waiting for a response from the MicroServicemachine on 192.168.1.114:8080

Which, of course, hasn't been started yet

Page 53: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Start Up the Two QEWD Systems

On the QEWD Login MicroService machine:

cd ~/qewdnode loginservice

Page 54: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Look at the QEWD Node Console Log on the MicroService machine

rtweed@ubuntu:~/qewd$ node loginServicewebServerRootPath = /home/rtweed/qewd/www/Worker Bootstrap Module file written to node_modules/ewd-qoper8-worker.js========================================================ewd-qoper8 is up and running. Max worker pool size: 2========================================================QEWD.js is listening on port 8080========================================================** sockets: incoming message received: {"type":"ewd-register","application":"login-micro-service","jwt":true,"socketId":"L7OwOnSiqhr-nAmdAAAA","ipAddress":"::ffff:192.168.1.119"}no available workerssent qoper8-start message to 30140process.argv[2] = qewd.workerworkerModule: qewd; workerSession Garbage Collector has started in worker 30140Tue, 22 Aug 2017 09:47:46 GMT; master process received response from worker 30140: {"type":"workerProcessStarted","ok":30140}new worker 30140 started and ready so process queue againTue, 22 Aug 2017 09:47:46 GMT; worker 30140 received message: {"type":"ewd-register","application":"login-micro-service","jwt":true,"socketId":"L7OwOnSiqhr-nAmdAAAA","ipAddress":"::ffff:192.168.1.119"}Tue, 22 Aug 2017 09:47:46 GMT; master process received response from worker 30140: {"type":"ewd-register","finished":true,"message":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDMzOTU1NjYsImlhdCI6MTUwMzM5NTI2NiwiaXNzIjoicWV3ZC5qd3QiLCJhcHBsaWNhdGlvbiI6ImxvZ2luLW1pY3JvLXNlcnZpY2UiLCJ0aW1lb3V0IjozMDAsInFld2QiOiJmZTc0U5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.DsDntCU3x2w21K3vmK3iaJd1kOhIj_Rl9h10469qXu4"}}*** handleMessage response {"type":"ewd-register","finished":true,"message":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ehOTE0OGQ4Nzg1N2ZiZWM5Nzk2YTc4MmYwYmRmMmY0MjFlZTZjNTdjZDUyMjE4ZjA1MTcxNGUxMTViNGJhMjU2OGEzNjQyZGM0NWNhZjljYjgwMjM2ZjM0M2Q0OWIwMmE4MzU5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.DsDntCU3x2w21K3vmK3iaJd1kOhIj_Rl9h10469qXu4"}}Response time: 313ms

Page 55: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Look at the QEWD Node Console Log on the MicroService machine

rtweed@ubuntu:~/qewd$ node loginServicewebServerRootPath = /home/rtweed/qewd/www/Worker Bootstrap Module file written to node_modules/ewd-qoper8-worker.js========================================================ewd-qoper8 is up and running. Max worker pool size: 2========================================================QEWD.js is listening on port 8080========================================================** sockets: incoming message received: {"type":"ewd-register","application":"login-micro-service","jwt":true,"socketId":"L7OwOnSiqhr-nAmdAAAA","ipAddress":"::ffff:192.168.1.119"}no available workerssent qoper8-start message to 30140process.argv[2] = qewd.workerworkerModule: qewd; workerSession Garbage Collector has started in worker 30140Tue, 22 Aug 2017 09:47:46 GMT; master process received response from worker 30140: {"type":"workerProcessStarted","ok":30140}new worker 30140 started and ready so process queue againTue, 22 Aug 2017 09:47:46 GMT; worker 30140 received message: {"type":"ewd-register","application":"login-micro-service","jwt":true,"socketId":"L7OwOnSiqhr-nAmdAAAA","ipAddress":"::ffff:192.168.1.119"}Tue, 22 Aug 2017 09:47:46 GMT; master process received response from worker 30140: {"type":"ewd-register","finished":true,"message":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDMzOTU1NjYsImlhdCI6MTUwMzM5NTI2NiwiaXNzIjoicWV3ZC5qd3QiLCJhcHBsaWNhdGlvbiI6ImxvZ2luLW1pY3JvLXNlcnZpY2UiLCJ0aW1lb3V0IjozMDAsInFld2QiOiJmZTc0U5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.DsDntCU3x2w21K3vmK3iaJd1kOhIj_Rl9h10469qXu4"}}*** handleMessage response {"type":"ewd-register","finished":true,"message":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ehOTE0OGQ4Nzg1N2ZiZWM5Nzk2YTc4MmYwYmRmMmY0MjFlZTZjNTdjZDUyMjE4ZjA1MTcxNGUxMTViNGJhMjU2OGEzNjQyZGM0NWNhZjljYjgwMjM2ZjM0M2Q0OWIwMmE4MzU5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.DsDntCU3x2w21K3vmK3iaJd1kOhIj_Rl9h10469qXu4"}}Response time: 313ms

QEWD has fully started

Page 56: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Notice This Activity…Tue, 22 Aug 2017 09:47:46 GMT; worker 30140 received message: {"type":"ewd-register","application":"login-micro-service","jwt":true,"socketId":"L7OwOnSiqhr-nAmdAAAA","ipAddress":"::ffff:192.168.1.119"}Tue, 22 Aug 2017 09:47:46 GMT; master process received response from worker 30140: {"type":"ewd-register","finished":true,"message":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDMzOTU1NjYsImlhdCI6MTUwMzM5NTI2NiwiaXNzIjoicWV3ZC5qd3QiLCJhcHBsaWNhdGlvbiI6ImxvZ2luLW1pY3JvLXNlcnZpY2UiLCJ0aW1lb3V0IjozMDAsInFld2QiOiJmZTc0NjBhM2ZjOGFmMWY5YjhlMWY1MWQ2M2FmYjQ3YTU5M2JkZDczYjNhOTE0OGQ4Nzg1N2ZiZWM5Nzk2YTc4MmYwYmRmMmY0MjFlZTZjNTdjZDUyMjE4ZjA1MTcxNGUxMTViNGJhMjU2OGEzNjQyZGM0NWNhZjljYjgwMjM2ZjM0M2Q0OWIwMmE4MzU5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.DsDntCU3x2w21K3vmK3iaJd1kOhIj_Rl9h10469qXu4"}}*** handleMessage response {"type":"ewd-register","finished":true,"message":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDMzOTU1NjYsImlhdCI6MTUwMzM5NTI2NiwiaXNzIjoicWV3ZC5qd3QiLCJhcHBsaWNhdGlvbiI6ImxvZ2luLW1pY3JvLXNlcnZpY2UiLCJ0aW1lb3V0IjozMDAsInFld2QiOiJmZTc0NjBhM2ZjOGFmMWY5YjhlMWY1MWQ2M2FmYjQ3YTU5M2JkZDczYjNhOTE0OGQ4Nzg1N2ZiZWM5Nzk2YTc4MmYwYmRmMmY0MjFlZTZjNTdjZDUyMjE4ZjA1MTcxNGUxMTViNGJhMjU2OGEzNjQyZGM0NWNhZjljYjgwMjM2ZjM0M2Q0OWIwMmE4MzU5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.DsDntCU3x2w21K3vmK3iaJd1kOhIj_Rl9h10469qXu4"}}Response time: 313ms

Page 57: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

What Happened?

• When the QEWD MicroService machine started, the primary machine was able to establish a WebSocket connection to it

• It then registered the login-micro-service application on the QEWD MicroService machine, using a JWT

Page 58: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Now look at the Primary QEWD Machine's Console Log

rtweed@ubuntu:~/qewd$ node microservicesSetting up micro-service connectionsAdding MicroService Client connection: url = http://192.168.1.114:8080; application = login-micro-servicestarting microService connection to http://192.168.1.114:8080webServerRootPath = /home/rtweed/qewd/www/route /api will be handled by qx.routerlogin-micro-service registeredhttp://192.168.1.114:8080 micro-service readyWorker Bootstrap Module file written to node_modules/ewd-qoper8-worker.js========================================================ewd-qoper8 is up and running. Max worker pool size: 2========================================================QEWD.js is listening on port 8080========================================================

Connection was established to the Login MicroServiceQEWD system, and the login-micro-service applicationwas registered

Page 59: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Now look at the Primary QEWD Machine's Console Log

rtweed@ubuntu:~/qewd$ node microservicesSetting up micro-service connectionsAdding MicroService Client connection: url = http://192.168.1.114:8080; application = login-micro-servicestarting microService connection to http://192.168.1.114:8080webServerRootPath = /home/rtweed/qewd/www/route /api will be handled by qx.routerlogin-micro-service registeredhttp://192.168.1.114:8080 micro-service readyWorker Bootstrap Module file written to node_modules/ewd-qoper8-worker.js========================================================ewd-qoper8 is up and running. Max worker pool size: 2========================================================QEWD.js is listening on port 8080========================================================

So QEWD has now fully started

Both QEWD systems are ready!

Page 60: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Startup Sequence Doesn't Matter

• You can try stopping both QEWD systems (just CTRL & C each of them)

• Restart the Login MicroService QEWD system first– It will start up fully and wait for incoming requests

• Then start the primary QEWD system– It will connect to the Login MicroService QEWD

machine immediately– You'll see the Login machine receive the registration

request– The primary machine will then start QEWD

Page 61: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

You can shut down and restart either server

• You can try stopping and restarting either QEWD system

• After a brief pause, you'll see the two servers re-communicating and re-registering

Page 62: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Ready to test the /api/login request

• Use a REST Client

• POST the /api/login request to the primary QEWD server

Page 63: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Try POST /api/login

Page 64: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Try POST /api/login

Not surprising – we haven't yet written a handlerFor the login-micro-service application to handleThis request on the MicroService machine…..but...

Page 65: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Look at the Console Log for both machines

• You'll see that they both burst into life

Page 66: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Primary Machine

sent: {"application":"login-micro-service","type":"restRequest","path":"/api/login","pathTemplate":"/api/login","method":"POST","headers":{"host":"192.168.1.119:8080","content-length":"41","content-type":"application/json"},"params":{"type":"login"},"query":{},"body":{"username":"rob","password":"secret"},"ip":"::ffff:192.168.1.74","ips":[],"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDMzOTk1NzMsImlhdCI6MTUwMzM5OTI3MywiaXNzIjoicWV3ZC5qd3QiLCJhcHBsaWNhdGlvbiI6ImxvZ2luLW1pY3JvLXNlcnZpY2UiLCJ0aW1lb3V0IjozMDAsInFld2QiOiJmZTc0NjBhM2ZjOGFmMWY5YjhlMWY1MWQ2MzhlZWM1OTZiMmJlYzU1YTI5MTRlODljNThmNTE4YTgwNzk2YTc4MmYwYmRmMmY0MjFlZTZjNTdjZDUyMjE4ZjA1MTcxNGUxMTViNGJhMjU2OGEzNjQyZGM0NWNhZjljYjgwMjM2ZjM0M2Q0OWIwMmE4MzU5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.Re4a6cEmIzQ9PFhwwYsoQ-UtMBKHkTPSpAk55FCDyV8","args":{},"jwt":true}

received: {"type":"restRequest","finished":true,"message":{"error":"Unable to load handler module for: login-micro-service","reason":{"code":"MODULE_NOT_FOUND"}},"responseTime":"14ms"}

Page 67: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login MicroService MachineTue, 22 Aug 2017 10:54:33 GMT; worker 30188 received message: {"application":"login-micro-service","type":"restRequest","path":"/api/login","pathTemplate":"/api/login","method":"POST","headers":{"host":"192.168.1.119:8080","content-length":"41","content-type":"application/json"},"params":{"type":"login"},"query":{},"body":{"username":"rob","password":"secret"},"ip":"::ffff:192.168.1.74","ips":[],"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDMzOTk1NzMsImlhdCI6MTUwMzM5OTI3MywiaXNzIjoicWV3ZC5qd3QiLCJhcHBsaWNhdGlvbiI6ImxvZ2luLW1pY3JvLXNlcnZpY2UiLCJ0aW1lb3V0IjozMDAsInFld2QiOiJmZTc0NjBhM2ZjOGFmMWY5YjhlMWY1MWQ2MzhlZWM1OTZiMmJlYzU1YTI5MTRlODljNThmNTE4YTgwNzk2YTc4MmYwYmRmMmY0MjFlZTZjNTdjZDUyMjE4ZjA1MTcxNGUxMTViNGJhMjU2OGEzNjQyZGM0NWNhZjljYjgwMjM2ZjM0M2Q0OWIwMmE4MzU5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.Re4a6cEmIzQ9PFhwwYsoQ-UtMBKHkTPSpAk55FCDyV8","args":{},"jwt":true}Unable to load handler module for: login-micro-service: Error: Cannot find module 'login-micro-service'Tue, 22 Aug 2017 10:54:33 GMT; master process received response from worker 30188: {"type":"restRequest","finished":true,"message":{"error":"Unable to load handler module for: login-micro-service","reason":{"code":"MODULE_NOT_FOUND"}}}*** handleMessage response {"type":"restRequest","finished":true,"message":{"error":"Unable to load handler module for: login-micro-service","reason":{"code":"MODULE_NOT_FOUND"}}}

Page 68: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login MicroService MachineTue, 22 Aug 2017 10:54:33 GMT; worker 30188 received message: {"application":"login-micro-service","type":"restRequest","path":"/api/login","pathTemplate":"/api/login","method":"POST","headers":{"host":"192.168.1.119:8080","content-length":"41","content-type":"application/json"},"params":{"type":"login"},"query":{},"body":{"username":"rob","password":"secret"},"ip":"::ffff:192.168.1.74","ips":[],"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDMzOTk1NzMsImlhdCI6MTUwMzM5OTI3MywiaXNzIjoicWV3ZC5qd3QiLCJhcHBsaWNhdGlvbiI6ImxvZ2luLW1pY3JvLXNlcnZpY2UiLCJ0aW1lb3V0IjozMDAsInFld2QiOiJmZTc0NjBhM2ZjOGFmMWY5YjhlMWY1MWQ2MzhlZWM1OTZiMmJlYzU1YTI5MTRlODljNThmNTE4YTgwNzk2YTc4MmYwYmRmMmY0MjFlZTZjNTdjZDUyMjE4ZjA1MTcxNGUxMTViNGJhMjU2OGEzNjQyZGM0NWNhZjljYjgwMjM2ZjM0M2Q0OWIwMmE4MzU5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.Re4a6cEmIzQ9PFhwwYsoQ-UtMBKHkTPSpAk55FCDyV8","args":{},"jwt":true}

Page 69: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login MicroService MachineTue, 22 Aug 2017 10:54:33 GMT; worker 30188 received message: {"application":"login-micro-service","type":"restRequest","path":"/api/login","pathTemplate":"/api/login","method":"POST","headers":{"host":"192.168.1.119:8080","content-length":"41","content-type":"application/json"},"params":{"type":"login"},"query":{},"body":{"username":"rob","password":"secret"},"ip":"::ffff:192.168.1.74","ips":[],"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDMzOTk1NzMsImlhdCI6MTUwMzM5OTI3MywiaXNzIjoicWV3ZC5qd3QiLCJhcHBsaWNhdGlvbiI6ImxvZ2luLW1pY3JvLXNlcnZpY2UiLCJ0aW1lb3V0IjozMDAsInFld2QiOiJmZTc0NjBhM2ZjOGFmMWY5YjhlMWY1MWQ2MzhlZWM1OTZiMmJlYzU1YTI5MTRlODljNThmNTE4YTgwNzk2YTc4MmYwYmRmMmY0MjFlZTZjNTdjZDUyMjE4ZjA1MTcxNGUxMTViNGJhMjU2OGEzNjQyZGM0NWNhZjljYjgwMjM2ZjM0M2Q0OWIwMmE4MzU5ZTZhNDRjNGZlNTYyZTM2NGE0ZjJjOTBmOGRjZjc4MzEyODhlZGJkOTE3In0.Re4a6cEmIzQ9PFhwwYsoQ-UtMBKHkTPSpAk55FCDyV8","args":{},"jwt":true}

Page 70: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Incoming WebSocket Message{ "application": "login-micro-service", "type": "restRequest", "path": "/api/login", "pathTemplate": "/api/login", "method": "POST", "headers": { "host": "192.168.1.119:8080", "content-length": "41", "content-type": "application/json" }, "params": { "type": "login" }, "query": {}, "body": { "username": "rob", "password": "secret" }, "ip": "::ffff:192.168.1.74", "ips": [], "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ey...", "args": {}, "jwt": true }

Page 71: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login MicroService MachineUnable to load handler module for: login-micro-service: Error: Cannot find module 'login-micro-service'

Page 72: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login MicroService MachineTue, 22 Aug 2017 10:54:33 GMT;

master process received response from worker 30188: {"type":"restRequest","finished":true,"message":{"error":"Unable to load handler module for: login-micro-service","reason":{"code":"MODULE_NOT_FOUND"}}}*** handleMessage response {"type":"restRequest","finished":true,"message":{"error":"Unable to load handler module for: login-micro-service","reason":{"code":"MODULE_NOT_FOUND"}}}

Page 73: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

So let's add a Login Handler

• On the Login MicroService machine– 192.168.1.114 in our example

– Create a new text file:• ~/qewd/node_modules/login-micro-service.js

Page 74: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Module

• We could write a standard QEWD WebSocket message handler function to deal with the re-packaged incoming message– Here's what it looked like

Page 75: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Incoming WebSocket Message{ "application": "login-micro-service", "type": "restRequest", "path": "/api/login", "pathTemplate": "/api/login", "method": "POST", "headers": { "host": "192.168.1.119:8080", "content-length": "41", "content-type": "application/json" }, "params": { "type": "login" }, "query": {}, "body": { "username": "rob", "password": "secret" }, "ip": "::ffff:192.168.1.74", "ips": [], "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ey...", "args": {}, "jwt": true }

Page 76: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Module

• We could write a standard QEWD WebSocket message handler function to deal with the re-packaged incoming message

• But QEWD provides a set of shortcuts to make it even simpler– And to allow you to define multiple handler

functions based on the original URL paths, using templated paths if you wish

Page 77: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

Page 78: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

First we need to definean init() function in which we'lldefine our URL routes

Page 79: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

Inside this function, we define a routes object for all the routeswe want to handle.

We only have one: POST /api/login

Page 80: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

Inside this function, we define a routes object for all the routeswe want to handle.

We only have one: POST /api/login

And it will invoke a handler functionnamed login() (which we haven'tyet written)

Page 81: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }}; Then we can run this QEWD

API which constructs thehandler function stubs for uswithin the module

Page 82: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

function login(args, finished) { // this will handle the login message}

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

Next we define the login function

Page 83: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

function login(args, finished) { // this will handle the login message}

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

Next we define the login() function

It's the same function interfacethat you use for standardREST route handling

The addMicroServiceHandler()API normalises the interfacefor you

Page 84: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

function login(args, finished) { // this will handle the login message}

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

Next we define the login function

It's the same function interfacethat you use for standardREST route handling

args is an object containing: -req: incoming request object-session: the JWT payload

Page 85: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulevar router = require('qewd-router');var routes;

function login(args, finished) { // this will handle the login message}

module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

Next we define the login function

It's the same function interfacethat you use for standardREST route handling

-finished is the function for returning the response and releasing the worker process

Page 86: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Incoming WebSocket Message{ "application": "login-micro-service", "type": "restRequest", "path": "/api/login", "pathTemplate": "/api/login", "method": "POST", "headers": { "host": "192.168.1.119:8080", "content-length": "41", "content-type": "application/json" }, "params": { "type": "login" }, "query": {}, "body": { "username": "rob", "password": "secret" }, "ip": "::ffff:192.168.1.74", "ips": [], "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ey...", "args": {}, "jwt": true }

We POSTed{"username":"rob","password":"secret"}

So the user login credentialswill be in the message body object

Page 87: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulefunction login( args, finished) { var username = args.req.body.username; var password = args.req.body.password; if (username === 'rob' && password === 'secret') { // valid login credentials } else { // invalid login – return an error }}

We'll just hard-code thevalid credentials for simplicityin this example

Page 88: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulefunction login(args, finished) { var username = args.req.body.username; var password = args.req.body.password; var session = args.session; if (username === 'rob' && password === 'secret') { session.userText = 'Welcome Rob'; session.username = username;

// return success response } else { // invalid login – return an error }}

Update the session objectWith our own data

Page 89: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulefunction login(args, finished) { var username = args.req.body.username; var password = args.req.body.password; var session = args.session; if (username === 'rob' && password === 'secret') { session.userText = 'Welcome Rob'; session.username = username; session.authenticated = true; session.timeout = 1200;

// return success response } else { // invalid login – return an error }}

These are reserved sessionproperties

authenticated helps determinethat the user was properlylogged in

timeout determines the JWTtimeout each time QEWDupdates it

Page 90: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulefunction login(args, finished) { var username = args.req.body.username; var password = args.req.body.password; var session = args.session; if (username === 'rob' && password === 'secret') { session.userText = 'Welcome Rob'; session.username = username; session.authenticated = true; session.timeout = 1200; session.makeSecret('username'); session.makeSecret('authenticated');

// return success response } else { // invalid login – return an error }}

Make these two session propertiessecret. QEWD will encrypt themwithin the JWT so they aren'taccesible or usable by the client.

They will be available, however,for your back-end handler functions

Page 91: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulefunction login(args, finished) { var username = args.req.body.username; var password = args.req.body.password; var session = args.session; if (username === 'rob' && password === 'secret') { session.userText = 'Welcome Rob'; session.username = username; session.authenticated = true; session.timeout = 1200; session.makeSecret('username'); session.makeSecret('authenticated'); finished({ok: true}); } else { // invalid login – return an error }}

Return a success response objectand release the worker process

Page 92: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Login Handler Modulefunction login(args, finished) { var username = args.req.body.username; var password = args.req.body.password; var session = args.session; if (username === 'rob' && password === 'secret') { session.userText = 'Welcome Rob'; session.username = username; session.authenticated = true; session.timeout = 1200; session.makeSecret('username'); session.makeSecret('authenticated'); finished({ok: true}); } else { return finished({error: 'Invalid login'}); }}

Return an error response objectand release the worker process

Page 93: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Save the Login Handler Modulevar router = require('qewd-router');var routes;function login(args, finished) { var username = args.req.body.username; var password = args.req.body.password; var session = args.session; if (username === 'rob' && password === 'secret') { session.userText = 'Welcome Rob'; session.username = username; session.authenticated = true; session.timeout = 1200; session.makeSecret('username'); session.makeSecret('authenticated'); return finished({ok: true}); } else { return finished({error: 'Invalid login'}); }}module.exports = { init: function() { routes = { '/api/login': { POST: login } }; router.addMicroServiceHandler(routes, module.exports); }};

~/qewd/node_modules/login-micro-service.js

Page 94: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Restart the QEWD on the Login machine and re-try POST /api/login

Now it works!

Page 95: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Restart the QEWD on the Login machine and re-try POST /api/login

Notice that although we just asked to return {ok: true},it's returned an updated JWT also

Page 96: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Let's decode that JWT

Page 97: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Let's decode that JWT

Here are the non-secret properties we set in thelogin() function

Page 98: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Let's decode that JWT

The secret ones are encrypted into this claim

Page 99: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Try an invalid POST /api/login request

Notice that although we just asked to return {ok: true},it's returned an updated JWT also

Page 100: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Try an invalid POST /api/login request

There's the error messageWe created in the login()function

Page 101: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Try an invalid POST /api/login request

Note that when an error isreported, the JWT is notupdated

Page 102: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

We now have a working MicroService!

Page 103: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

We now have a working MicroService

• Let's now add a local API to the primary QEWD system– that can't be run until the user has logged in

via the Login MicroService

Page 104: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Already Have a Local Route Defined

• Look in the Startup file and you'll see it also contains a route for locally processing all incoming REST requests starting /api:

var routes = [ { path: '/api', module: 'myRestService', errors: { notfound: { text: 'Resource Not Recognised', statusCode: 404 } } }];

Page 105: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Already Have a Local Route Defined

• Look in the Startup file and you'll see it also contains a route for locally processing all incoming REST requests starting /api:

var routes = [ { path: '/api', module: 'myRestService', errors: { notfound: { text: 'Resource Not Recognised', statusCode: 404 } } }];

All /api requests other than /api/login willbe handled locally by the myRestServiceWorker process Handler module

Page 106: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Already Have a Local Route Defined

• Look in the Startup file and you'll see it also contains a route for locally processing all incoming REST requests starting /api:

var routes = [ { path: '/api', module: 'myLocalServices', errors: { notfound: { text: 'Resource Not Recognised', statusCode: 404 } } }];

Let's change the name of thehandler module tomyLocalServices, to avoidconfusion

Page 107: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler ModuleOn the primary QEWD machine:

~/qewd/node_modules/myLocalServices.js

var router = require('qewd-router');var routes;module.exports = { restModule: true,

init: function() { },

beforeHandler: function(req, finished) { }};

Page 108: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Modulevar router = require('qewd-router');var routes;module.exports = { restModule: true,

init: function() { routes = [ { url: '/api/info', method: 'GET', handler: info } ] routes = router.initialise(routes, module.exports); },

beforeHandler: function(req, finished) { }};

Define a route to be handled

GET /api/info will be handled bya function named info()

Page 109: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Modulevar router = require('qewd-router');var routes;module.exports = { restModule: true,

init: function() { routes = [ { url: '/api/info', method: 'GET', handler: info } ] routes = router.initialise(routes, module.exports); },

beforeHandler: function(req, finished) { }};

Tell QEWD to set up theHandler function stubsAutomatically within themodule

Page 110: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Modulevar router = require('qewd-router');var routes;module.exports = { restModule: true,

init: function() { routes = [ { url: '/api/info', method: 'GET', handler: info } ] routes = router.initialise(routes, module.exports); },

beforeHandler: function(req, finished) { }};

The beforeHandler() functionwill be invoked for every incoming/api request

We'll use this to confirm that theuser has logged in before allowingthe incoming request to be handled

Page 111: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module beforeHandler: function(req, finished) { // invoked for every incoming request, // before the route-specific handler }

If the beforeHandler() function returns false,then the route-specific handler won't getcalled.

Any other return value (including undefined) will allow the route-specifichandler to run

Page 112: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module beforeHandler: function(req, finished) { return this.jwt.handlers.validateRestRequest.call(this, req, finished); }

Add this code inside thebeforeHandler() function

Page 113: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module beforeHandler: function(req, finished) { return this.jwt.handlers.validateRestRequest.call(this, req, finished); }

Use this built-in API to extract, validate anddecrypt the incoming JWT in the request'sAuthorization header

All incoming requests will now need to have aValid JWT, otherwise they'll be rejected

Page 114: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module beforeHandler: function(req, finished) { return this.jwt.handlers.validateRestRequest.call(this, req, finished); }

Returns an error, releases the worker processand ceases any further handling of the request if:

-No Authorization Header was found-No JWT was found in the Authorization Header-The JWT signature wasn't valid-The JWT had expired

Page 115: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module beforeHandler: function(req, finished) { return this.jwt.handlers.validateRestRequest.call(this, req, finished); }

Returns an error, releases the worker processand ceases any further handling of the request if:

-No Authorization Header was found-No JWT was found in the Authorization Header-The JWT signature wasn't valid-The JWT had expired

Otherwise, adds the extracted, decrypted payloadto the request as a Session object, and allows theroute-specific handler to be invoked

Page 116: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Modulevar router = require('qewd-router');var routes;

function info(args, finished) {}

module.exports = { restModule: true,

init: function() { routes = [ { url: '/api/info', method: 'GET', handler: info } ] routes = router.initialise(routes, module.exports); },

beforeHandler: function(req, finished) { //... etc }};

Now we'll add the info() function

Page 117: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module

function info(args, finished) { args.session.ranInfoAt = Date.now(); var username = args.session.username; console.log('*** info args: ' + JSON.stringify(args, null, 2)); var jwt = this.jwt.handlers.setJWT.call(this, args.session);

finished({ info: { server: 'ubuntu119', loggedInAs: username, arch: process.arch, platform: process.platform, versions: process.versions, memory: process.memoryUsage() }, token: jwt });}

Add this code inside the info()function

Page 118: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module

function info(args, finished) { args.session.ranInfoAt = Date.now(); var username = args.session.username; console.log('*** info args: ' + JSON.stringify(args, null, 2)); var jwt = this.jwt.handlers.setJWT.call(this, args.session);

finished({ info: { server: 'ubuntu119', loggedInAs: username, arch: process.arch, platform: process.platform, versions: process.versions, memory: process.memoryUsage() }, token: jwt });}

By the time the info() handler functionruns, the Session object has been made available as args.session.

We'll add a new property to the Session:-ranInfoAt which is the time when the function was run

Page 119: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module

function info(args, finished) { args.session.ranInfoAt = Date.now(); var username = args.session.username; console.log('*** info args: ' + JSON.stringify(args, null, 2)); var jwt = this.jwt.handlers.setJWT.call(this, args.session);

finished({ info: { server: 'ubuntu119', loggedInAs: username, arch: process.arch, platform: process.platform, versions: process.versions, memory: process.memoryUsage() }, token: jwt });}

username was specified as a private JWT/Session value bythe Login MicroService. However, our handler function can accessit because this server has thesame JWT Secret

Page 120: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module

function info(args, finished) { args.session.ranInfoAt = Date.now(); var username = args.session.username; console.log('*** info args: ' + JSON.stringify(args, null, 2)); var jwt = this.jwt.handlers.setJWT.call(this, args.session);

finished({ info: { server: 'ubuntu119', loggedInAs: username, arch: process.arch, platform: process.platform, versions: process.versions, memory: process.memoryUsage() }, token: jwt });}

You'll be able to see the decrypted, unpacked JWT payload displayedin the Node.js Console log

Page 121: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module

function info(args, finished) { args.session.ranInfoAt = Date.now(); var username = args.session.username; console.log('*** info args: ' + JSON.stringify(args, null, 2)); var jwt = this.jwt.handlers.setJWT.call(this, args.session);

finished({ info: { server: 'ubuntu119', loggedInAs: username, arch: process.arch, platform: process.platform, versions: process.versions, memory: process.memoryUsage() }, token: jwt });}

We'll create a new JWT fromthe updated Session contents

This will also update the JWT'sexpiry time

Page 122: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module

function info(args, finished) { args.session.ranInfoAt = Date.now(); var username = args.session.username; console.log('*** info args: ' + JSON.stringify(args, null, 2)); var jwt = this.jwt.handlers.setJWT.call(this, args.session);

finished({ info: { server: 'ubuntu119', loggedInAs: username, arch: process.arch, platform: process.platform, versions: process.versions, memory: process.memoryUsage() }, token: jwt });}

We'll return some items of Information about the server

We'll also display the username(which was a secret claim inThe JWT)

Page 123: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module

function info(args, finished) { args.session.ranInfoAt = Date.now(); var username = args.session.username; console.log('*** info args: ' + JSON.stringify(args, null, 2)); var jwt = this.jwt.handlers.setJWT.call(this, args.session);

finished({ info: { server: 'ubuntu119', loggedInAs: username, arch: process.arch, platform: process.platform, versions: process.versions, memory: process.memoryUsage() }, token: jwt });}

And finally we'll also returnthe updated JWT

The Worker process willthen be released

Page 124: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Create a new Handler Module

function info(args, finished) { args.session.ranInfoAt = Date.now(); var username = args.session.username; console.log('*** info args: ' + JSON.stringify(args, null, 2)); var jwt = this.jwt.handlers.setJWT.call(this, args.session);

finished({ info: { server: 'ubuntu119', loggedInAs: username, arch: process.arch, platform: process.platform, versions: process.versions, memory: process.memoryUsage() }, token: jwt });}

Save as ~/qewd/node_modules/myLocalServices.js

Page 125: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Restart the Primary QEWD System and Try the GET /api/info request

Page 126: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add an invalid Authorization Header

Page 127: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Add an invalid JWT

Page 128: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Now Login using the Login MicroService

Note: Make sure you remove the Authorization Header!

Page 129: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Successful Login

Page 130: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Paste the JWT into the Authorization Header and try GET /api/info request again

Page 131: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Success!

Page 132: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Check the Node.js Console Logs

• When you run the POST /api/login request, you'll see activity on both servers– Request passed to Login MicroService and

response returned to primary QEWD server

Page 133: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Check the Node.js Console Logs

• When you run the GET /api/info request, there's only activity on the primary QEWD Server as it's handled locally– But it's only allowing the request to be

handled locally if the JWT from the Login MicroService is present

Page 134: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Adding More Local Routes

• You can add as many additional local routes as you want to the primary QEWD server's Worker Process handler module

• The beforeHandler() function will be automatically invoked before any of them are handled, so all will be authenticated

• Each one should follow the pattern we used for the /api/info route definition and info() function

Page 135: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

QEWD MicroServices

• You should now have all the information you need to build a set of MicroServices using QEWD systems

Page 136: EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js

Copyright © 2016 M/Gateway Developments Ltd

Advanced QEWD MicroServices

• In the next Part of this course, we'll look at the advanced MicroServices features of QEWD, including:– Variables within URL Routes– Dynamic path-defined destinations

– Federated composite MicroServices from a group of destinations

– Re-direction of MicroService responses to another MicroService

– Chained MicroServices