Skip to content

A package that helps to easly create clients in a JANIS Service

Notifications You must be signed in to change notification settings

janis-commerce/client-creator

Repository files navigation

client-creator

Build Status Coverage Status npm version

Introduction

This package includes all the generic functionality to create, update and remove a client from the services. Its main purpose is to avoid code repetition.

📥 Installation

npm install @janiscommerce/client-creator

🛠️ Configuration

AWS Parameter Store

Since 7.1.0 Retrieves database configurations for clients directly from AWS Parameter Store {process.env.JANIS_SERVICE_NAME}-databases and store configuration in db new field

Parameter Store expected parsed content

{
  "newClientsDatabases": {
    "default": "6728b0de39a492eee4fcdaa8"
  }
}

Client created

{
  "code": "client-code",
  "db": {
    "default": {
      "id": "6728b0de39a492eee4fcdaa8",
      "database": "service-name-client-code"
    }
  },
  "status": "active"
}

⚠️ The client models will be dispatched using @janiscommerce/model@^8.8.0

Service Settings ⚠️ Deprecated

You should configure the database config in your service for the new clients using the package Settings and the newClientsDatabases field

.janiscommercerc.json

{
  "newClientsDatabases": {
    "default": { // DB config that the new clients will use
      "type": "mongodb",
      "database": "janis-{{code}}" // necessary to add dynamic database name. Since 3.0.0
    },
    "other-database": {
      "write": {
        "type": "solr",
        "database": "core-{{code}}"
      },
      "read": {
        "type": "solr",
        "host": "host-read-solr",
        "database": "core-{{code}}"
      }
    }
  }
}

If we create a brand-new-client client with the previous settings, we will get the following client

{
  "code": "brand-new-client",
  "databases": {
    "default": {
      "write": {
        "type": "mongodb",
        "database": "janis-brand-new-client"
      }
    },
    "other-database": {
      "write": {
        "type": "solr",
        "database": "core-brand-new-client"
      },
      "read": {
        "type": "solr",
        "database": "core-brand-new-client"
      }
    }
  },
  "status": "active"
}

🔑 Secrets ⚠️ Deprecated

The package will get the secret using the JANIS_SERVICE_NAME environment variable. If the secret was found, the result will be merged with the settings found in the janiscommercerc.json in the newClientsDatabases field.

The Secrets are stored in AWS Secrets Manager and obtained with the package @janiscommerce/aws-secrets-manager

Complete example in which the settings are obtained in the settings file and merged with the fetched credentials in AWS Secrets Manager.

In the example will be used a new client brand-new-client.

  1. Settings in file.
{
  "newClientsDatabases": {
    "default": {
      "type": "mongodb",
      "database": "janis-{{code}}"
    }
  }
}
  1. Secret fetched.
{
	"databases": {
    "default": {
      "write": {
        "host": "mongodb+srv://some-host.mongodb.net",
        "user": "secure-user",
        "password": "secure-password",
      }
    }
	}
}
  1. Settings merged after fetching the Secret
{
	"default": {
		"write": {
			"type": "mongodb",
			"database": "janis-brand-new-client",
			"host": "mongodb+srv://some-host.mongodb.net",
			"user": "secure-user",
			"password": "secure-password",
		}
	}
}

Skip Credential Fetching ⚠️ Deprecated

To skip the fetch of the credentials, it can be used the setting skipFetchCredentials set as true.

{
  "newClientsDatabases": {
    "default": {
      "write": {
        "type": "mongodb",
        "skipFetchCredentials": true,
        "protocol": "mongodb+srv://",
        "host": "mongodb+srv://some-host.mongodb.net",
        "user": "some-user",
        "password": "insecure-password"
      }
    }
  }
}

ClientModel

At ./[MS_PATH]/models/client.js

'use strict';

const { ModelClient } = require('@janiscommerce/client-creator');

module.exports = ModelClient;

✨🆕✨ Additional Fields Additional fields is a getter that allows the service to customize the clients fields, this is useful when a service needs their own custom data in clients.

ℹ️ This will affect Client Create API and also Client Updated Event behavior

When a client is created or modified, the current client will be obtained from ID service and only the additional fields that exist in the getter will be saved in the service along with the basic client fields.

Examples using additionalFields()

Model configuration

'use strict';

const { ModelClient } = require('@janiscommerce/client-creator');

module.exports = class MyModelClient extends ModelClient {

  static get additionalFields() {
    return [
      'myAdditionalField',
      'anotherAdditionalField'
    ]
  }
};

If a new client is created with these additional fields:

{
  "name": "Some Client",
  "code": "some-client",
  "myAdditionalField": "some-additional-data",
  "anotherAdditionalField": "another-additional-data",
  "unusedAdditionalField": "unused-data"
}

The client will be saved in the service with only the specified additional fields:

{
  "name": "Some Client",
  "code": "some-client",
  "myAdditionalField": "some-additional-data",
  "anotherAdditionalField": "another-additional-data"
}

APICreate

This Api will create new clients received in clients parameter.

Parameters:

  • clients string Array: The clients codes to be created. optional
  • processClients boolean: If received as true will compare Service clients with Janis ID clients and create, update or remove clients when needed. optional

File location ./[MS_PATH]/api/client/post.js

Basic version

'use strict';

const { APICreate } = require('@janiscommerce/client-creator');

module.exports = APICreate;

postSaveHook(clientCodes, clients)

Receives the clientCodes and clients from the API.

Parameters:

  • clientCodes string Array: The client created codes.
  • clients object Array: The clients created objects that were saved.

ℹ️ This hook is used when received clients or processClients (when need to create)

Example using ApiCreate postSaveHook()
'use strict';

const { APICreate } = require('@janiscommerce/client-creator');

module.exports = class ClientCreateAPI extends APICreate {

  async postSaveHook(clientCodes, clients) {

      await myPostSaveMethod(clientCodes);

      clientCodes.forEach(clientCode => {
          console.log(`Saved client ${clientCode}, now i'm gonna do something great`);
      })

      clients.forEach(({ databases, status }) => {
        console.log(`This epic client has ${databases.length} databases and its status is ${status}`)
      })
    }
};

postUpdateHook(clients)

Hook called after update clients.

ℹ️ This hook is used when received processClients (when no need to create)

Parameters:

  • clients object: The recently updated client.

postRemoveHook(clients)

Hook called after remove clients.

ℹ️ This hook is used when received processClients (when found clients to remove in service)

Parameters:

  • clientsCodes string Array: The recently removed client codes.

ListenerCreated

This listener handles a created event emitted by Janis ID service. It allows to create a new client in the core database and set a new database for him.

File location ./[MS_PATH]/event-listeners/id/client/created.js

Basic version

'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerCreated } = require('@janiscommerce/client-creator');

module.exports.handler = (...args) => ServerlessHandler.handle(ListenerCreated, ...args);

postSaveHook(clientCode, client)

Receives the clientCode and client from the event.

Parameters:

  • clientCode string: The client created code of the created client.
  • client object: The client created object that was saved.
Example using ListenerCreated postSaveHook()
'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerCreated } = require('@janiscommerce/client-creator');

class ClientCreatedListener extends ListenerCreated {

  async postSaveHook(clientCode, client) {
    console.log(`Saved client ${clientCode}, now i'm gonna do something great`);
    console.log(`Saved client has ${client.databases.length} databases! Whoaaa`)
  }
}

module.exports.handler = (...args) => ServerlessHandler.handle(ClientCreatedListener, ...args);

ListenerUpdated

This listener handles an updated event emitted by Janis ID service. It allows to activate or deactivate a client by changing his status.

File location ./[MS_PATH]/event-listeners/id/client/updated.js

Basic version

'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerUpdated } = require('@janiscommerce/client-creator');

module.exports.handler = (...args) => ServerlessHandler.handle(ListenerUpdated, ...args);

postSaveHook(currentClient)

Receives the currentClient from the event.

Parameters:

  • currentClient object: The recently updated client.
Example using ListenerUpdated postSaveHook()
'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerUpdated } = require('@janiscommerce/client-creator');

class ClientUpdatedListener extends ListenerUpdated {

  async postSaveHook(currentClient) {
    console.log(`Saved client ${currentClient.name}, now i'm gonna do something great`);
  }
}

module.exports.handler = (...args) => ServerlessHandler.handle(ClientUpdatedListener, ...args);

ListenerRemoved

This listener handles a removed event emitted by Janis ID service. It allows to remove a client from the core clients database and drop his database.

File location ./[MS_PATH]/event-listeners/id/client/removed.js

Basic version

'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerRemoved } = require('@janiscommerce/client-creator');

module.exports.handler = (...args) => ServerlessHandler.handle(ListenerRemoved, ...args);

postRemovedHook(clientCode)

Receives the removed clientCode from the API.

Parameters:

  • clientCode string: The client removed code.
Example using ListenerRemoved postRemovedHook()
'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerRemoved } = require('@janiscommerce/client-creator');

class ClientRemovedListener extends ListenerRemoved {

  async postRemovedHook(clientCode) {
    console.log(`Saved client ${clientCode}, now i'm gonna do something great`);
  }
}

module.exports.handler = (...args) => ServerlessHandler.handle(ClientRemovedListener, ...args);

Serverless functions

The package exports clientFunctions, an array with serverless functions to simplify the usage. It has the hooks for the Create Api and Listeners.

At ./serverless.js

'use strict';

const { helper } = require('sls-helper'); // eslint-disable-line
const { clientFunctions } = require('@janiscommerce/client-creator');

module.exports = helper({
	hooks: [
		// other hooks
		...clientFunctions
	]
});

Schemas

Add schemas for the Client Created, Updated and Removed event listeners and the Create Client API post. Subscribe to events.

At ./schemas/client/ add these two files:

At ./schemas/event-listeners/id/client add this file:

At ./events/src/id/ add this file:

Tests and coverage

The default Api and Listeners (:warning: without customization) not need to be tested.

To avoid coverage leaks, in ./.nycrc

{
  "exclude": [
    //... other excluded files
    "src/event-listeners/id/client/",
    "src/models/client.js",
    "src/api/client/post.js"
  ]
}

⚠️ If exists any customization of the files, do not add the file to the .nycrc and add the corresponding tests.

About

A package that helps to easly create clients in a JANIS Service

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •