To Introduction

Microservice Facade

Step 7. Running facade

Before we can run our facade, we need to add three more things: a factory for the component’s we’ve created, a container, and the code that will run it all. The process of implementing these pieces is the same as the one described in Data Microservice, so this time around we’ll just list the code:

Create three factories in the src/build/ folder:

One factory for the facade in a file named FacadeFactory.ts, containing the following code:

/src/build/FacadeFactory.ts

import { Factory } from 'pip-services3-components-node';
import { Descriptor } from 'pip-services3-commons-node';

import { FacadeServiceV1 } from '../services/version1/FacadeServiceV1';

export class FacadeFactory extends Factory {
public static FacadeServiceV1Descriptor = new Descriptor("pip-facades-example", "service", "http", "*", "1.0");

    public constructor() {
        super();

        this.registerAsType(FacadeFactory.FacadeServiceV1Descriptor, FacadeServiceV1);
    }
}

Another factory for the facade’s services, placed in a file named ServiceFacadeFactory.ts:

/src/build/ServiceFacadeFactory.ts

import { CompositeFactory } from 'pip-services3-components-node';

import { AccountsServiceFactory } from 'pip-services-accounts-node';
import { SessionsServiceFactory } from 'pip-services-sessions-node';
import { PasswordsServiceFactory } from 'pip-services-passwords-node';
import { RolesServiceFactory } from 'pip-services-roles-node';import { BeaconsServiceFactory } from 'pip-services-beacons-node';

export class ServiceFacadeFactory extends CompositeFactory {
    public constructor() {
        super();

        this.add(new AccountsServiceFactory());
        this.add(new SessionsServiceFactory());
        this.add(new PasswordsServiceFactory());
        this.add(new RolesServiceFactory());
        this.add(new BeaconsServiceFactory());
    }
}

And last but not least, a factory for the clients that that facade depends on in a file named ClientsFacadeFactory.ts:

/src/build/ClientFacadeFactory.ts

import { CompositeFactory } from 'pip-services3-components-node';
import { AccountsClientFactory } from 'pip-clients-accounts-node';
import { ActivitiesClientFactory } from 'pip-clients-activities-node';
import { SessionsClientFactory } from 'pip-clients-sessions-node';
import { PasswordsClientFactory } from 'pip-clients-passwords-node';
import { RolesClientFactory } from 'pip-clients-roles-node';
import { BeaconsClientFactory } from 'pip-clients-beacons-node';
export class ClientFacadeFactory extends CompositeFactory {    
  public constructor() {        
    super();        
    this.add(new AccountsClientFactory());        
    this.add(new ActivitiesClientFactory());        
    this.add(new SessionsClientFactory());        
    this.add(new PasswordsClientFactory());      
   this.add(new RolesClientFactory());        
    this.add(new BeaconsClientFactory());    
  }
}

The container that we want to run our facade in should be implemented in a file named FacadeProcess.ts and placed in the /container folder:

/src/container/FacadeProcess.ts

import { ProcessContainer } from 'pip-services3-container-node';
import { DefaultRpcFactory } from 'pip-services3-rpc-node';
import { DefaultMongoDbFactory } from 'pip-services3-mongodb-node';
import { ClientFacadeFactory } from '../build/ClientFacadeFactory';
import { ServiceFacadeFactory } from '../build/ServiceFacadeFactory';
import { FacadeFactory } from '../build/FacadeFactory';
export class FacadeProcess extends ProcessContainer {
    public constructor() {
        super("pip-facades-example", "Public facade for pip-vault 2.0");
        this._factories.add(new ClientFacadeFactory);
        this._factories.add(new ServiceFacadeFactory);
        this._factories.add(new FacadeFactory);
        this._factories.add(new DefaultRpcFactory);
        this._factories.add(new DefaultMongoDbFactory);
    }
}

For us to be able to run the container, create a run.js file in the /bin folder with the following code:

/bin/run.js

let FacadeProcess = require('../obj/src/container/FacadeProcess').FacadeProcess;
try {
    new FacadeProcess().run(process.argv);
} catch (ex) {
    console.error(ex);
}

Our facade will need to be configured before running, so create a config-distributed.yml file in the /config folder of the project with the following:

/config/config.yml

---
# Container info
- descriptor: "pip-services:container-info:default:default:*"
  name: "pip-facades-example"
  description: "Example Pip.Services facade"

# Console logger
- descriptor: "pip-services:logger:console:default:*"
  level: trace

# Log counters
- descriptor: "pip-services:counters:log:default:*"

# Mongodb connection
- descriptor: "pip-services:connection:mongodb:default:*"
  connection:
    uri: {{{MONGO_SERVICE_URI}}}
    host: {{{MONGO_SERVICE_HOST}}}{{#unless MONGO_SERVICE_HOST}}localhost{{/unless}}
    port: {{MONGO_SERVICE_PORT}}{{#unless MONGO_SERVICE_PORT}}27017{{/unless}}
    database: {{MONGO_DB}}{{#unless MONGO_DB}}app{{/unless}}
  credential:
    username: {{MONGO_USER}}
    password: {{MONGO_PASS}}

# Accounts components
- descriptor: "pip-services-accounts:client:http:default:*"
  connection:
    protocol: "http"
    host: "localhost"
    port: 8082

# Roles components
- descriptor: "pip-services-roles:client:http:default:*"
  connection:
    protocol: "http"
    host: "localhost"
    port: 8083

# Passwords components
- descriptor: "pip-services-passwords:client:http:default:*"
  connection:
    protocol: "http"
    host: "localhost"
    port: 8084

# Session components
- descriptor: "pip-services-sessions:client:http:default:*"
  connection:
    protocol: "http"
    host: "localhost"
    port: 8085

# Beacons components
- descriptor: "pip-services-beacons:client:http:default:*"
  connection:
    protocol: "http"
    host: "localhost"
    port: 8086

# Main facade service
- descriptor: "pip-services:endpoint:http:default:*"
  root_path: ""
  connection:
    protocol: "http"
    host: "0.0.0.0"
    port: 8080
  options:
    debug: true
    maintenance_enabled: false
    max_req_size: "1mb"

# Facade API V1
- descriptor: "pip-facades-example:service:http:default:1.0"

# Hearbeat service
- descriptor: "pip-services:heartbeat-service:http:default:1.0"

# Status service
- descriptor: "pip-services:status-service:http:default:1.0"

For demonstration purposes, we’ll be running our system in a distributed mode, with all of its components running in their own, individual containers. The configuration above is designed specifically for this type of distributed deployment.

The process of running a service in a Docker container is described in detail in the Dockerization tutorial

To run our system using Docker Compose, create a docker-compose.yml file with the following:

/docker/docker-compose.yml

version: '3.3'

services:

  app:
    image: ${IMAGE}
    environment:
      - MAGIC_CODE=magic
      - MONGO_SERVICE_URI=
      - MONGO_SERVICE_HOST=mongo
      - MONGO_SERVICE_PORT=27017
      - MONGO_DB=app
       ports:
      - "8080:8080"
    links:
      - mongo
      - accounts
      - role
      - passwords
      - sessions
      - beacons
      
         command: node /app/bin/run.js -c /app/config/config-distributed.yml

  mongo:
    image: mongo:latest
    ports:
      - "27017:27017"

  accounts:
    image: pipdevs/pip-services-accounts-node:latest
    environment:
      - MONGO_SERVICE_HOST=mongo
      - MONGO_SERVICE_PORT=27017
      - MONGO_DB=accounts
    links:
      - mongo
       ports:
      - "8082:8080"
    role:
    image: pipdevs/pip-services-roles-node:latest
    environment:
      - MONGO_SERVICE_HOST=mongo
      - MONGO_SERVICE_PORT=27017
      - MONGO_DB=roles
    links:
        - mongo
    ports:
      - "8083:8080"

  passwords:
    image: pipdevs/pip-services-passwords-node:1.0.1-12-rc
    environment:
      - MONGO_SERVICE_HOST=mongo
      - MONGO_SERVICE_PORT=27017
      - MONGO_DB=passwd
    links:
        - mongo
    ports:
      - "8084:8080"

  sessions:
    image: pipdevs/pip-services-sessions-node:1.0.1-19-rc
    environment:
      - MONGO_SERVICE_HOST=mongo
      - MONGO_SERVICE_PORT=27017
      - MONGO_DB=sessions
    links:
        - mongo
    ports:
      - "8085:8080"

  beacons:
    image: pipdevs/pip-services-beacons-node:1.0
    environment:
      - MONGO_SERVICE_HOST=mongo
      - MONGO_SERVICE_PORT=27017
      - MONGO_DB=beacons
    links:
        - mongo
    ports:
      - "8086:8080"

Build and run the facade using the respective scripts (described in the Docker tutorial we mentioned above), which can be found in this example project’s repository.

To build the facade’s image and load the rest of the services’ images, run the “package” script using the command below:

.\package.ps1

Once the build process successfully finishes, run the entire system with all of its microservices in Docker Compose using the “run” script. This can be done with the following command:

.\run.ps1

When running the facade, you should see something like this in the console:

app_1        | [pip-facades-example:INFO:2020-07-03T17:05:53.012Z] Press Control-C to stop the microservice...
app_1        | [pip-facades-example:DEBUG:2020-07-03T17:05:53.067Z] Connecting to mongodb
app_1        | [pip-facades-example:DEBUG:2020-07-03T17:05:53.557Z] Connected via REST to http://localhost:8082
app_1        | [pip-facades-example:DEBUG:2020-07-03T17:05:53.562Z] Connected via REST to http://localhost:8083
app_1        | [pip-facades-example:DEBUG:2020-07-03T17:05:53.566Z] Connected via REST to http://localhost:8084
app_1        | [pip-facades-example:DEBUG:2020-07-03T17:05:53.570Z] Connected via REST to http://localhost:8085
app_1        | [pip-facades-example:DEBUG:2020-07-03T17:05:53.573Z] Connected via REST to http://localhost:8086
app_1        | [pip-facades-example:DEBUG:2020-07-03T17:05:53.804Z] Opened REST service at http://0.0.0.0:8080
app_1        | [pip-facades-example:INFO:2020-07-03T17:05:53.805Z] Container pip-facades-example started.

Now we’re ready to move on to manually testing our facade. In Step 8 - Manually testing the facade - we’ll show you how this can be done.