ultravisor-beacon-capability 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -0
- package/docs/.nojekyll +0 -0
- package/docs/README.md +103 -0
- package/docs/_brand.json +18 -0
- package/docs/_cover.md +13 -0
- package/docs/_sidebar.md +31 -0
- package/docs/_topbar.md +5 -0
- package/docs/_version.json +7 -0
- package/docs/api/README.md +44 -0
- package/docs/api/action-convention.md +148 -0
- package/docs/api/add-action.md +68 -0
- package/docs/api/beacon-capability.md +89 -0
- package/docs/api/build-action-map.md +88 -0
- package/docs/api/connect.md +81 -0
- package/docs/api/disconnect.md +50 -0
- package/docs/api/is-connected.md +33 -0
- package/docs/api/lifecycle-hooks.md +115 -0
- package/docs/architecture.md +237 -0
- package/docs/css/docuserve.css +327 -0
- package/docs/examples/README.md +58 -0
- package/docs/examples/certificate-expiry-monitor.md +212 -0
- package/docs/examples/docker-container-management.md +265 -0
- package/docs/examples/log-archive-and-upload.md +214 -0
- package/docs/examples/log-file-cleanup.md +199 -0
- package/docs/examples/mysql-maintenance.md +253 -0
- package/docs/examples/postgresql-aggregation.md +247 -0
- package/docs/examples/rest-api-health-check.md +213 -0
- package/docs/examples/rest-endpoint-sync.md +240 -0
- package/docs/examples/server-metrics-collection.md +199 -0
- package/docs/examples/shell-commands.md +176 -0
- package/docs/index.html +39 -0
- package/docs/quickstart.md +199 -0
- package/docs/retold-catalog.json +85 -0
- package/docs/retold-keyword-index.json +10642 -0
- package/package.json +33 -0
- package/source/Ultravisor-Beacon-Capability-ActionMap.cjs +132 -0
- package/source/Ultravisor-Beacon-Capability.cjs +276 -0
- package/test/Ultravisor-Beacon-Capability_tests.js +744 -0
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Ultravisor Beacon Capability
|
|
2
|
+
============================
|
|
3
|
+
|
|
4
|
+
A convention-based base class for building Ultravisor beacon capabilities with minimal boilerplate. Extend the class, define action methods with the `action` prefix, and call `connect()` -- the module handles beacon registration, transport, and lifecycle automatically.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- **Convention Over Configuration** -- Define actions as methods prefixed with `action`; schemas and descriptions as companion getters
|
|
9
|
+
- **Automatic Discovery** -- Actions are discovered by walking the prototype chain, including multi-level inheritance
|
|
10
|
+
- **Simplified Handler Signature** -- Settings are pre-extracted from work items so handlers receive `(pSettings, pWorkItem, fCallback, fReportProgress)`
|
|
11
|
+
- **Lifecycle Hooks** -- Override `onInitialize()` and `onShutdown()` for setup and teardown (database connections, service handles, etc.)
|
|
12
|
+
- **Explicit Registration Escape Hatch** -- Use `addAction()` for dynamic or runtime-generated actions alongside convention-based ones
|
|
13
|
+
- **Fable Ecosystem Integration** -- Extends `fable-serviceproviderbase`; composes `ultravisor-beacon` internally
|
|
14
|
+
|
|
15
|
+
## Documentation
|
|
16
|
+
|
|
17
|
+
Comprehensive documentation is available in the [docs](./docs) folder:
|
|
18
|
+
|
|
19
|
+
- [Overview](./docs/README.md) -- Introduction and getting started
|
|
20
|
+
- [Quick Start](./docs/quickstart.md) -- Step-by-step setup guide
|
|
21
|
+
- [Architecture](./docs/architecture.md) -- System design and mermaid diagrams
|
|
22
|
+
- [API Reference](./docs/api/README.md) -- All classes and methods
|
|
23
|
+
- [Examples](./docs/examples/README.md) -- Real-world usage patterns
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
$ npm install ultravisor-beacon-capability
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
const libFable = require('fable');
|
|
35
|
+
const libBeaconCapability = require('ultravisor-beacon-capability');
|
|
36
|
+
|
|
37
|
+
class DiskCleanup extends libBeaconCapability
|
|
38
|
+
{
|
|
39
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
40
|
+
{
|
|
41
|
+
super(pFable, pOptions, pServiceHash);
|
|
42
|
+
this.serviceType = 'DiskCleanup';
|
|
43
|
+
this.capabilityName = 'DiskCleanup';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get actionPurgeTempFiles_Description()
|
|
47
|
+
{
|
|
48
|
+
return 'Remove temporary files older than N days';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get actionPurgeTempFiles_Schema()
|
|
52
|
+
{
|
|
53
|
+
return [
|
|
54
|
+
{ Name: 'Directory', DataType: 'String', Required: true },
|
|
55
|
+
{ Name: 'MaxAgeDays', DataType: 'Integer', Required: true },
|
|
56
|
+
{ Name: 'DryRun', DataType: 'Boolean', Required: false }
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
actionPurgeTempFiles(pSettings, pWorkItem, fCallback)
|
|
61
|
+
{
|
|
62
|
+
let tmpCmd = `find ${pSettings.Directory} -type f -mtime +${pSettings.MaxAgeDays}`;
|
|
63
|
+
if (!pSettings.DryRun)
|
|
64
|
+
{
|
|
65
|
+
tmpCmd += ' -delete';
|
|
66
|
+
}
|
|
67
|
+
require('child_process').exec(tmpCmd, (pError, pStdOut) =>
|
|
68
|
+
{
|
|
69
|
+
if (pError) return fCallback(pError);
|
|
70
|
+
return fCallback(null, { Outputs: { Result: pStdOut, DryRun: !!pSettings.DryRun } });
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let tmpFable = new libFable({ Product: 'DiskCleanup', ProductVersion: '1.0.0' });
|
|
76
|
+
tmpFable.addServiceType('DiskCleanup', DiskCleanup);
|
|
77
|
+
let tmpCleanup = tmpFable.instantiateServiceProvider('DiskCleanup');
|
|
78
|
+
|
|
79
|
+
tmpCleanup.connect(
|
|
80
|
+
{
|
|
81
|
+
ServerURL: 'http://ultravisor.local:54321',
|
|
82
|
+
Name: 'disk-cleanup-worker'
|
|
83
|
+
},
|
|
84
|
+
(pError, pBeaconInfo) =>
|
|
85
|
+
{
|
|
86
|
+
if (pError) throw pError;
|
|
87
|
+
console.log('Beacon online:', pBeaconInfo.BeaconID);
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Once connected, the Ultravisor server automatically creates a task type `beacon-diskcleanup-purgetempfiles` that can be triggered manually, scheduled, or wired into operation graphs.
|
|
92
|
+
|
|
93
|
+
## Related Packages
|
|
94
|
+
|
|
95
|
+
- [ultravisor-beacon](https://github.com/stevenvelozo/ultravisor-beacon) -- Underlying beacon client and Fable service
|
|
96
|
+
- [ultravisor](https://github.com/stevenvelozo/ultravisor) -- Process supervision and orchestration server
|
|
97
|
+
- [fable](https://github.com/stevenvelozo/fable) -- Service dependency injection framework
|
|
98
|
+
- [fable-serviceproviderbase](https://github.com/stevenvelozo/fable-serviceproviderbase) -- Service provider base class
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
MIT
|
|
103
|
+
|
|
104
|
+
## Contributing
|
|
105
|
+
|
|
106
|
+
Pull requests are welcome. For details on our code of conduct, contribution process, and testing requirements, see the [Retold Contributing Guide](https://github.com/stevenvelozo/retold/blob/main/docs/contributing.md).
|
package/docs/.nojekyll
ADDED
|
File without changes
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Ultravisor Beacon Capability
|
|
2
|
+
|
|
3
|
+
> Convention-based base class for building Ultravisor beacon capabilities
|
|
4
|
+
|
|
5
|
+
Ultravisor Beacon Capability eliminates the boilerplate of wiring up an Ultravisor beacon. Instead of manually creating a beacon service, building capability descriptors, and managing the connection lifecycle, you extend a single base class, write action methods, and call `connect()`. The module discovers your actions by convention, builds the capability descriptor, registers with the Ultravisor server, and manages the full beacon lifecycle.
|
|
6
|
+
|
|
7
|
+
The Ultravisor server automatically creates task types (cards) for each action your capability exposes. These can be triggered on demand, scheduled for recurring execution, or composed into multi-step operation graphs -- turning ad-hoc scripts into managed, observable automation.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Convention Over Configuration** -- Define actions as methods prefixed with `action`; schemas and descriptions as companion getters
|
|
12
|
+
- **Automatic Discovery** -- Actions are discovered by walking the prototype chain, including multi-level inheritance
|
|
13
|
+
- **Simplified Handler Signature** -- Settings are pre-extracted from work items so handlers receive `(pSettings, pWorkItem, fCallback, fReportProgress)`
|
|
14
|
+
- **Lifecycle Hooks** -- Override `onInitialize()` and `onShutdown()` for setup and teardown (database connections, service handles, etc.)
|
|
15
|
+
- **Explicit Registration Escape Hatch** -- Use `addAction()` for dynamic or runtime-generated actions alongside convention-based ones
|
|
16
|
+
- **Fable Ecosystem Integration** -- Extends `fable-serviceproviderbase`; composes `ultravisor-beacon` internally
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
const libFable = require('fable');
|
|
22
|
+
const libBeaconCapability = require('ultravisor-beacon-capability');
|
|
23
|
+
|
|
24
|
+
class HealthCheck extends libBeaconCapability
|
|
25
|
+
{
|
|
26
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
27
|
+
{
|
|
28
|
+
super(pFable, pOptions, pServiceHash);
|
|
29
|
+
this.serviceType = 'HealthCheck';
|
|
30
|
+
this.capabilityName = 'HealthCheck';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get actionCheckDiskSpace_Description()
|
|
34
|
+
{
|
|
35
|
+
return 'Report available disk space on the host';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
actionCheckDiskSpace(pSettings, pWorkItem, fCallback)
|
|
39
|
+
{
|
|
40
|
+
require('child_process').exec('df -h', (pError, pStdOut) =>
|
|
41
|
+
{
|
|
42
|
+
if (pError) return fCallback(pError);
|
|
43
|
+
return fCallback(null, { Outputs: { DiskUsage: pStdOut } });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let tmpFable = new libFable({ Product: 'HealthCheck' });
|
|
49
|
+
tmpFable.addServiceType('HealthCheck', HealthCheck);
|
|
50
|
+
let tmpCheck = tmpFable.instantiateServiceProvider('HealthCheck');
|
|
51
|
+
|
|
52
|
+
tmpCheck.connect({ ServerURL: 'http://ultravisor.local:54321' }, (pError) =>
|
|
53
|
+
{
|
|
54
|
+
if (pError) throw pError;
|
|
55
|
+
console.log('Health check beacon online');
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install ultravisor-beacon-capability
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Core Concepts
|
|
66
|
+
|
|
67
|
+
### The Action Convention
|
|
68
|
+
|
|
69
|
+
Actions are discovered by method name prefix. An action named `PurgeRecords` is defined by up to three members on your class:
|
|
70
|
+
|
|
71
|
+
| Member | Required | Purpose |
|
|
72
|
+
|--------|----------|---------|
|
|
73
|
+
| `actionPurgeRecords(pSettings, pWorkItem, fCallback, fReportProgress)` | Yes | The handler function |
|
|
74
|
+
| `get actionPurgeRecords_Schema()` | No | Returns a `SettingsSchema` array describing input parameters |
|
|
75
|
+
| `get actionPurgeRecords_Description()` | No | Returns a human-readable description string |
|
|
76
|
+
|
|
77
|
+
The handler receives `pSettings` pre-extracted from `pWorkItem.Settings` (defaulting to `{}` if absent), eliminating the universal boilerplate of `let tmpSettings = pWorkItem.Settings || {};`.
|
|
78
|
+
|
|
79
|
+
### Server-Side Integration
|
|
80
|
+
|
|
81
|
+
When a beacon registers capabilities, the Ultravisor server's coordinator automatically creates task types for each `Capability:Action` pair. The task type hash follows the format `beacon-{capability}-{action}` (e.g. `beacon-healthcheck-checkdiskspace`). These task types appear as cards in the Ultravisor UI and can be:
|
|
82
|
+
|
|
83
|
+
- **Triggered manually** from the Ultravisor dashboard
|
|
84
|
+
- **Scheduled** for recurring execution
|
|
85
|
+
- **Composed** into operation graphs with other task types
|
|
86
|
+
|
|
87
|
+
### Before and After
|
|
88
|
+
|
|
89
|
+
Without this module, registering a single capability requires approximately 60 lines of framework code (service type registration, beacon instantiation, descriptor building, lifecycle management). With this module, the same result requires approximately 5 lines of framework code -- one class declaration, one `capabilityName` assignment, and one `connect()` call.
|
|
90
|
+
|
|
91
|
+
## Documentation
|
|
92
|
+
|
|
93
|
+
- [Quick Start](quickstart.md) -- Step-by-step setup
|
|
94
|
+
- [Architecture](architecture.md) -- System design with diagrams
|
|
95
|
+
- [API Reference](api/README.md) -- Complete class and method reference
|
|
96
|
+
- [Examples](examples/README.md) -- Real-world usage patterns
|
|
97
|
+
|
|
98
|
+
## Related Packages
|
|
99
|
+
|
|
100
|
+
- [ultravisor-beacon](https://github.com/stevenvelozo/ultravisor-beacon) -- Underlying beacon client and Fable service
|
|
101
|
+
- [ultravisor](https://github.com/stevenvelozo/ultravisor) -- Process supervision and orchestration server
|
|
102
|
+
- [fable](https://github.com/stevenvelozo/fable) -- Service dependency injection framework
|
|
103
|
+
- [fable-serviceproviderbase](https://github.com/stevenvelozo/fable-serviceproviderbase) -- Service provider base class
|
package/docs/_brand.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Hash": "ultravisor-beacon-capability",
|
|
3
|
+
"Name": "Ultravisor Beacon Capability",
|
|
4
|
+
"Tagline": "Convention-based base class for building Ultravisor beacon capabilities with minimal boilerplate",
|
|
5
|
+
"Palette": "mix",
|
|
6
|
+
"Icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"frame-ultravisor-beacon-capability-filled-light\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#1dc3df\"/>\n\t\t<g clip-path=\"url(#frame-ultravisor-beacon-capability-filled-light)\"><rect x=\"20\" y=\"20\" width=\"56\" height=\"56\" rx=\"8\" fill=\"rgba(255,255,255,0.18)\"/>\n\t\t\t\t\t<path d=\"M 48 30 L 70 48 L 48 66 L 26 48 Z\" fill=\"#f043d4\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"28\" font-weight=\"600\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">UBC</text>\n\t</svg>",
|
|
7
|
+
"IconType": "svg",
|
|
8
|
+
"Favicon": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-ultravisor-beacon-capability-light\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#1dc3df\"/>\n\t\t<g clip-path=\"url(#fav-ultravisor-beacon-capability-light)\"><rect x=\"16\" y=\"16\" width=\"64\" height=\"64\" rx=\"10\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">U</text>\n\t</svg>",
|
|
9
|
+
"FaviconDark": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-ultravisor-beacon-capability-dark\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#71d6e7\"/>\n\t\t<g clip-path=\"url(#fav-ultravisor-beacon-capability-dark)\"><rect x=\"16\" y=\"16\" width=\"64\" height=\"64\" rx=\"10\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#101418\" letter-spacing=\"-1\">U</text>\n\t</svg>",
|
|
10
|
+
"Colors": {
|
|
11
|
+
"Primary": "#1dc3df",
|
|
12
|
+
"Secondary": "#f043d4",
|
|
13
|
+
"PrimaryLight": "#1dc3df",
|
|
14
|
+
"PrimaryDark": "#71d6e7",
|
|
15
|
+
"SecondaryLight": "#f043d4",
|
|
16
|
+
"SecondaryDark": "#f49ce5"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/docs/_cover.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Ultravisor Beacon Capability
|
|
2
|
+
|
|
3
|
+
> Convention-based base class for building Ultravisor beacon capabilities
|
|
4
|
+
|
|
5
|
+
- Define actions as methods with the `action` prefix
|
|
6
|
+
- Automatic discovery via prototype chain walking
|
|
7
|
+
- Simplified handler signature with pre-extracted settings
|
|
8
|
+
- Full Fable ecosystem integration
|
|
9
|
+
|
|
10
|
+
[Get Started](quickstart.md)
|
|
11
|
+
[API Reference](api/README.md)
|
|
12
|
+
[Examples](examples/README.md)
|
|
13
|
+
[GitHub](https://github.com/stevenvelozo/ultravisor-beacon-capability)
|
package/docs/_sidebar.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
- Getting Started
|
|
2
|
+
|
|
3
|
+
- [Introduction](/)
|
|
4
|
+
- [Quick Start](quickstart.md)
|
|
5
|
+
- [Architecture](architecture.md)
|
|
6
|
+
|
|
7
|
+
- API Reference
|
|
8
|
+
|
|
9
|
+
- [Overview](api/README.md)
|
|
10
|
+
- [UltravisorBeaconCapability](api/beacon-capability.md)
|
|
11
|
+
- [Action Convention](api/action-convention.md)
|
|
12
|
+
- [buildActionMap](api/build-action-map.md)
|
|
13
|
+
- [connect](api/connect.md)
|
|
14
|
+
- [disconnect](api/disconnect.md)
|
|
15
|
+
- [addAction](api/add-action.md)
|
|
16
|
+
- [onInitialize / onShutdown](api/lifecycle-hooks.md)
|
|
17
|
+
- [isConnected](api/is-connected.md)
|
|
18
|
+
|
|
19
|
+
- Examples
|
|
20
|
+
|
|
21
|
+
- [Overview](examples/README.md)
|
|
22
|
+
- [Shell Commands](examples/shell-commands.md)
|
|
23
|
+
- [MySQL Maintenance](examples/mysql-maintenance.md)
|
|
24
|
+
- [PostgreSQL Aggregation](examples/postgresql-aggregation.md)
|
|
25
|
+
- [REST API Health Check](examples/rest-api-health-check.md)
|
|
26
|
+
- [REST Endpoint Sync](examples/rest-endpoint-sync.md)
|
|
27
|
+
- [Log File Cleanup](examples/log-file-cleanup.md)
|
|
28
|
+
- [Log Archive and Upload](examples/log-archive-and-upload.md)
|
|
29
|
+
- [Server Metrics Collection](examples/server-metrics-collection.md)
|
|
30
|
+
- [Certificate Expiry Monitor](examples/certificate-expiry-monitor.md)
|
|
31
|
+
- [Docker Container Management](examples/docker-container-management.md)
|
package/docs/_topbar.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
> Complete reference for ultravisor-beacon-capability
|
|
4
|
+
|
|
5
|
+
## Module Export
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
const libBeaconCapability = require('ultravisor-beacon-capability');
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The module exports `UltravisorBeaconCapability`, a class that extends `fable-serviceproviderbase`. You extend this class to define your capability.
|
|
12
|
+
|
|
13
|
+
## Classes
|
|
14
|
+
|
|
15
|
+
| Class | Description |
|
|
16
|
+
|-------|-------------|
|
|
17
|
+
| [UltravisorBeaconCapability](beacon-capability.md) | Base class -- extend to define capabilities with action methods |
|
|
18
|
+
|
|
19
|
+
## Convention
|
|
20
|
+
|
|
21
|
+
| Reference | Description |
|
|
22
|
+
|-----------|-------------|
|
|
23
|
+
| [Action Convention](action-convention.md) | How actions are discovered via the `action` prefix |
|
|
24
|
+
|
|
25
|
+
## Methods
|
|
26
|
+
|
|
27
|
+
| Method | Description |
|
|
28
|
+
|--------|-------------|
|
|
29
|
+
| [connect()](connect.md) | Connect to an Ultravisor server, register actions, begin accepting work |
|
|
30
|
+
| [disconnect()](disconnect.md) | Disconnect from the Ultravisor server |
|
|
31
|
+
| [addAction()](add-action.md) | Explicitly register an action (escape hatch for dynamic actions) |
|
|
32
|
+
| [isConnected()](is-connected.md) | Check whether the beacon is currently connected |
|
|
33
|
+
|
|
34
|
+
## Lifecycle Hooks
|
|
35
|
+
|
|
36
|
+
| Hook | Description |
|
|
37
|
+
|------|-------------|
|
|
38
|
+
| [onInitialize() / onShutdown()](lifecycle-hooks.md) | Setup and teardown hooks for resource management |
|
|
39
|
+
|
|
40
|
+
## Internal
|
|
41
|
+
|
|
42
|
+
| Function | Description |
|
|
43
|
+
|----------|-------------|
|
|
44
|
+
| [buildActionMap()](build-action-map.md) | Discovers action methods on a capability instance's prototype chain |
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Action Convention
|
|
2
|
+
|
|
3
|
+
Actions are discovered automatically by examining method names on your class. Any method starting with `action` (and longer than just the word "action") is treated as an action handler. Companion getters provide metadata.
|
|
4
|
+
|
|
5
|
+
## Defining an Action
|
|
6
|
+
|
|
7
|
+
An action named `DoSomething` consists of up to three members:
|
|
8
|
+
|
|
9
|
+
### Handler (required)
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
actionDoSomething(pSettings, pWorkItem, fCallback, fReportProgress)
|
|
13
|
+
{
|
|
14
|
+
// pSettings -- pre-extracted from pWorkItem.Settings (defaults to {} if missing)
|
|
15
|
+
// pWorkItem -- the full work item object from Ultravisor
|
|
16
|
+
// fCallback -- function(pError, pResult) where pResult = { Outputs: {...}, Log: [...] }
|
|
17
|
+
// fReportProgress -- optional function({ Percent, Message, Step, TotalSteps })
|
|
18
|
+
|
|
19
|
+
return fCallback(null, { Outputs: { Result: 'done' } });
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Schema (optional)
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
get actionDoSomething_Schema()
|
|
27
|
+
{
|
|
28
|
+
return [
|
|
29
|
+
{ Name: 'InputFile', DataType: 'String', Required: true },
|
|
30
|
+
{ Name: 'OutputFormat', DataType: 'String', Required: false },
|
|
31
|
+
{ Name: 'MaxRows', DataType: 'Integer', Required: false }
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The schema is an array of field definitions. Each field has:
|
|
37
|
+
|
|
38
|
+
| Property | Type | Description |
|
|
39
|
+
|----------|------|-------------|
|
|
40
|
+
| `Name` | `string` | Parameter name |
|
|
41
|
+
| `DataType` | `string` | Type: `String`, `Integer`, `Boolean`, `Object`, `Array`, `DateTime` |
|
|
42
|
+
| `Required` | `boolean` | Whether the parameter is required |
|
|
43
|
+
| `Default` | `any` | Optional default value |
|
|
44
|
+
| `Description` | `string` | Optional human-readable description |
|
|
45
|
+
|
|
46
|
+
### Description (optional)
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
get actionDoSomething_Description()
|
|
50
|
+
{
|
|
51
|
+
return 'Process an input file and produce output in the specified format';
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Handler Signature
|
|
56
|
+
|
|
57
|
+
The convention handler signature differs from the raw `ultravisor-beacon` handler:
|
|
58
|
+
|
|
59
|
+
| Parameter | Convention | Raw beacon |
|
|
60
|
+
|-----------|-----------|------------|
|
|
61
|
+
| 1st | `pSettings` (pre-extracted) | `pWorkItem` |
|
|
62
|
+
| 2nd | `pWorkItem` (full object) | `pContext` |
|
|
63
|
+
| 3rd | `fCallback` | `fCallback` |
|
|
64
|
+
| 4th | `fReportProgress` | `fReportProgress` |
|
|
65
|
+
|
|
66
|
+
The base class wraps your method so that `ultravisor-beacon` receives the raw signature it expects.
|
|
67
|
+
|
|
68
|
+
## Result Format
|
|
69
|
+
|
|
70
|
+
The callback expects:
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
// Success
|
|
74
|
+
fCallback(null, {
|
|
75
|
+
Outputs: { Key: 'value', AnotherKey: 123 },
|
|
76
|
+
Log: ['Step 1 complete', 'Step 2 complete']
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Error
|
|
80
|
+
fCallback(new Error('Something went wrong'));
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- `Outputs` -- key-value pairs available as task state outputs on the Ultravisor server
|
|
84
|
+
- `Log` -- array of log strings recorded with the work item result
|
|
85
|
+
|
|
86
|
+
## Progress Reporting
|
|
87
|
+
|
|
88
|
+
For long-running actions, use `fReportProgress`:
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
actionLongTask(pSettings, pWorkItem, fCallback, fReportProgress)
|
|
92
|
+
{
|
|
93
|
+
fReportProgress({ Percent: 0, Message: 'Starting...', Step: 1, TotalSteps: 3 });
|
|
94
|
+
|
|
95
|
+
// ... do step 1 ...
|
|
96
|
+
|
|
97
|
+
fReportProgress({ Percent: 33, Message: 'Step 1 complete', Step: 2, TotalSteps: 3 });
|
|
98
|
+
|
|
99
|
+
// ... do step 2 ...
|
|
100
|
+
|
|
101
|
+
fReportProgress({ Percent: 66, Message: 'Step 2 complete', Step: 3, TotalSteps: 3 });
|
|
102
|
+
|
|
103
|
+
// ... do step 3 ...
|
|
104
|
+
|
|
105
|
+
return fCallback(null, { Outputs: { Result: 'all done' } });
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Discovery Rules
|
|
110
|
+
|
|
111
|
+
1. Method name must start with `action` and be longer than 6 characters
|
|
112
|
+
2. Methods ending with `_Schema` or `_Description` are companions, not actions
|
|
113
|
+
3. Only actual functions are considered (not getters or plain properties)
|
|
114
|
+
4. The prototype chain is walked from the derived class up to (but not including) `Object.prototype`
|
|
115
|
+
5. If a method name appears on both a derived and base class, the derived version wins
|
|
116
|
+
6. Missing `_Schema` defaults to `[]`; missing `_Description` defaults to `''`
|
|
117
|
+
|
|
118
|
+
## `this` Context
|
|
119
|
+
|
|
120
|
+
Action methods are bound to the capability instance. You have full access to:
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
actionQuery(pSettings, pWorkItem, fCallback)
|
|
124
|
+
{
|
|
125
|
+
// Access Fable services
|
|
126
|
+
this.fable.services.SomeService.doWork();
|
|
127
|
+
|
|
128
|
+
// Access the logger
|
|
129
|
+
this.log.info('Processing query...');
|
|
130
|
+
|
|
131
|
+
// Access instance state set in onInitialize
|
|
132
|
+
this._DatabaseConnection.query(pSettings.SQL, (pError, pRows) =>
|
|
133
|
+
{
|
|
134
|
+
if (pError) return fCallback(pError);
|
|
135
|
+
return fCallback(null, { Outputs: { Rows: pRows } });
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Naming Conventions
|
|
141
|
+
|
|
142
|
+
The action name is derived by stripping the `action` prefix. The casing is preserved:
|
|
143
|
+
|
|
144
|
+
| Method Name | Action Name | Task Type Hash |
|
|
145
|
+
|-------------|-------------|----------------|
|
|
146
|
+
| `actionPurgeRecords` | `PurgeRecords` | `beacon-{cap}-purgerecords` |
|
|
147
|
+
| `actionRunBackup` | `RunBackup` | `beacon-{cap}-runbackup` |
|
|
148
|
+
| `actionSyncData` | `SyncData` | `beacon-{cap}-syncdata` |
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# addAction()
|
|
2
|
+
|
|
3
|
+
Explicitly register an action. Use this as an escape hatch for actions that cannot be expressed via the convention (e.g. dynamically generated actions, actions loaded from configuration, or actions with closures over external state).
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
addAction(pName, pDefinition)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Parameters
|
|
12
|
+
|
|
13
|
+
| Parameter | Type | Description |
|
|
14
|
+
|-----------|------|-------------|
|
|
15
|
+
| `pName` | `string` | Action name (e.g. `'ProcessData'`) |
|
|
16
|
+
| `pDefinition` | `object` | Action definition (see below) |
|
|
17
|
+
|
|
18
|
+
### Definition
|
|
19
|
+
|
|
20
|
+
| Property | Type | Required | Description |
|
|
21
|
+
|----------|------|----------|-------------|
|
|
22
|
+
| `Handler` | `function` | Yes | `function(pWorkItem, pContext, fCallback, fReportProgress)` -- uses the **raw** beacon handler signature |
|
|
23
|
+
| `Description` | `string` | No | Human-readable description |
|
|
24
|
+
| `SettingsSchema` | `array` | No | Array of field definitions |
|
|
25
|
+
|
|
26
|
+
**Important:** The `Handler` uses the raw `ultravisor-beacon` signature, not the simplified convention signature. This means `pWorkItem` is the first parameter (not `pSettings`).
|
|
27
|
+
|
|
28
|
+
## Behavior
|
|
29
|
+
|
|
30
|
+
- Stores the action in an internal map
|
|
31
|
+
- Explicit actions are merged with convention-discovered actions when `connect()` is called
|
|
32
|
+
- If an explicit action has the same name as a convention-discovered action, the explicit one wins
|
|
33
|
+
- Validation: rejects calls with missing/empty `pName` or missing `Handler` function
|
|
34
|
+
|
|
35
|
+
## Example
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
let tmpFable = new libFable({});
|
|
39
|
+
let tmpCap = new MyCapability(tmpFable, {}, 'cap');
|
|
40
|
+
|
|
41
|
+
// Register a dynamic action
|
|
42
|
+
tmpCap.addAction('ImportCSV',
|
|
43
|
+
{
|
|
44
|
+
Description: 'Import data from a CSV file',
|
|
45
|
+
SettingsSchema: [
|
|
46
|
+
{ Name: 'FilePath', DataType: 'String', Required: true },
|
|
47
|
+
{ Name: 'Delimiter', DataType: 'String', Required: false }
|
|
48
|
+
],
|
|
49
|
+
Handler: function (pWorkItem, pContext, fCallback)
|
|
50
|
+
{
|
|
51
|
+
let tmpSettings = pWorkItem.Settings || {};
|
|
52
|
+
// ... process CSV ...
|
|
53
|
+
return fCallback(null, { Outputs: { RowsImported: 42 } });
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
tmpCap.connect({ ServerURL: 'http://ultravisor:54321' }, (pError) => { });
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## When to Use
|
|
61
|
+
|
|
62
|
+
| Scenario | Use Convention | Use addAction |
|
|
63
|
+
|----------|---------------|---------------|
|
|
64
|
+
| Standard action with known schema | Yes | -- |
|
|
65
|
+
| Action generated from config at runtime | -- | Yes |
|
|
66
|
+
| Action wrapping an external library callback | Either | Yes (simpler) |
|
|
67
|
+
| Action that needs the raw `pContext` parameter | -- | Yes |
|
|
68
|
+
| Multiple capabilities sharing a common action | -- | Yes |
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# UltravisorBeaconCapability
|
|
2
|
+
|
|
3
|
+
The base class for all convention-based beacon capabilities. Extend this class, set `capabilityName`, define action methods with the `action` prefix, and call `connect()`.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
const libBeaconCapability = require('ultravisor-beacon-capability');
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Constructor
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
class MyCapability extends libBeaconCapability
|
|
15
|
+
{
|
|
16
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
17
|
+
{
|
|
18
|
+
super(pFable, pOptions, pServiceHash);
|
|
19
|
+
this.serviceType = 'MyCapability';
|
|
20
|
+
this.capabilityName = 'MyCapability';
|
|
21
|
+
this.providerName = 'MyCapabilityProvider'; // optional
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Parameters
|
|
27
|
+
|
|
28
|
+
| Parameter | Type | Description |
|
|
29
|
+
|-----------|------|-------------|
|
|
30
|
+
| `pFable` | `Fable` | Fable instance (provided by the framework) |
|
|
31
|
+
| `pOptions` | `object` | Service options (provided by the framework) |
|
|
32
|
+
| `pServiceHash` | `string` | Service hash identifier (provided by the framework) |
|
|
33
|
+
|
|
34
|
+
### Properties
|
|
35
|
+
|
|
36
|
+
| Property | Type | Default | Description |
|
|
37
|
+
|----------|------|---------|-------------|
|
|
38
|
+
| `capabilityName` | `string` | `''` | **Required.** The capability name registered with Ultravisor. Must be set before calling `connect()`. |
|
|
39
|
+
| `providerName` | `string` | `''` | Optional display name. Defaults to `{capabilityName}Provider` if not set. |
|
|
40
|
+
| `serviceType` | `string` | `'UltravisorBeaconCapability'` | Fable service type identifier. Set to your class name. |
|
|
41
|
+
|
|
42
|
+
## Methods
|
|
43
|
+
|
|
44
|
+
| Method | Description |
|
|
45
|
+
|--------|-------------|
|
|
46
|
+
| [`connect(pBeaconConfig, fCallback)`](connect.md) | Connect to Ultravisor server |
|
|
47
|
+
| [`disconnect(fCallback)`](disconnect.md) | Disconnect from Ultravisor server |
|
|
48
|
+
| [`addAction(pName, pDefinition)`](add-action.md) | Register an explicit action |
|
|
49
|
+
| [`isConnected()`](is-connected.md) | Check connection status |
|
|
50
|
+
|
|
51
|
+
## Lifecycle Hooks
|
|
52
|
+
|
|
53
|
+
| Hook | Description |
|
|
54
|
+
|------|-------------|
|
|
55
|
+
| [`onInitialize(fCallback)`](lifecycle-hooks.md) | Called after beacon connects, before polling |
|
|
56
|
+
| [`onShutdown(fCallback)`](lifecycle-hooks.md) | Called when beacon disconnects |
|
|
57
|
+
|
|
58
|
+
## Usage with Fable
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
const libFable = require('fable');
|
|
62
|
+
|
|
63
|
+
let tmpFable = new libFable({ Product: 'MyApp' });
|
|
64
|
+
|
|
65
|
+
// Register the service type
|
|
66
|
+
tmpFable.addServiceType('MyCapability', MyCapability);
|
|
67
|
+
|
|
68
|
+
// Instantiate
|
|
69
|
+
let tmpCap = tmpFable.instantiateServiceProvider('MyCapability');
|
|
70
|
+
|
|
71
|
+
// Connect
|
|
72
|
+
tmpCap.connect({ ServerURL: 'http://ultravisor:54321' }, (pError) =>
|
|
73
|
+
{
|
|
74
|
+
if (pError) throw pError;
|
|
75
|
+
console.log('Connected');
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Inheritance
|
|
80
|
+
|
|
81
|
+
`UltravisorBeaconCapability` extends `fable-serviceproviderbase`, which means your capability instance has access to all standard Fable service features:
|
|
82
|
+
|
|
83
|
+
- `this.fable` -- the Fable instance
|
|
84
|
+
- `this.log` -- the Fable logger (`this.log.info()`, `this.log.error()`, etc.)
|
|
85
|
+
- `this.options` -- the service options
|
|
86
|
+
- `this.fable.settings` -- application settings
|
|
87
|
+
- `this.fable.services` -- other registered services
|
|
88
|
+
|
|
89
|
+
Multi-level inheritance is supported. Actions defined on base classes are discovered alongside those on derived classes, with derived classes taking precedence on name collision.
|