1.1.2 • Published 4 years ago

@mangar2/messageservice v1.1.2

Weekly downloads
6
License
LGPL-3.0-or-later
Repository
github
Last release
4 years ago

Abstract

Main program, service to store messages and provide a rest api to access to stored messages an the message hierarchy This service is implemented by connecting the mqttclient and the messagestore to a new service

Meta

Filemessageservice.js
AuthorVolker Böhm
CopyrightCopyright ( c ) 2020 Volker Böhm
LicenseThis software is licensed under the GNU LESSER GENERAL PUBLIC LICENSE Version 3 . It is furnished "as is" , without any support , and with no warranty , express or implied , as to its usefulness for any purpose .

Installation

Install all yaha services in one directory with a central yahaconfig.json file. Use a tool like ps2 to manage multiple services

npm i @mangar2/messageservice

Configuration example

You need to provide a file called "yahaconfig.json" in the installation root. This configuration file is designed to contain configuration for multiple services and for multiple environments ('development', 'test', 'staging', 'production') All configuration parameters have default values. You do not have to provide parameter.

// Example for a yahaconfig
{
    "production": {
        "messageService": {
            "clientId": "yaha/external",
            "version": "1.0",
            "clean": true,
            "broker": {
                "port": 8183,
                "host": "192.168.0.4"
            },
            "listener": 8202,
            "keepAliveInSeconds": 600,
            "subscriptions": {
                "#": 1,
                "$SYS/#": 1
            },
            "log": [
            ]
        },
        "messageStore": {
            "persist" : {
                "keepFiles": 5,
                "directory": "C:\\NodeJs\\data",
                "filename": "messages",
                "interval": 60000
            },
            "server": {
                "port": 8203,
                "path": "sensor"
            },
            "tree": {
                "maxHistoryLength": 20,
                "maxValuesLength": 32,
                "historyHysterese": 10,
                "upperBoundFactor": 1.2,
                "upperBoundAddInMilliseconds": 1000,
                "lowerBoundFactor": 0.8,
                "lowerBoundSubInMilliseconds": 1000
            }
        }
    }
}
  • clientId name of the client, must be unique across all services
  • version version of the interface (0.0 or 1.0)
  • clean true, if the broker shall cleanup all messages on disconnect, false to buffer messages until the service is up again.
  • broker information to connect to the broker
  • listener port number to listen for broker messages, you may set any free port you like
  • keepAliveInSeconds time between keep alive calls to the broker (usually pings)
  • subscriptions messages that are subscribed and thus stores. Here all messages (the '#' is an MQTT wildchard and the special '$SYS/#' messages) are substribed. Please note that # matches all messages but $SYS messages, see MQTT documentation for details
  • log settings to log incoming messages to the console

JSON Schema for messageservice

const MessageServiceJSONSchema = {
    properties: {
        clientId: {
            description: 'Unique identifier of the client',
            type: 'string'
        },
        version: {
            description: 'The version of the interface, use "1.0", "0.0" is deprecated',
            enum: ['0.0', '1.0']
        },
        clean: {
            description: 'Clean services are removed from the broker memory if disconnected',
            type: 'boolean'
        },
        broker: {
            description: 'Broker connection information',
            $ref: '#broker'
        },
        listener: {
            description: 'Port to listen for Broker messages',
            type: ['string', 'number']
        },
        keepAliveInSeconds: {
            description: 'Interval between alive messages sent to the Broker',
            type: 'number'
        },
        log: {
            description: 'Initial logging settings',
            $ref: '#log'
        },
        subscriptions: {
            description: 'Subscriptions of the service, ',
            type: 'object',
            additionalProperties: {
                description: 'Property name is the topic and QoS is its value',
                enum: ['0', '1', '2'],
                minProperties: 1
            }
        },
        required: ['clientId', 'version', 'clean', 'broker', 'listener', 'keepAliveInSeconds', 'log', 'subscriptions'],
        additionalProperties: false
    },
    $defs: {
        broker: {
            $id: '#broker',
            type: 'object',
            properties: {
                port: {
                    description: 'The port the broker listens on',
                    type: ['string', 'number']
                },
                host: {
                    description: 'The host ip or host name of the broker',
                    type: 'string'
                }
            },
            required: ['port', 'host'],
            additionalProperties: false
        },
        log: {
            $id: '#log',
            type: 'array',
            items: {
                type: 'object',
                properties: {
                    module: { enum: ['all', 'send', 'receive'] },
                    topic: { type: '#' },
                    level: { type: 'integer' }
                },
                required: ['module', 'topic'],
                additionalProperties: false
            }
        }
    }
}

JSON Schema for message store

const MessageStoreJSONSchema = {
    title: 'Messagestore configuration',
    type: 'object',
    properties: {
        persist: {
            type: 'object',
            properties: {
                keepFiles: {
                    description: 'Amount of files to keep',
                    type: 'integer'
                },
                directory: {
                    description: 'Directory to store the persistence files',
                    type: 'string'
                },
                filename: {
                    description: 'Filename to store presistence data',
                    type: 'string'
                },
                interval: {
                    description: 'Interval in milliseconds to store the internal state to disk',
                    type: 'integer'
                }
            },
            additionalProperties: false,
            required: ['keepFiles', 'directory', 'filename', 'interval']
        },
        server: {
            type: 'object',
            properties: {
                port: {
                    description: 'Port providing the sensor information service for the user interface',
                    type: ['integer', 'string']
                },
                path: {
                    description: 'Root path for the sensor information service',
                    type: 'string'
                }
            },
            additionalProperties: false,
            required: ['port', 'path']
        },
        tree: {
            type: 'object',
            properties: {
                maxHistoryLength: {
                    description: 'Maximal length of the history before older entries will be removed',
                    type: 'integer'
                },
                historyHysterese: {
                    description: 'Amount of elements to remove every time the history is shrinked',
                    type: 'integer'
                },
                maxValuesPerHistoryEntry: {
                    description: 'Maximal amount of entries in a history entry',
                    type: 'integer'
                },
                lengthForFurtherCompression: {
                    description: 'Amount of elements in a history entry when trying additional compression',
                    type: 'integer'
                },
                upperBoundFactor: {
                    description: 'Multiplication factor to calculate the upper bound for an interval timespan',
                    type: 'number'
                },
                upperBoundAddInMilliseconds: {
                    description: 'Time in milliseconds to add to the upper bound of an interval timespan',
                    type: 'integer'
                },
                lowerBoundFactor: {
                    description: 'Multiplication factor to calculate the lower bound for an interval timespan',
                    type: 'number'
                },
                lowerBoundSubInMilliseconds: {
                    description: 'Time in milliseconds to subtract from the lower bound of an interval timespan',
                    type: 'integer'
                }
            },
            additionalProperties: false,
            required: [
                'maxHistoryLength', 'historyHysterese', 'maxValuesPerHistoryEntry', 'lengthForFurtherCompression',
                'upperBoundFactor', 'upperBoundAddInMilliseconds', 'lowerBoundFactor', 'lowerBoundSubInMilliseconds'
            ]
        }
    },
    additionalProperties: false,
    required: ['persist', 'server', 'tree']
}