isatdatapro-microservices
Version:
A library for creating microservices to access Inmarsat's IsatData Pro satellite IoT system
603 lines (463 loc) • 24.3 kB
HTML
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<script src="scripts/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/jaguar.css">
<script>
var config = {"monospaceLinks":false,"cleverLinks":true,"default":{}};
</script>
</head>
<body>
<div id="wrap" class="clearfix">
<div class="navigation">
<h3 class="applicationName"><a href="index.html"></a></h3>
<div class="search">
<input id="search" type="text" class="form-control input-sm" placeholder="Search Documentations">
</div>
<ul class="list">
<li class="item" data-name="ApiCallLog">
<span class="title">
<a href="ApiCallLog.html">ApiCallLog</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Field">
<span class="title">
<a href="Field.html">Field</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Mailbox">
<span class="title">
<a href="Mailbox.html">Mailbox</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li data-name="Mailbox#passwordGet"><a href="Mailbox.html#passwordGet">passwordGet</a></li>
<li data-name="Mailbox#passwordSet"><a href="Mailbox.html#passwordSet">passwordSet</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Message">
<span class="title">
<a href="Message.html">Message</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li data-name="Message#getCodecMessageId"><a href="Message.html#getCodecMessageId">getCodecMessageId</a></li>
<li data-name="Message#getCodecServiceId"><a href="Message.html#getCodecServiceId">getCodecServiceId</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="MessageForward">
<span class="title">
<a href="MessageForward.html">MessageForward</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li data-name="MessageForward#getStateName"><a href="MessageForward.html#getStateName">getStateName</a></li>
<li data-name="MessageForward#getStateReason"><a href="MessageForward.html#getStateReason">getStateReason</a></li>
<li data-name="MessageForward#submit"><a href="MessageForward.html#submit">submit</a></li>
<li data-name="MessageForward#updateStatus"><a href="MessageForward.html#updateStatus">updateStatus</a></li>
<li data-name="MessageForward#wakeupPeriodEnum"><a href="MessageForward.html#wakeupPeriodEnum">wakeupPeriodEnum</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="MessageReturn">
<span class="title">
<a href="MessageReturn.html">MessageReturn</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Mobile">
<span class="title">
<a href="Mobile.html">Mobile</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="module:repositories/azureCosmosRepository~DatabaseContext">
<span class="title">
<a href="module-repositories_azureCosmosRepository-DatabaseContext.html">module:repositories/azureCosmosRepository~DatabaseContext</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li data-name="module:repositories/azureCosmosRepository~DatabaseContext#close"><a href="module-repositories_azureCosmosRepository-DatabaseContext.html#close">close</a></li>
<li data-name="module:repositories/azureCosmosRepository~DatabaseContext#delete"><a href="module-repositories_azureCosmosRepository-DatabaseContext.html#delete">delete</a></li>
<li data-name="module:repositories/azureCosmosRepository~DatabaseContext#find"><a href="module-repositories_azureCosmosRepository-DatabaseContext.html#find">find</a></li>
<li data-name="module:repositories/azureCosmosRepository~DatabaseContext#initialize"><a href="module-repositories_azureCosmosRepository-DatabaseContext.html#initialize">initialize</a></li>
<li data-name="module:repositories/azureCosmosRepository~DatabaseContext#upsert"><a href="module-repositories_azureCosmosRepository-DatabaseContext.html#upsert">upsert</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="module:repositories/mysqlRepository~DatabaseContext">
<span class="title">
<a href="module-repositories_mysqlRepository-DatabaseContext.html">module:repositories/mysqlRepository~DatabaseContext</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li data-name="module:repositories/mysqlRepository~DatabaseContext#close"><a href="module-repositories_mysqlRepository-DatabaseContext.html#close">close</a></li>
<li data-name="module:repositories/mysqlRepository~DatabaseContext#delete"><a href="module-repositories_mysqlRepository-DatabaseContext.html#delete">delete</a></li>
<li data-name="module:repositories/mysqlRepository~DatabaseContext#find"><a href="module-repositories_mysqlRepository-DatabaseContext.html#find">find</a></li>
<li data-name="module:repositories/mysqlRepository~DatabaseContext#initialize"><a href="module-repositories_mysqlRepository-DatabaseContext.html#initialize">initialize</a></li>
<li data-name="module:repositories/mysqlRepository~DatabaseContext#upsert"><a href="module-repositories_mysqlRepository-DatabaseContext.html#upsert">upsert</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Payload">
<span class="title">
<a href="Payload.html">Payload</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li data-name="Payload#addField"><a href="Payload.html#addField">addField</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="SatelliteGateway">
<span class="title">
<a href="SatelliteGateway.html">SatelliteGateway</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
</ul>
</div>
<div class="main">
<h1 class="page-title" data-filename="index.html">Index</h1>
<h3> </h3>
<section>
<article class="readme"><h1>isatdatapro-microservices</h1>
<p>This library provides a microservices framework for interacting with Inmarsat's
IsatData Pro satellite IoT messaging service. Messages sent from or to remote
devices via satellite connectivity are stored in a database along with metadata
about the satellite modem configuration and properties. A Node.js singleton
emitter is also supported to publish events such as message delivery, new modems
sending data, and API/server errors.</p>
<p><a target="_blank" href="https://inmarsat.github.io/isatdatapro-microservices/">Documentation</a></p>
<h2>Installation</h2>
<pre class="prettyprint source"><code>npm i isatdatapro-microservices
</code></pre>
<h2>Configuration</h2>
<p>The library relies on the following environment variable settings.</p>
<p>The database particulars are configured as environment variables:</p>
<ul>
<li><strong><code>DB_TYPE</code></strong> supports <code>azureCosmos</code> or <code>mysql</code></li>
</ul>
<p>For <a href="./module-repositories_azureCosmosRepository-DatabaseContext.html">Cosmos DB</a>:</p>
<ul>
<li><strong><code>COSMOS_DB_HOST</code></strong> is the Azure URL for the Cosmos DB</li>
<li><strong><code>COSMOS_DB_PASS</code></strong> is the password for the Cosmos DB</li>
<li><strong><code>COSMOS_DB_NAME</code></strong> is the database name e.g. IsatDataPro</li>
<li><strong><code>COSMOS_DB_CONTAINER</code></strong> is the container name e.g. Main</li>
<li><strong><code>COSMOS_DB_PARTITION</code></strong> is the partition name i.e. <code>category</code></li>
<li><strong><code>COSMOS_DB_THROUGHPUT</code></strong> is the default throughput e.g. 400</li>
</ul>
<p>For <a href="./module-repositories_mysqlRepository-DatabaseContext.html">MySQL</a>:</p>
<ul>
<li><strong><code>MYSQL_DB_HOST</code></strong> is the MySQL host name e.g. localhost</li>
<li><strong><code>MYSQL_DB_USER</code></strong> is the access name e.g. root</li>
<li><strong><code>MYSQL_DB_PASS</code></strong> is the password</li>
<li><strong><code>MYSQL_DB_NAME</code></strong> is the name of the database e.g. IsatDataPro</li>
</ul>
<p>Encryption of Mailbox passwords uses a secret defined in an environment variable:</p>
<ul>
<li><strong><code>MAILBOX_SECRET</code></strong> is a string used as the encryption key</li>
</ul>
<p>The following environment variables are optional with defaults in the code:</p>
<ul>
<li><strong><code>SATELLITE_HISTORY_HOURS=48</code></strong> the number of hours to go back on first API
call for message/status retrieval</li>
<li><strong><code>DB_TTL_DAYS_API=7</code></strong> time to live for ApiCallLog entries in database</li>
<li><strong><code>DB_TTL_DAYS_MSG=90</code></strong> time to live for message entries in database</li>
</ul>
<h2>Infrastructure</h2>
<h3>Database</h3>
<h4>Models</h4>
<p>The database supports the following model concepts:</p>
<ul>
<li>
<p><a href="./SatelliteGateway.html"><strong>SatelliteGateway</strong></a> represents the API server
operated by Inmarsat or another authorized network operator.
<code>category = 'satellite_gateway'</code> with <code>name</code> as the model-unique key.</p>
</li>
<li>
<p><a href="./Mailbox.html"><strong>Mailbox</strong></a> represents an account providing authentication
and segregation of customer data access. These are configured with
authentication credentials, where the password component is [encrypted] for
storage. <code>category = 'mailbox'</code> with <code>mailboxId</code> as the model-unique key.</p>
</li>
<li>
<p><a href="./Mobile.html"><strong>Mobile</strong></a> represents a satellite modem associated with a
remote asset/device and supports various metadata related to configuration,
queried location and diagnostic information. <code>category = 'mobile'</code>
with <code>mobileId</code> as the model-unique key.</p>
</li>
<li>
<p><a href="./MessageReturn.html"><strong>MessageReturn</strong></a> represents mobile-originated
(aka <em>Return</em>) data, typically device telemetry or responses to low-level modem
commands. These messages contain data as raw binary and/or JSON structures
depending on whether a <em>Message Definition File</em> is provisioned on the <em>Mailbox</em>.<br>
<code>category = 'message_return'</code> with <code>messageId</code> as the model-unique key.</p>
</li>
<li>
<p><a href="./MessageForward.html"><strong>MessageForward</strong></a> represents mobile-terminated
(aka <em>Forward</em>) data, typically commands or small files sent to the device from
a cloud-based application. These messages contain data as raw binary and/or
JSON structures depending on how they are submitted and whether a
<em>Message Definition File</em> is provisioned on the <em>Mailbox</em>.<br>
<code>category = 'message_forward'</code> with <code>messageId</code> as the model-unique key.</p>
</li>
<li>
<p><a href="./ApiCallLog.html"><strong>ApiCallLog</strong></a> record the low-level API transactions
to the Inmarsat server including various metadata used as a "high water mark"
for message retrieval and for diagnostic purposes.<br>
<code>category = 'api_call_log'</code> with <code>callTimeUtc</code> as the model-unique key.</p>
</li>
</ul>
<h4>Storage</h4>
<p>Data storage architecture is dependent on the database type. For example
Azure Cosmos DB is a flat structure using a category tag for search, while
MySQL initializes a table for each model type. Model property keys use
snake_case when stored in the database, which are translated to camelCase when
retrieved via <code>find()</code></p>
<p>ApiCallLog and Messages include a <em>time-to-live</em> (<strong>ttl</strong>) class property
with units in seconds. When using Cosmos DB, this property should automatically
remove aged data to keep database size smaller. For MySQL, the user can
implement a periodic check with the <em>removeAged</em> method.</p>
<h4>Methods</h4>
<p>The principle methods for accessing the database are:</p>
<ol>
<li>
<p><strong><code>initialize()</code></strong> ensures the database infrastructure is in place, creating
it if running for the first time, and instantiates the connection.</p>
</li>
<li>
<p><strong><code>find()</code></strong> retrieves the specified model based on its category and optional
filter criteria.</p>
</li>
<li>
<p><strong><code>upsert()</code></strong> adds a new model or updates an existing one based on its model-
unique key.</p>
</li>
<li>
<p><strong><code>close()</code></strong> terminates the connection after use.</p>
</li>
</ol>
<h3>Encryption</h3>
<p>The encryption function is primarily for illustrative purposes using AES-256
based on a secret/key stored as an environment variable <code>MAILBOX_SECRET</code>. The
encryption is used at rest when storing Mailbox password in the database, then
decrypted to pass as a credential in the relevant API call, which in turn is
encrypted by TLS in transit.</p>
<h3>Event Handler</h3>
<p>The <a href="./module-eventHandler.html"><code>eventHandler.emitter</code></a> is implemented as a
Node <em>events</em> emitter intended for use as a singleton, which emits the
following dependent on the microservice in play:</p>
<ul>
<li>
<p><strong>NewMobile</strong> includes metadata about a new satellite modem the first time a
return message is received causing that Mobile to be added to the database.</p>
</li>
<li>
<p><strong>NewReturnMessage</strong> includes message content and metadata whenever a new
return messsage is received from any modem.</p>
</li>
<li>
<p><strong>NewForwardMessage</strong> includes content and metadata when a forward message is
submitted via the <code>submitForwardMessages</code> microservice.</p>
</li>
<li>
<p><strong>ForwardMessageStateChange</strong> triggers when a submitted forward message's
state changes e.g. to DELIVERED or FAILED.</p>
</li>
<li>
<p><strong>OtherClientForwardSubmission</strong> triggers when a status is retrieved for a
forward message that was <em>not</em> submitted via the <code>submitForwardMessages</code>
microservice.</p>
</li>
<li>
<p><strong>ApiError</strong> triggers when an error code is returned by the Inmarsat API.</p>
</li>
<li>
<p><strong>ApiOutage</strong> triggers when the Inmarsat API becomes non-responsive. API
state is maintained in the database <code>SatelliteGateway</code> property <code>alive</code>.</p>
</li>
<li>
<p><strong>ApiRecovery</strong> triggers when the Inmarsat API becomes responsive after an
outage.</p>
</li>
</ul>
<h3>Logging</h3>
<p>A Winston <a href="./module-logging.html">logger</a> is included to provide
JSON-structured logs with a standard format and UTC timestamp for
troubleshooting. A proxy logger is exposed for convenience use by applications
using the library.</p>
<h3>Message Codecs</h3>
<p>All IsatData Pro modems support a standard set of basic remote operations
referred to as <a href="./module-messageCodecs_coreModem.html"><em>Core Modem Messages</em></a>
which are normally presented as JSON-structured data on the API and contain
metadata about the modem.</p>
<p>The <code>getReturnMessages</code> microservice parses these standard messages to
populate <em>Mobile</em> metadata in the database.</p>
<p>Additionally the <code>submitForwardMessages</code> microservice accepts shorthand
remote commands/parameters which use the message codec to encode the message to
send over the air.</p>
<p>The JSON-structured data employs a so-called <em>common message format</em> supporting
various data types encoded as binary data over the satellite link. To make use
of <a href="./module-messageCodecs_commonMessageFormat.html"><code>commonMessageFormat</code></a>
for application messages, contact your Inmarsat representative to discuss the
concept of <em>Message Definition File</em> in your application.</p>
<h2>Microservices</h2>
<p>The microservices and eventHandler emitter are the primary aspects exposed by
this library. Before using the microservices it is necessary to "provision" at
least one <em>SatelliteGateway</em> (API URL) and one <em>Mailbox</em> with valid access
credentials.</p>
<ul>
<li>
<p><a href="./module-getReturnMessages.html"><strong><code>getReturnMessages</code></strong></a> is intended to
run periodically (e.g. every 15 seconds) to retrieve new messages coming in from
all modems accessed by the provisioned <em>Mailbox</em>(es).<br>
Events emitted include <code>NewReturnMessage</code>, <code>NewMobile</code>.</p>
</li>
<li>
<p><a href="./module-submitForwardMessages.html"><strong><code>submitForwardMessages</code></strong></a> is called
destined to a specific <em>mobileId</em> with specific commands, an array of
decimal-coded bytes <em>payloadRaw</em> or an application-specific <em>payloadJson</em>.<br>
Events emitted include <code>NewForwardMessage</code>.</p>
</li>
<li>
<p><a href="./module-getForwardStatuses.html"><strong><code>getForwardStatuses</code></strong></a> is intended to
be run periodically, in particular following the use of
<code>submitForwardMessages</code> to monitor the progression of commands or
mobile-terminated data. Events emitted include <code>ForwardMessageStateChange</code>,
<code>OtherClientForwardSubmission</code>.</p>
</li>
<li>
<p><a href="./module-getForwardMessages.html"><strong><code>getForwardMessages</code></strong></a> is intended to
be used following a <code>OtherClientForwardSubmission</code> event, to retrieve the
content of a message submitted by a means other than <code>submitForwardMessages</code>
(which generally implies another API client is accessing the Mailbox in
parallel).</p>
</li>
<li>
<p><a href="./module-updateMailbox.html"><strong><code>updateMailbox</code></strong></a> is used to add a
<em>Mailbox</em> to the database which will subsequently be polled by
<code>getReturnMessages</code> and accessible for <code>submitForwardMessages</code>.<br>
A <em>Mailbox</em> is the parent of one or more <em>Mobile</em>(s).</p>
</li>
<li>
<p><a href="./module-updateSatelliteGateway.html"><strong><code>updateSatelliteGateway</code></strong></a> is used
to add a <em>SatelliteGateway</em> to the database as the parent of one or more
<em>Mailbox</em>(es).</p>
</li>
<li>
<p><a href="./module-getMobiles.html"><strong><code>getMobiles</code></strong></a> may be used to retrieve the
list of <em>Mobile</em>(s) metadata from the provisioned <em>Mailbox</em>(es). This operation
is useful if a given Mobile has not yet sent any return messages.</p>
</li>
</ul></article>
</section>
<footer>
Documentation generated by <a target="_blank" href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.4</a> on Sat Oct 24 2020 14:53:36 GMT-0400 (Eastern Daylight Time)
</footer>
</div>
</div>
<script>prettyPrint();</script>
<script src="scripts/jaguar.js"></script>
</body>
</html>