ldn-inbox-server 1.3.2 → 1.4.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 +42 -5
- package/bin/ldn-inbox-server.js +2 -10
- package/bin/post-notification.js +17 -2
- package/config/inbox_config.json +42 -23
- package/config/outbox_config.json +8 -7
- package/ecosystem.config.js-example +16 -0
- package/examples/memento_announce.jsonld +27 -0
- package/handler/{demo_inbox_handler.js → inbox_handler/demo.js} +1 -1
- package/handler/{accept_notification_handler.js → notification_handler/accept.js} +4 -4
- package/handler/notification_handler/add_timemap_link.js +51 -0
- package/handler/{eventlog_notification_handler.js → notification_handler/eventlog.js} +5 -11
- package/handler/notification_handler/jsonpath_filter.js +84 -0
- package/handler/notification_handler/multi.js +96 -0
- package/handler/{offer_memento_notification_handler.js → notification_handler/offer_memento.js} +6 -11
- package/handler/{send_notification_handler.js → notification_handler/send_notification.js} +3 -3
- package/handler/{type_filter_notification_handler.js → notification_handler/type_filter.js} +6 -16
- package/handler/{valid_artifact_notification_handler.js → notification_handler/valid_artifact.js} +4 -4
- package/handler/notification_handler/valid_eventlog.js +52 -0
- package/lib/handler.js +34 -24
- package/lib/util.js +39 -8
- package/package.json +7 -6
- package/handler/multi_notification_handler.js +0 -61
package/README.md
CHANGED
|
@@ -119,7 +119,7 @@ A handler that creates for an incoming notification an `Accept` notification in
|
|
|
119
119
|
|
|
120
120
|
A handler that updates an event log with the incoming notification.
|
|
121
121
|
|
|
122
|
-
Requires
|
|
122
|
+
Requires configuration properties:
|
|
123
123
|
|
|
124
124
|
- `log`: the path to the event log (starting from the `public` directory)
|
|
125
125
|
- `dir`: the path to a container to store the events (starting from the `public` directory)
|
|
@@ -127,6 +127,25 @@ Requires a configuration file with property `notification_handler.eventlog`:
|
|
|
127
127
|
The `log` and `dir` path may contain a `@artifact(:strip)?@` directive to fill in the
|
|
128
128
|
path of the current artifact. The `:strip` filter is used to strip an artifact path of a file extension. E.g. `path/artifact.html` becomes `path/artifact` when using a `:strip`.
|
|
129
129
|
|
|
130
|
+
### Json Path handler
|
|
131
|
+
|
|
132
|
+
A handler that accepts a notifiction when it matches one or more JSON paths
|
|
133
|
+
|
|
134
|
+
Requires configuration properties:
|
|
135
|
+
|
|
136
|
+
- anyOf : an array of json path matchers, the combination should be interpreted as a logical `OR`.
|
|
137
|
+
- every json path matcher is an array of single matchers, the combination should be interpered as a logical `AND`.
|
|
138
|
+
|
|
139
|
+
A single matcher needs two properties:
|
|
140
|
+
|
|
141
|
+
- path : a json path
|
|
142
|
+
- value : a value
|
|
143
|
+
|
|
144
|
+
The json path matches when one of:
|
|
145
|
+
|
|
146
|
+
- On the json path an array is found and the value is included in the array
|
|
147
|
+
- On the json path a string or number is found and the value is equal to this string or number
|
|
148
|
+
|
|
130
149
|
### Multi handler
|
|
131
150
|
|
|
132
151
|
A `handler/multi_notification_handler.js` is available to start multiple handler for each notification messages. The handlers to start are specified in a configuraton file that can be passed via the `config` parameter of an `handle_inbox`. In the commmand line tool `bin/ldn-inbox-server` the default location of such config file is `config/inbox_config.json` when processing an `@inbox`, and `config/outbox_config.json` when processing an `@outbox`.
|
|
@@ -135,19 +154,37 @@ A `handler/multi_notification_handler.js` is available to start multiple handler
|
|
|
135
154
|
|
|
136
155
|
A handler to `Offer` an event log to a memento server.
|
|
137
156
|
|
|
138
|
-
Requires
|
|
157
|
+
Requires configuration properties:
|
|
139
158
|
|
|
140
159
|
- `actor`: the LDN+AS2 `actor` to use in a notification
|
|
141
160
|
- `target`: the LDN+AS2 `target` to use in a notification
|
|
142
161
|
|
|
143
|
-
### Send handler
|
|
162
|
+
### Send notification handler
|
|
144
163
|
|
|
145
|
-
A
|
|
164
|
+
A handler to send notification that live in the `@outbox` via the LDN protocol to the LDN `target`.
|
|
146
165
|
|
|
147
|
-
###
|
|
166
|
+
### Type handler
|
|
167
|
+
|
|
168
|
+
A handler that accepts any notification with a type that matches one of the `anyOf` types.
|
|
169
|
+
|
|
170
|
+
### Valid artifact handler
|
|
148
171
|
|
|
149
172
|
A handler that validates the incoming notification and checks if the `object` or `context` contains an artifact that is part of the `public` resources. See 'Artifact support' below.
|
|
150
173
|
|
|
174
|
+
Generates the following options keys:
|
|
175
|
+
|
|
176
|
+
- artifact.id : the URL of the artifact
|
|
177
|
+
- artifact.path : the local path to the artifact
|
|
178
|
+
|
|
179
|
+
### Valid event log handler
|
|
180
|
+
|
|
181
|
+
A hander that validates the incoming notification and checks if the `object` or `context` contains an event log that is part of the `public` resources.
|
|
182
|
+
|
|
183
|
+
Generates the following options keys:
|
|
184
|
+
|
|
185
|
+
- eventlog.id : the URL of the event log
|
|
186
|
+
- eventlog.path : the local path of the event log
|
|
187
|
+
|
|
151
188
|
## Artifact support
|
|
152
189
|
|
|
153
190
|
This code base contains Event Notifications support for Data Node artifacts. See the examples
|
package/bin/ldn-inbox-server.js
CHANGED
|
@@ -69,15 +69,7 @@ program
|
|
|
69
69
|
}
|
|
70
70
|
break;
|
|
71
71
|
}
|
|
72
|
-
|
|
73
|
-
while(1) {
|
|
74
|
-
await handle_inbox(box,options);
|
|
75
|
-
await new Promise(resolve => setTimeout(resolve, options['loop']*1000));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
await handle_inbox(box,options);
|
|
80
|
-
}
|
|
72
|
+
await handle_inbox(box,options);
|
|
81
73
|
});
|
|
82
74
|
|
|
83
|
-
|
|
75
|
+
program.parse();
|
package/bin/post-notification.js
CHANGED
|
@@ -16,9 +16,24 @@ program
|
|
|
16
16
|
.argument('<url>','notification')
|
|
17
17
|
.argument('<file>','notification')
|
|
18
18
|
.action( async(url,file) => {
|
|
19
|
-
const to = url === '@me' ? `${INBOX_BASE_URL}/${INBOX_URL}` : url;
|
|
20
19
|
const json = JSON.parse(fs.readFileSync(file, { encoding: 'utf-8'}));
|
|
21
|
-
|
|
20
|
+
|
|
21
|
+
let to = url;
|
|
22
|
+
|
|
23
|
+
if (to === '@me') {
|
|
24
|
+
to = `${INBOX_BASE_URL}/${INBOX_URL}`;
|
|
25
|
+
}
|
|
26
|
+
else if (to === '@target') {
|
|
27
|
+
to = json['target']['inbox'];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!to) {
|
|
31
|
+
logger.error('no "to" inbox found');
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
logger.info(`sending notification to ${to}`);
|
|
35
|
+
await sendNotification(to,json);
|
|
36
|
+
}
|
|
22
37
|
});
|
|
23
38
|
|
|
24
39
|
program.parse();
|
package/config/inbox_config.json
CHANGED
|
@@ -1,31 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"notification_handler": {
|
|
3
|
-
"eventlog": {
|
|
4
|
-
"log": "@artifact:strip@.jsonld",
|
|
5
|
-
"dir": "@artifact:strip@"
|
|
6
|
-
},
|
|
7
3
|
"multi": {
|
|
8
4
|
"handlers": [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
[
|
|
6
|
+
{
|
|
7
|
+
"id": "handler/notification_handler/jsonpath_filter.js",
|
|
8
|
+
"anyOf": [
|
|
9
|
+
[
|
|
10
|
+
{ "path": "$.type" , "value": "Offer" }
|
|
11
|
+
]
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"handler/notification_handler/valid_artifact.js" ,
|
|
15
|
+
{
|
|
16
|
+
"id": "handler/notification_handler/eventlog.js",
|
|
17
|
+
"log": "@artifact:strip@.jsonld",
|
|
18
|
+
"dir": "@artifact:strip@"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "handler/notification_handler/offer_memento.js",
|
|
22
|
+
"actor": {
|
|
23
|
+
"id": "http://localhost:8000/profile/card#me" ,
|
|
24
|
+
"inbox": "http://localhost:8000/inbox/" ,
|
|
25
|
+
"type": "Service"
|
|
26
|
+
},
|
|
27
|
+
"target": {
|
|
28
|
+
"id": "http://localhost:8001/profile/card#me" ,
|
|
29
|
+
"inbox": "http://localhost:8001/inbox/" ,
|
|
30
|
+
"type": "Service"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
] ,
|
|
34
|
+
[
|
|
35
|
+
{
|
|
36
|
+
"id": "handler/notification_handler/jsonpath_filter.js",
|
|
37
|
+
"anyOf": [
|
|
38
|
+
[
|
|
39
|
+
{ "path": "$.type" , "value": "Announce" } ,
|
|
40
|
+
{ "path": "$.actor.id", "value": "https://labs.eventnotifications.net/service/m/profile/card.ttl" }
|
|
41
|
+
]
|
|
42
|
+
]
|
|
43
|
+
} ,
|
|
44
|
+
"handler/notification_handler/valid_eventlog.js",
|
|
45
|
+
"handler/notification_handler/add_timemap_link.js"
|
|
46
|
+
]
|
|
13
47
|
]
|
|
14
|
-
},
|
|
15
|
-
"offer_memento": {
|
|
16
|
-
"actor": {
|
|
17
|
-
"id": "http://localhost:8000/profile/card#me" ,
|
|
18
|
-
"inbox": "http://localhost:8000/inbox/" ,
|
|
19
|
-
"type": "Service"
|
|
20
|
-
},
|
|
21
|
-
"target": {
|
|
22
|
-
"id": "http://localhost:8001/profile/card#me" ,
|
|
23
|
-
"inbox": "http://localhost:8001/inbox/" ,
|
|
24
|
-
"type": "Service"
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
"type_filter": {
|
|
28
|
-
"anyOf": [ "Offer" ]
|
|
29
48
|
}
|
|
30
49
|
}
|
|
31
50
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"notification_handler": {
|
|
3
|
-
"eventlog": {
|
|
4
|
-
"log": "@artifact:strip@.jsonld",
|
|
5
|
-
"dir": "@artifact:strip@"
|
|
6
|
-
},
|
|
7
3
|
"multi": {
|
|
8
4
|
"handlers": [
|
|
9
|
-
|
|
10
|
-
"handler/
|
|
11
|
-
|
|
5
|
+
[
|
|
6
|
+
"handler/notification_handler/send_notification.js",
|
|
7
|
+
{
|
|
8
|
+
"id": "handler/eventlog_notification_handler.js",
|
|
9
|
+
"log": "@artifact:strip@.jsonld",
|
|
10
|
+
"dir": "@artifact:strip@"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
12
13
|
]
|
|
13
14
|
}
|
|
14
15
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
apps : [
|
|
3
|
+
{
|
|
4
|
+
name : "ldn-inbox-server",
|
|
5
|
+
script : "./bin/ldn-inbox-server.js start-server"
|
|
6
|
+
} ,
|
|
7
|
+
{
|
|
8
|
+
name : "ldn-inbox-inbox",
|
|
9
|
+
script : "LOG4JS=info ./bin/ldn-inbox-server.js handler @inbox --loop 20 -hn ./handler/notification_handler/multi.js"
|
|
10
|
+
} ,
|
|
11
|
+
{
|
|
12
|
+
name : "ldn-inbox-outbox",
|
|
13
|
+
script : "LOG4JS=info ./bin/ldn-inbox-server.js handler @outbox --loop 20 -hn ./handler/notification_handler/multi.js"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": [
|
|
3
|
+
"https://www.w3.org/ns/activitystreams",
|
|
4
|
+
{
|
|
5
|
+
"ietf": "https://www.iana.org/"
|
|
6
|
+
}
|
|
7
|
+
],
|
|
8
|
+
"type": "Announce",
|
|
9
|
+
"actor": {
|
|
10
|
+
"id": "https://labs.eventnotifications.net/service/m/profile/card.ttl",
|
|
11
|
+
"inbox": "https://labs.eventnotifications.net/service/m/inbox/",
|
|
12
|
+
"type": "Service"
|
|
13
|
+
},
|
|
14
|
+
"context": "http://localhost:8000/artifacts/artifact1.jsonld",
|
|
15
|
+
"inReplyTo": "urn:uuid:6E5FAF88-A7F1-47A4-B087-77345EBFF495",
|
|
16
|
+
"object": {
|
|
17
|
+
"id": "https://labs.eventnotifications.net/service/m/map/http://localhost:8000/artifacts/artifact1.jsonld",
|
|
18
|
+
"type": "Document",
|
|
19
|
+
"ietf:original": "http://localhost:8000/artifacts/artifact1.jsonld",
|
|
20
|
+
"ietf:memento": "https://labs.eventnotifications.net/service/m/memento/http://localhost:8000/artifacts/artifact1.jsonld/6c7f984b0702a16b6b9661ea7dca2db48fa8086d"
|
|
21
|
+
},
|
|
22
|
+
"target": {
|
|
23
|
+
"id": "http://193.190.80.48:56633/service/r/profile/card#me",
|
|
24
|
+
"type": "Service",
|
|
25
|
+
"inbox": "http://193.190.80.48:56633/service/r/inbox/"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -6,7 +6,7 @@ const fs = require('fs');
|
|
|
6
6
|
* To use it set it via the `--hi` option of `bin/ldn-inbox-server.js`, or
|
|
7
7
|
* the `inbox_handler` option of the `handle_inbox` function.
|
|
8
8
|
*/
|
|
9
|
-
async function handle({path,options}) {
|
|
9
|
+
async function handle({path,options,config}) {
|
|
10
10
|
console.log(`handleInbox(${path},..)`);
|
|
11
11
|
fs.readdir(path, (err,files) => {
|
|
12
12
|
files.forEach( (file) => {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const md5 = require('md5');
|
|
3
|
-
const { parseAsJSON } = require('
|
|
4
|
-
const logger = require('
|
|
3
|
+
const { parseAsJSON } = require('../../lib/util.js');
|
|
4
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Demonstration notification handler, that creates an 'Accept'
|
|
8
8
|
* notification for each incoming notification message and stores
|
|
9
9
|
* it in the outbox container.
|
|
10
10
|
*/
|
|
11
|
-
async function handle({path,options}) {
|
|
11
|
+
async function handle({path,options,config}) {
|
|
12
12
|
logger.info(`parsing notification ${path}`);
|
|
13
13
|
|
|
14
14
|
try {
|
|
@@ -47,7 +47,7 @@ async function handle({path,options}) {
|
|
|
47
47
|
}
|
|
48
48
|
catch(e) {
|
|
49
49
|
logger.error(`failed to process ${path}`);
|
|
50
|
-
logger.
|
|
50
|
+
logger.error(e);
|
|
51
51
|
return { path, options, success: false };
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const jp = require('jsonpath');
|
|
3
|
+
const { parseAsJSON } = require('../../lib/util.js');
|
|
4
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Demonstration event log handler
|
|
8
|
+
*/
|
|
9
|
+
async function handle({path,options,config}) {
|
|
10
|
+
logger.info(`parsing notification ${path}`);
|
|
11
|
+
|
|
12
|
+
const eventlog = options['eventlog'];
|
|
13
|
+
|
|
14
|
+
if (!eventlog) {
|
|
15
|
+
logger.error(`no eventlog option available (do you run valid_eventlog first?)`);
|
|
16
|
+
return { path, options, success: false };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const json = parseAsJSON(path);
|
|
21
|
+
|
|
22
|
+
const meta = parseAsJSON(`${eventlog['path']}.meta`);
|
|
23
|
+
|
|
24
|
+
const timemap = jp.query(json,'$.object.id');
|
|
25
|
+
const relation = `<${timemap}> ; rel="timemap"`;
|
|
26
|
+
|
|
27
|
+
let links = meta['Link'] || [];
|
|
28
|
+
|
|
29
|
+
if (links.includes(relation)) {
|
|
30
|
+
// Do nothing
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
links.push(`<${timemap}> ; rel="timemap"`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
meta['Link'] = links;
|
|
37
|
+
|
|
38
|
+
logger.info(`Writing ${meta['Link']} to ${eventlog['path']}.meta`);
|
|
39
|
+
|
|
40
|
+
fs.writeFileSync(`${eventlog['path']}.meta`,JSON.stringify(meta,null,4));
|
|
41
|
+
|
|
42
|
+
return { path, options, success: true };
|
|
43
|
+
}
|
|
44
|
+
catch(e) {
|
|
45
|
+
logger.error(`failed to process ${path}`);
|
|
46
|
+
logger.error(e);
|
|
47
|
+
return { path, options, success: false };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = { handle };
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const md5 = require('md5');
|
|
3
|
-
const fsPath = require('path');
|
|
4
3
|
const lockfile = require('proper-lockfile');
|
|
5
|
-
const
|
|
6
|
-
const logger = require('../lib/util.js').getLogger();
|
|
4
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* Demonstration event log handler
|
|
10
8
|
*/
|
|
11
|
-
async function handle({path,options}) {
|
|
9
|
+
async function handle({path,options,config}) {
|
|
12
10
|
logger.info(`parsing notification ${path}`);
|
|
13
11
|
|
|
14
|
-
const config = parseAsJSON(options['config']);
|
|
15
|
-
|
|
16
12
|
if (! config) {
|
|
17
13
|
logger.error('no configuration found for eventlog_notification_handler');
|
|
18
14
|
return { path, options, success: false };
|
|
19
15
|
}
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (! thisConfig || !thisConfig['log'] || !thisConfig['dir']) {
|
|
17
|
+
if (!config['log'] || !config['dir']) {
|
|
24
18
|
logger.error('no log/dir entry for notification_handler.eventlog configuration');
|
|
25
19
|
return { path, options, success: false };
|
|
26
20
|
}
|
|
@@ -30,8 +24,8 @@ async function handle({path,options}) {
|
|
|
30
24
|
`http://${options['host']}:${options['port']}` :
|
|
31
25
|
'http://localhost:8000';
|
|
32
26
|
|
|
33
|
-
let eventLog =
|
|
34
|
-
let eventDir =
|
|
27
|
+
let eventLog = config['log'];
|
|
28
|
+
let eventDir = config['dir'];
|
|
35
29
|
|
|
36
30
|
let artifactPath = undefined;
|
|
37
31
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const jp = require('jsonpath');
|
|
2
|
+
const { parseAsJSON } = require('../../lib/util.js');
|
|
3
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Demonstration notification handler, that checks if the notification
|
|
7
|
+
* matches a configurable list
|
|
8
|
+
*/
|
|
9
|
+
async function handle({path,options,config}) {
|
|
10
|
+
logger.info(`parsing notification ${path}`);
|
|
11
|
+
|
|
12
|
+
if (! config) {
|
|
13
|
+
logger.error('no configuration found for eventlog_notification_handler');
|
|
14
|
+
return { path, options, success: false };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (! (config['anyOf'] && Array.isArray(config['anyOf']))) {
|
|
18
|
+
logger.error('no anyOf entry in notification_handler.type_filer should be an array');
|
|
19
|
+
return { path, options, success: false };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const anyOf = config['anyOf'];
|
|
24
|
+
const json = parseAsJSON(path);
|
|
25
|
+
|
|
26
|
+
let isOk = false;
|
|
27
|
+
|
|
28
|
+
for (let i = 0 ; i < anyOf.length ; i++) {
|
|
29
|
+
let matchCount = 0;
|
|
30
|
+
for (let j = 0 ; j < anyOf[i].length ; j++) {
|
|
31
|
+
const anyPart = anyOf[i][j];
|
|
32
|
+
const path = anyPart['path'];
|
|
33
|
+
const value = anyPart['value'];
|
|
34
|
+
|
|
35
|
+
const jsonValue = jp.query(json,path);
|
|
36
|
+
|
|
37
|
+
if (jsonValue !== null || jsonValue !== undefined) {
|
|
38
|
+
if (Array.isArray(jsonValue)) {
|
|
39
|
+
if (jsonValue.includes(value)) {
|
|
40
|
+
// Yup ..
|
|
41
|
+
logger.info(`found ${path} includes ${value} `)
|
|
42
|
+
matchCount++;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Nope ..
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (typeof jsonValue === 'string' || typeof jsonValue === 'number') {
|
|
49
|
+
if (jsonValue === value) {
|
|
50
|
+
// Yup ..
|
|
51
|
+
logger.info(`found ${path} === ${value} `)
|
|
52
|
+
matchCount++
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Nope ..
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Nope ..
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (matchCount == anyOf[i].length) {
|
|
64
|
+
isOk = true;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (isOk) {
|
|
70
|
+
return { path, options, success: true };
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
logger.error(`notification does not pass jsonpath_filter check`);
|
|
74
|
+
return { path, options, success: false };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch(e) {
|
|
78
|
+
logger.error(`failed to process ${path}`);
|
|
79
|
+
logger.error(e);
|
|
80
|
+
return { path, options, success: false };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = { handle };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const { dynamic_handler , parseAsJSON } = require('../../lib/util.js');
|
|
2
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Demonstration notification handler that start multiple notification handlers.
|
|
6
|
+
* Requires a config file that specifies which handlers to start.
|
|
7
|
+
*/
|
|
8
|
+
async function handle({path,options}) {
|
|
9
|
+
let success = false;
|
|
10
|
+
|
|
11
|
+
const config = parseAsJSON(options['config']);
|
|
12
|
+
|
|
13
|
+
if (! config) {
|
|
14
|
+
logger.error('no configuration found for multi_notification_handler');
|
|
15
|
+
return { path, options, success: false };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const handlers = config['notification_handler']?.['multi']?.['handlers'];
|
|
19
|
+
|
|
20
|
+
if (! handlers) {
|
|
21
|
+
logger.error('no notification_handler.multi.handlers key in configuration file');
|
|
22
|
+
return { path, options, success: false };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
logger.info(`starting multi handler`);
|
|
26
|
+
|
|
27
|
+
let workflow_success = 0;
|
|
28
|
+
let workflow_errors = 0;
|
|
29
|
+
|
|
30
|
+
for (let i = 0 ; i < handlers.length ; i++) {
|
|
31
|
+
const workflow = handlers[i];
|
|
32
|
+
|
|
33
|
+
let thisWorkflow = true;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
for (let j = 0 ; j < workflow.length ; j++) {
|
|
37
|
+
let step = undefined;
|
|
38
|
+
let config = undefined;
|
|
39
|
+
|
|
40
|
+
if (typeof workflow[j] === 'string' || workflow[j] instanceof String) {
|
|
41
|
+
step = workflow[j];
|
|
42
|
+
config = {};
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
step = workflow[j]['id'];
|
|
46
|
+
delete workflow[j]['id'];
|
|
47
|
+
config = workflow[j];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
logger.info(`workflow[${i}] : starting ${step}`);
|
|
51
|
+
|
|
52
|
+
const handler = dynamic_handler(step,null);
|
|
53
|
+
|
|
54
|
+
if (! handler) {
|
|
55
|
+
throw new Error(`failed to load ${step}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const result = await handler({path,options,config});
|
|
59
|
+
|
|
60
|
+
if (result['success']) {
|
|
61
|
+
logger.info(`workflow[${i}] : finished ${step}`);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
logger.error(`workflow[${i}] : failed ${step}`);
|
|
65
|
+
thisWorkflow = false;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
logger.error(`failed to process ${path}`);
|
|
72
|
+
logger.error(e);
|
|
73
|
+
thisWorkflow = false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (thisWorkflow) {
|
|
77
|
+
workflow_success++;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
workflow_errors++;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (handlers.length > 0 && workflow_success > 0) {
|
|
85
|
+
success = true;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
success = false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
logger.info(`finished multi handler`);
|
|
92
|
+
|
|
93
|
+
return { path, options, success: success };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = { handle };
|
package/handler/{offer_memento_notification_handler.js → notification_handler/offer_memento.js}
RENAMED
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const md5 = require('md5');
|
|
3
|
-
const
|
|
4
|
-
const logger = require('../lib/util.js').getLogger();
|
|
3
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Demonstration notification handler, that creates an 'Offer'
|
|
8
7
|
* notification for each incoming notificaation to request the
|
|
9
8
|
* archivation of the event log.
|
|
10
9
|
*/
|
|
11
|
-
async function handle({path,options}) {
|
|
10
|
+
async function handle({path,options,config}) {
|
|
12
11
|
logger.info(`parsing notification ${path}`);
|
|
13
12
|
|
|
14
|
-
const config = parseAsJSON(options['config']);
|
|
15
|
-
|
|
16
13
|
if (! config) {
|
|
17
14
|
logger.error('no configuration found for offer_memento_notification_handler');
|
|
18
15
|
return { path, options, success: false };
|
|
19
16
|
}
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (! thisConfig || !thisConfig['actor'] || !thisConfig['target']) {
|
|
18
|
+
if (!config['actor'] || !config['target']) {
|
|
24
19
|
logger.error('no actor/target entry for notification_handler.eventlog configuration');
|
|
25
20
|
return { path, options, success: false };
|
|
26
21
|
}
|
|
@@ -42,12 +37,12 @@ async function handle({path,options}) {
|
|
|
42
37
|
{"schema": "https://schema.org/"}
|
|
43
38
|
],
|
|
44
39
|
type: 'Offer',
|
|
45
|
-
actor:
|
|
40
|
+
actor: config['actor'],
|
|
46
41
|
object: {
|
|
47
42
|
id: options['eventlog']['id'],
|
|
48
43
|
type: [ "Document", "schema:Dataset" ]
|
|
49
44
|
},
|
|
50
|
-
target:
|
|
45
|
+
target: config['target']
|
|
51
46
|
},null,4);
|
|
52
47
|
|
|
53
48
|
const outboxFile = options['outbox'] + '/' + md5(data) + '.jsonld';
|
|
@@ -60,7 +55,7 @@ async function handle({path,options}) {
|
|
|
60
55
|
}
|
|
61
56
|
catch(e) {
|
|
62
57
|
logger.error(`failed to process ${path}`);
|
|
63
|
-
logger.
|
|
58
|
+
logger.error(e);
|
|
64
59
|
return { path, options, success: false };
|
|
65
60
|
}
|
|
66
61
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const logger = require('
|
|
2
|
-
const { sendNotification , parseAsJSON } = require('
|
|
1
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
2
|
+
const { sendNotification , parseAsJSON } = require('../../lib/util.js');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Demonstration notification handler that sends a notification to a
|
|
6
6
|
* target inbox.
|
|
7
7
|
*/
|
|
8
|
-
async function handle({path,options}) {
|
|
8
|
+
async function handle({path,options,config}) {
|
|
9
9
|
try {
|
|
10
10
|
const data = parseAsJSON(path);
|
|
11
11
|
const type = data['type'];
|
|
@@ -1,29 +1,19 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const logger = require('../lib/util.js').getLogger();
|
|
1
|
+
const { parseAsJSON } = require('../../lib/util.js');
|
|
2
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Demonstration notification handler, that checks if the notification
|
|
7
6
|
* matches a configurable list
|
|
8
7
|
*/
|
|
9
|
-
async function handle({path,options}) {
|
|
8
|
+
async function handle({path,options,config}) {
|
|
10
9
|
logger.info(`parsing notification ${path}`);
|
|
11
10
|
|
|
12
|
-
const config = parseAsJSON(options['config']);
|
|
13
|
-
|
|
14
11
|
if (! config) {
|
|
15
12
|
logger.error('no configuration found for eventlog_notification_handler');
|
|
16
13
|
return { path, options, success: false };
|
|
17
14
|
}
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (! thisConfig) {
|
|
22
|
-
logger.error('no notification_handler.type_filer configuration');
|
|
23
|
-
return { path, options, success: false };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (! (thisConfig['anyOf'] && Array.isArray(thisConfig['anyOf']))) {
|
|
16
|
+
if (! (config['anyOf'] && Array.isArray(config['anyOf']))) {
|
|
27
17
|
logger.error('no anyOf entry in notification_handler.type_filer should be an array');
|
|
28
18
|
return { path, options, success: false };
|
|
29
19
|
}
|
|
@@ -38,7 +28,7 @@ async function handle({path,options}) {
|
|
|
38
28
|
let isOk = true ;
|
|
39
29
|
|
|
40
30
|
for (let i = 0 ; i < typeArray.length ; i++) {
|
|
41
|
-
if (
|
|
31
|
+
if (config['anyOf'].includes(typeArray[i])) {
|
|
42
32
|
// We are ok
|
|
43
33
|
}
|
|
44
34
|
else {
|
|
@@ -57,7 +47,7 @@ async function handle({path,options}) {
|
|
|
57
47
|
}
|
|
58
48
|
catch(e) {
|
|
59
49
|
logger.error(`failed to process ${path}`);
|
|
60
|
-
logger.
|
|
50
|
+
logger.error(e);
|
|
61
51
|
return { path, options, success: false };
|
|
62
52
|
}
|
|
63
53
|
}
|
package/handler/{valid_artifact_notification_handler.js → notification_handler/valid_artifact.js}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const { ldPropertyAsId , parseArtifact, parseAsJSON } = require('
|
|
2
|
-
const logger = require('
|
|
1
|
+
const { ldPropertyAsId , parseArtifact, parseAsJSON } = require('../../lib/util.js');
|
|
2
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Demonstration notification handler, that checks if the notification
|
|
6
6
|
* message contains an artifact that is known to the data node
|
|
7
7
|
*/
|
|
8
|
-
async function handle({path,options}) {
|
|
8
|
+
async function handle({path,options,config}) {
|
|
9
9
|
logger.info(`parsing notification ${path}`);
|
|
10
10
|
|
|
11
11
|
try {
|
|
@@ -47,7 +47,7 @@ async function handle({path,options}) {
|
|
|
47
47
|
}
|
|
48
48
|
catch(e) {
|
|
49
49
|
logger.error(`failed to process ${path}`);
|
|
50
|
-
logger.
|
|
50
|
+
logger.error(e);
|
|
51
51
|
return { path, options, success: false };
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const { ldPropertyAsId , parseEventLog, parseAsJSON } = require('../../lib/util.js');
|
|
2
|
+
const logger = require('../../lib/util.js').getLogger();
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Demonstration notification handler, that checks if the notification
|
|
6
|
+
* message contains an artifact that is known to the data node
|
|
7
|
+
*/
|
|
8
|
+
async function handle({path,options,config}) {
|
|
9
|
+
logger.info(`parsing notification ${path}`);
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
const json = parseAsJSON(path);
|
|
13
|
+
|
|
14
|
+
let eventlog = undefined;
|
|
15
|
+
|
|
16
|
+
if (ldPropertyAsId(json['context'])) {
|
|
17
|
+
eventlog = ldPropertyAsId(json['context']);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
logger.error(`failed to find valid context or object`);
|
|
21
|
+
return { path, options, success: false };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (! eventlog) {
|
|
25
|
+
logger.error(`failed to find eventlog`);
|
|
26
|
+
return { path, options, success: false };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const eventLogPath = parseEventLog(eventlog,options);
|
|
30
|
+
|
|
31
|
+
if (eventLogPath) {
|
|
32
|
+
// Storing the eventlog path to the options.
|
|
33
|
+
// Maybe bad practice..but it is a workflow attribute like in Nifi :P
|
|
34
|
+
options['eventlog'] = {
|
|
35
|
+
'id': eventlog ,
|
|
36
|
+
'path': eventLogPath
|
|
37
|
+
};
|
|
38
|
+
return { path, options, success: true };
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
logger.error(`artifact ${artifact} is not known here...`);
|
|
42
|
+
return { path, options, success: false };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch(e) {
|
|
46
|
+
logger.error(`failed to process ${path}`);
|
|
47
|
+
logger.error(e);
|
|
48
|
+
return { path, options, success: false };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = { handle };
|
package/lib/handler.js
CHANGED
|
@@ -23,35 +23,45 @@ async function defaultInboxHandler({path,options}) {
|
|
|
23
23
|
maxQueue: queue_size
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
26
|
+
const loopWait = options['loop'] || 0;
|
|
27
|
+
|
|
28
|
+
do {
|
|
29
|
+
try {
|
|
30
|
+
const [prms,locks] = await inboxProcessor(pool,path,options);
|
|
31
|
+
const results = await Promise.all(prms);
|
|
32
|
+
|
|
33
|
+
for (let i = 0 ; i < results.length ; i++) {
|
|
34
|
+
const result = results[i];
|
|
35
|
+
const success = result['success'];
|
|
36
|
+
const notification = result['path'];
|
|
37
|
+
|
|
38
|
+
if (success) {
|
|
39
|
+
logger.info(`processing ${notification} is a success`);
|
|
40
|
+
if (fs.existsSync(notification)) {
|
|
41
|
+
logger.debug(`removing ${notification}`);
|
|
42
|
+
fs.unlinkSync(result['path']);
|
|
43
|
+
}
|
|
40
44
|
}
|
|
45
|
+
else {
|
|
46
|
+
logger.warn(`processing ${notification} is a failure`);
|
|
47
|
+
logger.debug(`moving ${notification} to ${options['error']}`);
|
|
48
|
+
moveTo(notification,options['error']);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// release lock
|
|
52
|
+
if (locks[i]) locks[i]();
|
|
41
53
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
logger.error(e);
|
|
57
|
+
}
|
|
47
58
|
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
if (loopWait) {
|
|
60
|
+
logger.debug(`sleep ${loopWait} secs...`);
|
|
61
|
+
await new Promise(resolve => setTimeout(resolve, loopWait*1000));
|
|
50
62
|
}
|
|
51
63
|
}
|
|
52
|
-
|
|
53
|
-
logger.error(e);
|
|
54
|
-
}
|
|
64
|
+
while (loopWait > 0);
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
async function inboxProcessor(pool,path,options) {
|
package/lib/util.js
CHANGED
|
@@ -156,6 +156,40 @@ function ldPropertyAsId(object_or_string) {
|
|
|
156
156
|
|
|
157
157
|
function parseArtifact(url,options) {
|
|
158
158
|
logger.debug(`isArtifact(${url})?`);
|
|
159
|
+
|
|
160
|
+
const resource = parseLocalResource(url,options);
|
|
161
|
+
|
|
162
|
+
if (resource === null) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const { filePath , metaPath , json} = resource;
|
|
167
|
+
|
|
168
|
+
if (json['X-Artifact']) {
|
|
169
|
+
return filePath;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function parseEventLog(url,options) {
|
|
177
|
+
logger.debug(`isEventLog(${url})?`);
|
|
178
|
+
|
|
179
|
+
const resource = parseLocalResource(url,options);
|
|
180
|
+
|
|
181
|
+
if (resource === null) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const { filePath , metaPath , json} = resource;
|
|
186
|
+
|
|
187
|
+
return filePath;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function parseLocalResource(url,options) {
|
|
191
|
+
logger.debug(`isLocalResource(${url})?`);
|
|
192
|
+
|
|
159
193
|
const base = options['base'] ? options['base'] :
|
|
160
194
|
options['host'] && options['port'] ?
|
|
161
195
|
`http://${options['host']}:${options['port']}` :
|
|
@@ -163,9 +197,9 @@ function parseArtifact(url,options) {
|
|
|
163
197
|
|
|
164
198
|
const public = options['public'];
|
|
165
199
|
|
|
166
|
-
const filePath = url.substring(base.length + 1);
|
|
200
|
+
const filePath = `${public}/` + url.substring(base.length + 1);
|
|
167
201
|
|
|
168
|
-
const metaPath = `${
|
|
202
|
+
const metaPath = `${filePath}.meta`;
|
|
169
203
|
|
|
170
204
|
logger.debug(`searching ${metaPath}`);
|
|
171
205
|
|
|
@@ -181,12 +215,7 @@ function parseArtifact(url,options) {
|
|
|
181
215
|
return null;
|
|
182
216
|
}
|
|
183
217
|
|
|
184
|
-
|
|
185
|
-
return `${public}/${filePath}`;
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
return null;
|
|
189
|
-
}
|
|
218
|
+
return { filePath, metaPath, json };
|
|
190
219
|
}
|
|
191
220
|
|
|
192
221
|
module.exports = {
|
|
@@ -198,5 +227,7 @@ module.exports = {
|
|
|
198
227
|
dynamic_handler ,
|
|
199
228
|
parseAsJSON ,
|
|
200
229
|
parseArtifact ,
|
|
230
|
+
parseEventLog ,
|
|
231
|
+
parseLocalResource ,
|
|
201
232
|
ldPropertyAsId
|
|
202
233
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ldn-inbox-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "A demonstration Event Notifications Inbox server",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"author": "Patrick Hochstenbach <Patrick.Hochstenbach@UGent.be>",
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"server": "npx ldn-inbox-server start-server",
|
|
10
10
|
"demo-post": "curl -X POST -H 'Content-Type: application/ld+json' --data-binary '@examples/offer.jsonld' http://localhost:8000/inbox/",
|
|
11
|
-
"handle-inbox": "npx ldn-inbox-server handler @inbox -hn ./handler/
|
|
12
|
-
"handle-outbox": "npx ldn-inbox-server handler @outbox -hn ./handler/
|
|
13
|
-
"handle-eventlog": "npx ldn-inbox-server handler @inbox -hn handler/
|
|
14
|
-
"handle-inbox-multi": "npx ldn-inbox-server handler @inbox -hn ./handler/
|
|
15
|
-
"handle-outbox-multi": "npx ldn-inbox-server handler @outbox -hn ./handler/
|
|
11
|
+
"handle-inbox": "npx ldn-inbox-server handler @inbox -hn ./handler/notification_handler/accept.js",
|
|
12
|
+
"handle-outbox": "npx ldn-inbox-server handler @outbox -hn ./handler/notification_handler/send_notification.js",
|
|
13
|
+
"handle-eventlog": "npx ldn-inbox-server handler @inbox -hn handler/notification_handler/eventlog.js",
|
|
14
|
+
"handle-inbox-multi": "npx ldn-inbox-server handler @inbox -hn ./handler/notification_handler/multi.js",
|
|
15
|
+
"handle-outbox-multi": "npx ldn-inbox-server handler @outbox -hn ./handler/notification_handler/multi.js",
|
|
16
16
|
"clean": "rm -rf error/* inbox/* outbox/* public/events/* public/events/log/* public/artifacts/artifact1 public/artifacts/artifact2 public/artifacts/*.jsonld*"
|
|
17
17
|
},
|
|
18
18
|
"bin": "./bin/ldn-inbox-server.js",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"commander": "^12.0.0",
|
|
26
26
|
"dotenv": "^16.4.5",
|
|
27
27
|
"exponential-backoff": "^3.1.1",
|
|
28
|
+
"jsonpath": "^1.1.1",
|
|
28
29
|
"jsonschema": "^1.4.1",
|
|
29
30
|
"md5": "^2.3.0",
|
|
30
31
|
"mellon-server": "^1.0.8",
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const { dynamic_handler , parseAsJSON } = require('../lib/util');
|
|
2
|
-
const logger = require('../lib/util.js').getLogger();
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Demonstration notification handler that start multiple notification handlers.
|
|
6
|
-
* Requires a config file that specifies which handlers to start.
|
|
7
|
-
*/
|
|
8
|
-
async function handle({path,options}) {
|
|
9
|
-
let success = false;
|
|
10
|
-
|
|
11
|
-
const config = parseAsJSON(options['config']);
|
|
12
|
-
|
|
13
|
-
if (! config) {
|
|
14
|
-
logger.error('no configuration found for multi_notification_handler');
|
|
15
|
-
return { path, options, success: false };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const handlers = config['notification_handler']?.['multi']?.['handlers'];
|
|
19
|
-
|
|
20
|
-
if (! handlers) {
|
|
21
|
-
logger.error('no notification_handler.multi.handlers key in configuration file');
|
|
22
|
-
return { path, options, success: false };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
logger.info(`starting multi handler`);
|
|
27
|
-
|
|
28
|
-
for (let i = 0 ; i < handlers.length ; i++) {
|
|
29
|
-
logger.info(`starting ${handlers[i]}`);
|
|
30
|
-
|
|
31
|
-
const handler = dynamic_handler(handlers[i],null);
|
|
32
|
-
|
|
33
|
-
if (! handler) {
|
|
34
|
-
throw new Error(`failed to load ${handlers[i]}`);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const result = await handler({path,options});
|
|
38
|
-
|
|
39
|
-
if (result['success']) {
|
|
40
|
-
logger.info(`finished ${handlers[i]}`);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
throw new Error(`Eek! ${handlers[i]} failed`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
success = true;
|
|
48
|
-
}
|
|
49
|
-
catch (e) {
|
|
50
|
-
logger.error(`failed to process ${path}`);
|
|
51
|
-
logger.error(e);
|
|
52
|
-
|
|
53
|
-
success = false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
logger.info(`finished multi handler`);
|
|
57
|
-
|
|
58
|
-
return { path, options, success: success };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
module.exports = { handle };
|