node-opcua-server 2.76.1 → 2.76.2

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.
Files changed (59) hide show
  1. package/dist/base_server.d.ts +110 -110
  2. package/dist/base_server.js +473 -473
  3. package/dist/factory.d.ts +12 -12
  4. package/dist/factory.js +23 -23
  5. package/dist/filter/check_where_clause_on_address_space.d.ts +3 -3
  6. package/dist/filter/check_where_clause_on_address_space.js +22 -22
  7. package/dist/filter/extract_event_fields.d.ts +10 -10
  8. package/dist/filter/extract_event_fields.js +17 -17
  9. package/dist/helper.d.ts +10 -10
  10. package/dist/helper.js +75 -75
  11. package/dist/history_server_capabilities.d.ts +35 -35
  12. package/dist/history_server_capabilities.js +43 -43
  13. package/dist/i_channel_data.d.ts +13 -13
  14. package/dist/i_channel_data.js +2 -2
  15. package/dist/i_register_server_manager.d.ts +16 -16
  16. package/dist/i_register_server_manager.js +2 -2
  17. package/dist/i_server_side_publish_engine.d.ts +36 -36
  18. package/dist/i_server_side_publish_engine.js +49 -49
  19. package/dist/i_socket_data.d.ts +11 -11
  20. package/dist/i_socket_data.js +2 -2
  21. package/dist/index.d.ts +16 -16
  22. package/dist/index.js +32 -32
  23. package/dist/monitored_item.d.ts +177 -177
  24. package/dist/monitored_item.js +1001 -1001
  25. package/dist/node_sampler.d.ts +3 -3
  26. package/dist/node_sampler.js +75 -75
  27. package/dist/opcua_server.d.ts +747 -747
  28. package/dist/opcua_server.js +2431 -2431
  29. package/dist/queue.d.ts +11 -11
  30. package/dist/queue.js +71 -71
  31. package/dist/register_server_manager.d.ts +96 -96
  32. package/dist/register_server_manager.js +584 -584
  33. package/dist/register_server_manager_hidden.d.ts +17 -17
  34. package/dist/register_server_manager_hidden.js +27 -27
  35. package/dist/register_server_manager_mdns_only.d.ts +22 -22
  36. package/dist/register_server_manager_mdns_only.js +55 -55
  37. package/dist/server_capabilities.d.ts +148 -148
  38. package/dist/server_capabilities.js +92 -92
  39. package/dist/server_end_point.d.ts +183 -183
  40. package/dist/server_end_point.js +817 -817
  41. package/dist/server_engine.d.ts +317 -317
  42. package/dist/server_engine.js +1716 -1716
  43. package/dist/server_publish_engine.d.ts +113 -113
  44. package/dist/server_publish_engine.js +541 -541
  45. package/dist/server_publish_engine_for_orphan_subscriptions.d.ts +16 -16
  46. package/dist/server_publish_engine_for_orphan_subscriptions.js +51 -51
  47. package/dist/server_session.d.ts +182 -182
  48. package/dist/server_session.js +739 -739
  49. package/dist/server_subscription.d.ts +421 -421
  50. package/dist/server_subscription.js +1346 -1346
  51. package/dist/sessions_compatible_for_transfer.d.ts +2 -2
  52. package/dist/sessions_compatible_for_transfer.js +39 -39
  53. package/dist/user_manager.d.ts +32 -32
  54. package/dist/user_manager.js +74 -74
  55. package/dist/user_manager_ua.d.ts +3 -3
  56. package/dist/user_manager_ua.js +39 -39
  57. package/dist/validate_filter.d.ts +5 -5
  58. package/dist/validate_filter.js +60 -60
  59. package/package.json +42 -41
@@ -1,585 +1,585 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RegisterServerManager = exports.RegisterServerManagerStatus = void 0;
4
- /**
5
- * @module node-opcua-server
6
- */
7
- // tslint:disable:no-console
8
- const events_1 = require("events");
9
- const async = require("async");
10
- const chalk = require("chalk");
11
- const node_opcua_assert_1 = require("node-opcua-assert");
12
- const node_opcua_client_1 = require("node-opcua-client");
13
- const node_opcua_debug_1 = require("node-opcua-debug");
14
- const node_opcua_hostname_1 = require("node-opcua-hostname");
15
- const node_opcua_secure_channel_1 = require("node-opcua-secure-channel");
16
- const node_opcua_service_discovery_1 = require("node-opcua-service-discovery");
17
- const node_opcua_types_1 = require("node-opcua-types");
18
- const node_opcua_crypto_1 = require("node-opcua-crypto");
19
- const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
20
- const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
21
- const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
22
- var RegisterServerManagerStatus;
23
- (function (RegisterServerManagerStatus) {
24
- RegisterServerManagerStatus[RegisterServerManagerStatus["INACTIVE"] = 1] = "INACTIVE";
25
- RegisterServerManagerStatus[RegisterServerManagerStatus["INITIALIZING"] = 2] = "INITIALIZING";
26
- RegisterServerManagerStatus[RegisterServerManagerStatus["REGISTERING"] = 3] = "REGISTERING";
27
- RegisterServerManagerStatus[RegisterServerManagerStatus["WAITING"] = 4] = "WAITING";
28
- RegisterServerManagerStatus[RegisterServerManagerStatus["UNREGISTERING"] = 5] = "UNREGISTERING";
29
- })(RegisterServerManagerStatus = exports.RegisterServerManagerStatus || (exports.RegisterServerManagerStatus = {}));
30
- const g_DefaultRegistrationServerTimeout = 8 * 60 * 1000; // 8 minutes
31
- function securityPolicyLevel(securityPolicy) {
32
- switch (securityPolicy) {
33
- case node_opcua_secure_channel_1.SecurityPolicy.None:
34
- return 0;
35
- case node_opcua_secure_channel_1.SecurityPolicy.Basic128:
36
- return 1;
37
- case node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15:
38
- return 2;
39
- case node_opcua_secure_channel_1.SecurityPolicy.Basic192:
40
- return 3;
41
- case node_opcua_secure_channel_1.SecurityPolicy.Basic192Rsa15:
42
- return 4;
43
- case node_opcua_secure_channel_1.SecurityPolicy.Basic256:
44
- return 5;
45
- case node_opcua_secure_channel_1.SecurityPolicy.Basic256Rsa15:
46
- return 6;
47
- case node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep:
48
- return 7;
49
- case node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256:
50
- return 8;
51
- case node_opcua_secure_channel_1.SecurityPolicy.Aes256_Sha256_RsaPss:
52
- return 9;
53
- default:
54
- return 0;
55
- }
56
- }
57
- function sortEndpointBySecurityLevel(endpoints) {
58
- endpoints.sort((a, b) => {
59
- if (a.securityMode === b.securityMode) {
60
- if (a.securityPolicyUri === b.securityPolicyUri) {
61
- const sa = a.securityLevel;
62
- const sb = b.securityLevel;
63
- return sa < sb ? 1 : sa > sb ? -1 : 0;
64
- }
65
- else {
66
- const sa = securityPolicyLevel(a.securityPolicyUri);
67
- const sb = securityPolicyLevel(b.securityPolicyUri);
68
- return sa < sb ? 1 : sa > sb ? -1 : 0;
69
- }
70
- }
71
- else {
72
- return a.securityMode < b.securityMode ? 1 : 0;
73
- }
74
- });
75
- return endpoints;
76
- }
77
- function findSecureEndpoint(endpoints) {
78
- // we only care about binary tcp transport endpoint
79
- endpoints = endpoints.filter((e) => {
80
- return e.transportProfileUri === "http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary";
81
- });
82
- endpoints = endpoints.filter((e) => {
83
- return e.securityMode === node_opcua_secure_channel_1.MessageSecurityMode.SignAndEncrypt;
84
- });
85
- if (endpoints.length === 0) {
86
- endpoints = endpoints.filter((e) => {
87
- return e.securityMode === node_opcua_secure_channel_1.MessageSecurityMode.Sign;
88
- });
89
- }
90
- if (endpoints.length === 0) {
91
- endpoints = endpoints.filter((e) => {
92
- return e.securityMode === node_opcua_secure_channel_1.MessageSecurityMode.None;
93
- });
94
- }
95
- endpoints = sortEndpointBySecurityLevel(endpoints);
96
- return endpoints[0];
97
- }
98
- function constructRegisteredServer(server, isOnline) {
99
- var _a, _b, _c;
100
- const discoveryUrls = server.getDiscoveryUrls();
101
- (0, node_opcua_assert_1.assert)(!isOnline || discoveryUrls.length >= 1, "expecting some discoveryUrls if we go online ....");
102
- const info = (0, node_opcua_crypto_1.exploreCertificate)(server.getCertificate());
103
- const commonName = info.tbsCertificate.subject.commonName;
104
- const serverUri = (_a = info.tbsCertificate.extensions) === null || _a === void 0 ? void 0 : _a.subjectAltName.uniformResourceIdentifier[0];
105
- // istanbul ignore next
106
- if (serverUri !== server.serverInfo.applicationUri) {
107
- warningLog(chalk.yellow("Warning certificate uniformResourceIdentifier doesn't match serverInfo.applicationUri"), "\n subjectKeyIdentifier : ", (_b = info.tbsCertificate.extensions) === null || _b === void 0 ? void 0 : _b.subjectKeyIdentifier, "\n subjectAltName : ", (_c = info.tbsCertificate.extensions) === null || _c === void 0 ? void 0 : _c.subjectAltName, "\n commonName : ", info.tbsCertificate.subject.commonName, "\n serverInfo.applicationUri : ", server.serverInfo.applicationUri);
108
- }
109
- // istanbul ignore next
110
- if (!server.serverInfo.applicationName.text) {
111
- debugLog("warning: application name is missing");
112
- }
113
- // The globally unique identifier for the Server instance. The serverUri matches
114
- // the applicationUri from the ApplicationDescription defined in 7.1.
115
- const s = {
116
- serverUri: server.serverInfo.applicationUri,
117
- // The globally unique identifier for the Server product.
118
- productUri: server.serverInfo.productUri,
119
- serverNames: [
120
- {
121
- locale: "en-US",
122
- text: server.serverInfo.applicationName.text
123
- }
124
- ],
125
- serverType: server.serverType,
126
- discoveryUrls,
127
- gatewayServerUri: null,
128
- isOnline,
129
- semaphoreFilePath: null
130
- };
131
- return s;
132
- }
133
- function constructRegisterServerRequest(serverB, isOnline) {
134
- const server = constructRegisteredServer(serverB, isOnline);
135
- return new node_opcua_service_discovery_1.RegisterServerRequest({
136
- server
137
- });
138
- }
139
- function constructRegisterServer2Request(serverB, isOnline) {
140
- const server = constructRegisteredServer(serverB, isOnline);
141
- return new node_opcua_service_discovery_1.RegisterServer2Request({
142
- discoveryConfiguration: [
143
- new node_opcua_types_1.MdnsDiscoveryConfiguration({
144
- mdnsServerName: serverB.serverInfo.applicationUri,
145
- serverCapabilities: serverB.capabilitiesForMDNS
146
- })
147
- ],
148
- server
149
- });
150
- }
151
- const no_reconnect_connectivity_strategy = {
152
- initialDelay: 2000,
153
- maxDelay: 50000,
154
- maxRetry: 1,
155
- randomisationFactor: 0
156
- };
157
- const infinite_connectivity_strategy = {
158
- initialDelay: 2000,
159
- maxDelay: 50000,
160
- maxRetry: 10000000,
161
- randomisationFactor: 0
162
- };
163
- function sendRegisterServerRequest(server, client, isOnline, callback) {
164
- // try to send a RegisterServer2Request
165
- const request = constructRegisterServer2Request(server, isOnline);
166
- client.performMessageTransaction(request, (err, response) => {
167
- if (!err) {
168
- // RegisterServerResponse
169
- debugLog("RegisterServerManager#_registerServer sendRegisterServer2Request has succeeded (isOnline", isOnline, ")");
170
- (0, node_opcua_assert_1.assert)(response instanceof node_opcua_service_discovery_1.RegisterServer2Response);
171
- callback(err);
172
- }
173
- else {
174
- debugLog("RegisterServerManager#_registerServer sendRegisterServer2Request has failed " + "(isOnline", isOnline, ")");
175
- debugLog("RegisterServerManager#_registerServer" + " falling back to using sendRegisterServerRequest instead");
176
- // fall back to
177
- const request1 = constructRegisterServerRequest(server, isOnline);
178
- client.performMessageTransaction(request1, (err1, response1) => {
179
- if (!err1) {
180
- debugLog("RegisterServerManager#_registerServer sendRegisterServerRequest " + "has succeeded (isOnline", isOnline, ")");
181
- (0, node_opcua_assert_1.assert)(response1 instanceof node_opcua_service_discovery_1.RegisterServerResponse);
182
- }
183
- else {
184
- debugLog("RegisterServerManager#_registerServer sendRegisterServerRequest " + "has failed (isOnline", isOnline, ")");
185
- }
186
- callback(err1);
187
- });
188
- }
189
- });
190
- }
191
- /**
192
- * RegisterServerManager is responsible to Register an opcua server on a LDS or LDS-ME server
193
- * This class takes in charge :
194
- * - the initial registration of a server
195
- * - the regular registration renewal (every 8 minutes or so ...)
196
- * - dealing with cases where LDS is not up and running when server starts.
197
- * ( in this case the connection will be continuously attempted using the infinite
198
- * back-off strategy
199
- * - the un-registration of the server ( during shutdown for instance)
200
- *
201
- * Events:
202
- *
203
- * Emitted when the server is trying to registered the LDS
204
- * but when the connection to the lds has failed
205
- * serverRegistrationPending is sent when the backoff signal of the
206
- * connection process is rained
207
- * @event serverRegistrationPending
208
- *
209
- * emitted when the server is successfully registered to the LDS
210
- * @event serverRegistered
211
- *
212
- * emitted when the server has successfully renewed its registration to the LDS
213
- * @event serverRegistrationRenewed
214
- *
215
- * emitted when the server is successfully unregistered to the LDS
216
- * ( for instance during shutdown)
217
- * @event serverUnregistered
218
- *
219
- *
220
- * (LDS => Local Discovery Server)
221
- * @param options
222
- * @param options.server {OPCUAServer}
223
- * @param options.discoveryServerEndpointUrl {String}
224
- * @constructor
225
- */
226
- class RegisterServerManager extends events_1.EventEmitter {
227
- constructor(options) {
228
- super();
229
- this.state = RegisterServerManagerStatus.INACTIVE;
230
- this._registration_client = null;
231
- this._serverEndpoints = [];
232
- this.server = options.server;
233
- this._setState(RegisterServerManagerStatus.INACTIVE);
234
- this.timeout = g_DefaultRegistrationServerTimeout;
235
- this.discoveryServerEndpointUrl = options.discoveryServerEndpointUrl || "opc.tcp://localhost:4840";
236
- (0, node_opcua_assert_1.assert)(typeof this.discoveryServerEndpointUrl === "string");
237
- this._registrationTimerId = null;
238
- }
239
- dispose() {
240
- this.server = null;
241
- debugLog("RegisterServerManager#dispose", this.state.toString());
242
- (0, node_opcua_assert_1.assert)(this.state === RegisterServerManagerStatus.INACTIVE);
243
- if (this._registrationTimerId) {
244
- clearTimeout(this._registrationTimerId);
245
- this._registrationTimerId = null;
246
- }
247
- (0, node_opcua_assert_1.assert)(this._registrationTimerId === null, "stop has not been called");
248
- this.removeAllListeners();
249
- }
250
- _emitEvent(eventName) {
251
- setImmediate(() => {
252
- this.emit(eventName);
253
- });
254
- }
255
- _setState(status) {
256
- const previousState = this.state || RegisterServerManagerStatus.INACTIVE;
257
- debugLog("RegisterServerManager#setState : ", RegisterServerManagerStatus[previousState], " => ", RegisterServerManagerStatus[status]);
258
- this.state = status;
259
- }
260
- start(callback) {
261
- debugLog("RegisterServerManager#start");
262
- if (this.state !== RegisterServerManagerStatus.INACTIVE) {
263
- return callback(new Error("RegisterServer process already started")); // already started
264
- }
265
- this.discoveryServerEndpointUrl = (0, node_opcua_hostname_1.resolveFullyQualifiedDomainName)(this.discoveryServerEndpointUrl);
266
- // perform initial registration + automatic renewal
267
- this._establish_initial_connection((err) => {
268
- if (err) {
269
- debugLog("RegisterServerManager#start => _establish_initial_connection has failed");
270
- return callback(err);
271
- }
272
- if (this.state !== RegisterServerManagerStatus.INITIALIZING) {
273
- debugLog("RegisterServerManager#start => _establish_initial_connection has failed");
274
- return callback();
275
- }
276
- this._registerServer(true, (err1) => {
277
- if (this.state !== RegisterServerManagerStatus.REGISTERING) {
278
- debugLog("RegisterServerManager#start )=> Registration has been cancelled");
279
- return callback(new Error("Registration has been cancelled"));
280
- }
281
- if (err1) {
282
- warningLog("RegisterServerManager#start - registering server has failed ! \n" +
283
- "please check that your server certificate is accepted by the LDS");
284
- this._setState(RegisterServerManagerStatus.INACTIVE);
285
- this._emitEvent("serverRegistrationFailure");
286
- }
287
- else {
288
- this._emitEvent("serverRegistered");
289
- this._setState(RegisterServerManagerStatus.WAITING);
290
- this._trigger_next();
291
- }
292
- callback();
293
- });
294
- });
295
- }
296
- _establish_initial_connection(outer_callback) {
297
- var _a;
298
- /* istanbul ignore next */
299
- if (!this.server) {
300
- throw new Error("Internal Error");
301
- }
302
- debugLog("RegisterServerManager#_establish_initial_connection");
303
- (0, node_opcua_assert_1.assert)(!this._registration_client);
304
- (0, node_opcua_assert_1.assert)(typeof this.discoveryServerEndpointUrl === "string");
305
- (0, node_opcua_assert_1.assert)(this.state === RegisterServerManagerStatus.INACTIVE);
306
- this._setState(RegisterServerManagerStatus.INITIALIZING);
307
- this.selectedEndpoint = undefined;
308
- const applicationName = ((_a = (0, node_opcua_client_1.coerceLocalizedText)(this.server.serverInfo.applicationName)) === null || _a === void 0 ? void 0 : _a.text) || undefined;
309
- // Retry Strategy must be set
310
- this.server.serverCertificateManager.referenceCounter++;
311
- const registrationClient = node_opcua_client_1.OPCUAClientBase.create({
312
- clientName: this.server.serverInfo.applicationUri,
313
- applicationName,
314
- applicationUri: this.server.serverInfo.applicationUri,
315
- connectionStrategy: infinite_connectivity_strategy,
316
- clientCertificateManager: this.server.serverCertificateManager,
317
- certificateFile: this.server.certificateFile,
318
- privateKeyFile: this.server.privateKeyFile
319
- });
320
- this._registration_client = registrationClient;
321
- registrationClient.on("backoff", (nbRetry, delay) => {
322
- debugLog("RegisterServerManager - received backoff");
323
- warningLog(chalk.bgWhite.cyan("contacting discovery server backoff "), this.discoveryServerEndpointUrl, " attempt #", nbRetry, " retrying in ", delay / 1000.0, " seconds");
324
- this._emitEvent("serverRegistrationPending");
325
- });
326
- async.series([
327
- // do_initial_connection_with_discovery_server
328
- (callback) => {
329
- registrationClient.connect(this.discoveryServerEndpointUrl, (err) => {
330
- if (err) {
331
- debugLog("RegisterServerManager#_establish_initial_connection " + ": initial connection to server has failed");
332
- // xx debugLog(err);
333
- }
334
- return callback(err);
335
- });
336
- },
337
- // getEndpoints_on_discovery_server
338
- (callback) => {
339
- registrationClient.getEndpoints((err, endpoints) => {
340
- if (!err) {
341
- const endpoint = findSecureEndpoint(endpoints);
342
- if (!endpoint) {
343
- throw new Error("Cannot find Secure endpoint");
344
- }
345
- if (endpoint.serverCertificate) {
346
- (0, node_opcua_assert_1.assert)(endpoint.serverCertificate);
347
- this.selectedEndpoint = endpoint;
348
- }
349
- else {
350
- this.selectedEndpoint = undefined;
351
- }
352
- }
353
- else {
354
- debugLog("RegisterServerManager#_establish_initial_connection " + ": getEndpointsRequest has failed");
355
- debugLog(err);
356
- }
357
- callback(err);
358
- });
359
- },
360
- // function closing_discovery_server_connection
361
- (callback) => {
362
- this._serverEndpoints = registrationClient._serverEndpoints;
363
- registrationClient.disconnect((err) => {
364
- this._registration_client = null;
365
- callback(err);
366
- });
367
- },
368
- // function wait_a_little_bit
369
- (callback) => {
370
- setTimeout(callback, 10);
371
- }
372
- ], (err) => {
373
- debugLog("-------------------------------", !!err);
374
- if (this.state !== RegisterServerManagerStatus.INITIALIZING) {
375
- debugLog("RegisterServerManager#_establish_initial_connection has been interrupted ", RegisterServerManagerStatus[this.state]);
376
- this._setState(RegisterServerManagerStatus.INACTIVE);
377
- if (this._registration_client) {
378
- this._registration_client.disconnect((err2) => {
379
- this._registration_client = null;
380
- outer_callback(new Error("Initialization has been canceled"));
381
- });
382
- }
383
- else {
384
- outer_callback(new Error("Initialization has been canceled"));
385
- }
386
- return;
387
- }
388
- if (err) {
389
- this._setState(RegisterServerManagerStatus.INACTIVE);
390
- if (this._registration_client) {
391
- this._registration_client.disconnect((err1) => {
392
- this._registration_client = null;
393
- debugLog("#######", !!err1);
394
- outer_callback(err);
395
- });
396
- return;
397
- }
398
- }
399
- outer_callback();
400
- });
401
- }
402
- _trigger_next() {
403
- (0, node_opcua_assert_1.assert)(!this._registrationTimerId);
404
- (0, node_opcua_assert_1.assert)(this.state === RegisterServerManagerStatus.WAITING);
405
- // from spec 1.04 part 4:
406
- // The registration process is designed to be platform independent, robust and able to minimize
407
- // problems created by configuration errors. For that reason, Servers shall register themselves more
408
- // than once.
409
- // Under normal conditions, manually launched Servers shall periodically register with the Discovery
410
- // Server as long as they are able to receive connections from Clients. If a Server goes offline then it
411
- // shall register itself once more and indicate that it is going offline. The registration frequency
412
- // should be configurable; however, the maximum is 10 minutes. If an error occurs during registration
413
- // (e.g. the Discovery Server is not running) then the Server shall periodically re-attempt registration.
414
- // The frequency of these attempts should start at 1 second but gradually increase until the
415
- // registration frequency is the same as what it would be if no errors occurred. The recommended
416
- // approach would be to double the period of each attempt until reaching the maximum.
417
- // When an automatically launched Server (or its install program) registers with the Discovery Server
418
- // it shall provide a path to a semaphore file which the Discovery Server can use to determine if the
419
- // Server has been uninstalled from the machine. The Discovery Server shall have read access to
420
- // the file system that contains the file
421
- // install a registration
422
- debugLog("RegisterServerManager#_trigger_next " + ": installing timeout to perform registerServer renewal (timeout =", this.timeout, ")");
423
- this._registrationTimerId = setTimeout(() => {
424
- if (!this._registrationTimerId) {
425
- debugLog("RegisterServerManager => cancelling re registration");
426
- return;
427
- }
428
- this._registrationTimerId = null;
429
- debugLog("RegisterServerManager#_trigger_next : renewing RegisterServer");
430
- this._registerServer(true, (err) => {
431
- if (this.state !== RegisterServerManagerStatus.INACTIVE &&
432
- this.state !== RegisterServerManagerStatus.UNREGISTERING) {
433
- debugLog("RegisterServerManager#_trigger_next : renewed !", err);
434
- this._setState(RegisterServerManagerStatus.WAITING);
435
- this._emitEvent("serverRegistrationRenewed");
436
- this._trigger_next();
437
- }
438
- });
439
- }, this.timeout);
440
- }
441
- stop(callback) {
442
- debugLog("RegisterServerManager#stop");
443
- if (this._registrationTimerId) {
444
- debugLog("RegisterServerManager#stop :clearing timeout");
445
- clearTimeout(this._registrationTimerId);
446
- this._registrationTimerId = null;
447
- }
448
- this._cancel_pending_client_if_any(() => {
449
- debugLog("RegisterServerManager#stop _cancel_pending_client_if_any done ", this.state);
450
- if (!this.selectedEndpoint || this.state === RegisterServerManagerStatus.INACTIVE) {
451
- this.state = RegisterServerManagerStatus.INACTIVE;
452
- (0, node_opcua_assert_1.assert)(this._registrationTimerId === null);
453
- return callback();
454
- }
455
- this._registerServer(false, () => {
456
- this._setState(RegisterServerManagerStatus.INACTIVE);
457
- this._emitEvent("serverUnregistered");
458
- callback();
459
- });
460
- });
461
- }
462
- /**
463
- * @param isOnline
464
- * @param outer_callback
465
- * @private
466
- */
467
- _registerServer(isOnline, outer_callback) {
468
- var _a, _b;
469
- (0, node_opcua_assert_1.assert)(typeof outer_callback === "function");
470
- debugLog("RegisterServerManager#_registerServer isOnline:", isOnline, "selectedEndpoint: ", (_a = this.selectedEndpoint) === null || _a === void 0 ? void 0 : _a.endpointUrl);
471
- (0, node_opcua_assert_1.assert)(this.selectedEndpoint, "must have a selected endpoint => please call _establish_initial_connection");
472
- (0, node_opcua_assert_1.assert)(this.server.serverType !== undefined, " must have a valid server Type");
473
- // construct connection
474
- const server = this.server;
475
- const selectedEndpoint = this.selectedEndpoint;
476
- if (!selectedEndpoint) {
477
- warningLog("Warning : cannot register server - no endpoint available");
478
- return outer_callback(new Error("Cannot registerServer"));
479
- }
480
- server.serverCertificateManager.referenceCounter++;
481
- const applicationName = ((_b = (0, node_opcua_client_1.coerceLocalizedText)(server.serverInfo.applicationName)) === null || _b === void 0 ? void 0 : _b.text) || undefined;
482
- const theStatus = isOnline ? RegisterServerManagerStatus.REGISTERING : RegisterServerManagerStatus.UNREGISTERING;
483
- if (theStatus === this.state) {
484
- warningLog(`Warning the server is already in the ${RegisterServerManagerStatus[theStatus]} state`);
485
- return outer_callback();
486
- }
487
- if (!(this.state === RegisterServerManagerStatus.INITIALIZING || this.state === RegisterServerManagerStatus.WAITING)) {
488
- warningLog("Warning : cannot register server - wrong state ", RegisterServerManagerStatus[this.state]);
489
- return outer_callback();
490
- }
491
- ;
492
- this._setState(theStatus);
493
- if (this._registration_client) {
494
- warningLog(`Warning there is already a registering/unregistering task taking place: ${RegisterServerManagerStatus[this.state]} state`);
495
- }
496
- const options = {
497
- securityMode: selectedEndpoint.securityMode,
498
- securityPolicy: (0, node_opcua_secure_channel_1.coerceSecurityPolicy)(selectedEndpoint.securityPolicyUri),
499
- serverCertificate: selectedEndpoint.serverCertificate,
500
- clientCertificateManager: server.serverCertificateManager,
501
- certificateFile: server.certificateFile,
502
- privateKeyFile: server.privateKeyFile,
503
- // xx clientName: server.serverInfo.applicationUri!,
504
- applicationName,
505
- applicationUri: server.serverInfo.applicationUri,
506
- connectionStrategy: no_reconnect_connectivity_strategy,
507
- clientName: "server client to LDS " + RegisterServerManagerStatus[theStatus]
508
- };
509
- const client = node_opcua_client_1.OPCUAClientBase.create(options);
510
- const tmp = this._serverEndpoints;
511
- client._serverEndpoints = tmp;
512
- this._registration_client = client;
513
- debugLog(" lds endpoint uri : ", selectedEndpoint.endpointUrl);
514
- debugLog(" securityMode : ", node_opcua_secure_channel_1.MessageSecurityMode[selectedEndpoint.securityMode]);
515
- debugLog(" securityPolicy : ", selectedEndpoint.securityPolicyUri);
516
- async.series([
517
- // establish_connection_with_lds
518
- (callback) => {
519
- client.connect(selectedEndpoint.endpointUrl, (err) => {
520
- debugLog("establish_connection_with_lds => err = ", err);
521
- if (err) {
522
- debugLog("RegisterServerManager#_registerServer connection to client has failed");
523
- debugLog("RegisterServerManager#_registerServer " +
524
- "=> please check that you server certificate is trusted by the LDS");
525
- warningLog("RegisterServer to the LDS has failed during secure connection " +
526
- "=> please check that you server certificate is trusted by the LDS.", "\nerr: " + err.message, "\nLDS endpoint :", selectedEndpoint.endpointUrl, "\nsecurity mode :", node_opcua_secure_channel_1.MessageSecurityMode[selectedEndpoint.securityMode], "\nsecurity policy :", (0, node_opcua_secure_channel_1.coerceSecurityPolicy)(selectedEndpoint.securityPolicyUri));
527
- // xx debugLog(options);
528
- client.disconnect(() => {
529
- this._registration_client = null;
530
- debugLog("RegisterServerManager#_registerServer client disconnected");
531
- callback( /* intentionally no error propagation*/);
532
- });
533
- }
534
- else {
535
- callback();
536
- }
537
- });
538
- },
539
- (callback) => {
540
- if (!this._registration_client) {
541
- callback();
542
- return;
543
- }
544
- sendRegisterServerRequest(this.server, client, isOnline, (err) => {
545
- callback( /* intentionally no error propagation*/);
546
- });
547
- },
548
- // close_connection_with_lds
549
- (callback) => {
550
- if (!this._registration_client) {
551
- callback();
552
- return;
553
- }
554
- client.disconnect(callback);
555
- }
556
- ], (err) => {
557
- if (!this._registration_client) {
558
- debugLog("RegisterServerManager#_registerServer end (isOnline", isOnline, ") has been interrupted");
559
- outer_callback();
560
- return;
561
- }
562
- this._registration_client.disconnect(() => {
563
- debugLog("RegisterServerManager#_registerServer end (isOnline", isOnline, ")");
564
- this._registration_client = null;
565
- outer_callback(err);
566
- });
567
- });
568
- }
569
- _cancel_pending_client_if_any(callback) {
570
- debugLog("RegisterServerManager#_cancel_pending_client_if_any");
571
- if (this._registration_client) {
572
- debugLog("RegisterServerManager#_cancel_pending_client_if_any " + "=> wee need to disconnect _registration_client");
573
- this._registration_client.disconnect(() => {
574
- this._registration_client = null;
575
- this._cancel_pending_client_if_any(callback);
576
- });
577
- }
578
- else {
579
- debugLog("RegisterServerManager#_cancel_pending_client_if_any : done");
580
- callback();
581
- }
582
- }
583
- }
584
- exports.RegisterServerManager = RegisterServerManager;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RegisterServerManager = exports.RegisterServerManagerStatus = void 0;
4
+ /**
5
+ * @module node-opcua-server
6
+ */
7
+ // tslint:disable:no-console
8
+ const events_1 = require("events");
9
+ const async = require("async");
10
+ const chalk = require("chalk");
11
+ const node_opcua_assert_1 = require("node-opcua-assert");
12
+ const node_opcua_client_1 = require("node-opcua-client");
13
+ const node_opcua_debug_1 = require("node-opcua-debug");
14
+ const node_opcua_hostname_1 = require("node-opcua-hostname");
15
+ const node_opcua_secure_channel_1 = require("node-opcua-secure-channel");
16
+ const node_opcua_service_discovery_1 = require("node-opcua-service-discovery");
17
+ const node_opcua_types_1 = require("node-opcua-types");
18
+ const node_opcua_crypto_1 = require("node-opcua-crypto");
19
+ const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
20
+ const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
21
+ const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
22
+ var RegisterServerManagerStatus;
23
+ (function (RegisterServerManagerStatus) {
24
+ RegisterServerManagerStatus[RegisterServerManagerStatus["INACTIVE"] = 1] = "INACTIVE";
25
+ RegisterServerManagerStatus[RegisterServerManagerStatus["INITIALIZING"] = 2] = "INITIALIZING";
26
+ RegisterServerManagerStatus[RegisterServerManagerStatus["REGISTERING"] = 3] = "REGISTERING";
27
+ RegisterServerManagerStatus[RegisterServerManagerStatus["WAITING"] = 4] = "WAITING";
28
+ RegisterServerManagerStatus[RegisterServerManagerStatus["UNREGISTERING"] = 5] = "UNREGISTERING";
29
+ })(RegisterServerManagerStatus = exports.RegisterServerManagerStatus || (exports.RegisterServerManagerStatus = {}));
30
+ const g_DefaultRegistrationServerTimeout = 8 * 60 * 1000; // 8 minutes
31
+ function securityPolicyLevel(securityPolicy) {
32
+ switch (securityPolicy) {
33
+ case node_opcua_secure_channel_1.SecurityPolicy.None:
34
+ return 0;
35
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic128:
36
+ return 1;
37
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic128Rsa15:
38
+ return 2;
39
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic192:
40
+ return 3;
41
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic192Rsa15:
42
+ return 4;
43
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic256:
44
+ return 5;
45
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic256Rsa15:
46
+ return 6;
47
+ case node_opcua_secure_channel_1.SecurityPolicy.Aes128_Sha256_RsaOaep:
48
+ return 7;
49
+ case node_opcua_secure_channel_1.SecurityPolicy.Basic256Sha256:
50
+ return 8;
51
+ case node_opcua_secure_channel_1.SecurityPolicy.Aes256_Sha256_RsaPss:
52
+ return 9;
53
+ default:
54
+ return 0;
55
+ }
56
+ }
57
+ function sortEndpointBySecurityLevel(endpoints) {
58
+ endpoints.sort((a, b) => {
59
+ if (a.securityMode === b.securityMode) {
60
+ if (a.securityPolicyUri === b.securityPolicyUri) {
61
+ const sa = a.securityLevel;
62
+ const sb = b.securityLevel;
63
+ return sa < sb ? 1 : sa > sb ? -1 : 0;
64
+ }
65
+ else {
66
+ const sa = securityPolicyLevel(a.securityPolicyUri);
67
+ const sb = securityPolicyLevel(b.securityPolicyUri);
68
+ return sa < sb ? 1 : sa > sb ? -1 : 0;
69
+ }
70
+ }
71
+ else {
72
+ return a.securityMode < b.securityMode ? 1 : 0;
73
+ }
74
+ });
75
+ return endpoints;
76
+ }
77
+ function findSecureEndpoint(endpoints) {
78
+ // we only care about binary tcp transport endpoint
79
+ endpoints = endpoints.filter((e) => {
80
+ return e.transportProfileUri === "http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary";
81
+ });
82
+ endpoints = endpoints.filter((e) => {
83
+ return e.securityMode === node_opcua_secure_channel_1.MessageSecurityMode.SignAndEncrypt;
84
+ });
85
+ if (endpoints.length === 0) {
86
+ endpoints = endpoints.filter((e) => {
87
+ return e.securityMode === node_opcua_secure_channel_1.MessageSecurityMode.Sign;
88
+ });
89
+ }
90
+ if (endpoints.length === 0) {
91
+ endpoints = endpoints.filter((e) => {
92
+ return e.securityMode === node_opcua_secure_channel_1.MessageSecurityMode.None;
93
+ });
94
+ }
95
+ endpoints = sortEndpointBySecurityLevel(endpoints);
96
+ return endpoints[0];
97
+ }
98
+ function constructRegisteredServer(server, isOnline) {
99
+ var _a, _b, _c;
100
+ const discoveryUrls = server.getDiscoveryUrls();
101
+ (0, node_opcua_assert_1.assert)(!isOnline || discoveryUrls.length >= 1, "expecting some discoveryUrls if we go online ....");
102
+ const info = (0, node_opcua_crypto_1.exploreCertificate)(server.getCertificate());
103
+ const commonName = info.tbsCertificate.subject.commonName;
104
+ const serverUri = (_a = info.tbsCertificate.extensions) === null || _a === void 0 ? void 0 : _a.subjectAltName.uniformResourceIdentifier[0];
105
+ // istanbul ignore next
106
+ if (serverUri !== server.serverInfo.applicationUri) {
107
+ warningLog(chalk.yellow("Warning certificate uniformResourceIdentifier doesn't match serverInfo.applicationUri"), "\n subjectKeyIdentifier : ", (_b = info.tbsCertificate.extensions) === null || _b === void 0 ? void 0 : _b.subjectKeyIdentifier, "\n subjectAltName : ", (_c = info.tbsCertificate.extensions) === null || _c === void 0 ? void 0 : _c.subjectAltName, "\n commonName : ", info.tbsCertificate.subject.commonName, "\n serverInfo.applicationUri : ", server.serverInfo.applicationUri);
108
+ }
109
+ // istanbul ignore next
110
+ if (!server.serverInfo.applicationName.text) {
111
+ debugLog("warning: application name is missing");
112
+ }
113
+ // The globally unique identifier for the Server instance. The serverUri matches
114
+ // the applicationUri from the ApplicationDescription defined in 7.1.
115
+ const s = {
116
+ serverUri: server.serverInfo.applicationUri,
117
+ // The globally unique identifier for the Server product.
118
+ productUri: server.serverInfo.productUri,
119
+ serverNames: [
120
+ {
121
+ locale: "en-US",
122
+ text: server.serverInfo.applicationName.text
123
+ }
124
+ ],
125
+ serverType: server.serverType,
126
+ discoveryUrls,
127
+ gatewayServerUri: null,
128
+ isOnline,
129
+ semaphoreFilePath: null
130
+ };
131
+ return s;
132
+ }
133
+ function constructRegisterServerRequest(serverB, isOnline) {
134
+ const server = constructRegisteredServer(serverB, isOnline);
135
+ return new node_opcua_service_discovery_1.RegisterServerRequest({
136
+ server
137
+ });
138
+ }
139
+ function constructRegisterServer2Request(serverB, isOnline) {
140
+ const server = constructRegisteredServer(serverB, isOnline);
141
+ return new node_opcua_service_discovery_1.RegisterServer2Request({
142
+ discoveryConfiguration: [
143
+ new node_opcua_types_1.MdnsDiscoveryConfiguration({
144
+ mdnsServerName: serverB.serverInfo.applicationUri,
145
+ serverCapabilities: serverB.capabilitiesForMDNS
146
+ })
147
+ ],
148
+ server
149
+ });
150
+ }
151
+ const no_reconnect_connectivity_strategy = {
152
+ initialDelay: 2000,
153
+ maxDelay: 50000,
154
+ maxRetry: 1,
155
+ randomisationFactor: 0
156
+ };
157
+ const infinite_connectivity_strategy = {
158
+ initialDelay: 2000,
159
+ maxDelay: 50000,
160
+ maxRetry: 10000000,
161
+ randomisationFactor: 0
162
+ };
163
+ function sendRegisterServerRequest(server, client, isOnline, callback) {
164
+ // try to send a RegisterServer2Request
165
+ const request = constructRegisterServer2Request(server, isOnline);
166
+ client.performMessageTransaction(request, (err, response) => {
167
+ if (!err) {
168
+ // RegisterServerResponse
169
+ debugLog("RegisterServerManager#_registerServer sendRegisterServer2Request has succeeded (isOnline", isOnline, ")");
170
+ (0, node_opcua_assert_1.assert)(response instanceof node_opcua_service_discovery_1.RegisterServer2Response);
171
+ callback(err);
172
+ }
173
+ else {
174
+ debugLog("RegisterServerManager#_registerServer sendRegisterServer2Request has failed " + "(isOnline", isOnline, ")");
175
+ debugLog("RegisterServerManager#_registerServer" + " falling back to using sendRegisterServerRequest instead");
176
+ // fall back to
177
+ const request1 = constructRegisterServerRequest(server, isOnline);
178
+ client.performMessageTransaction(request1, (err1, response1) => {
179
+ if (!err1) {
180
+ debugLog("RegisterServerManager#_registerServer sendRegisterServerRequest " + "has succeeded (isOnline", isOnline, ")");
181
+ (0, node_opcua_assert_1.assert)(response1 instanceof node_opcua_service_discovery_1.RegisterServerResponse);
182
+ }
183
+ else {
184
+ debugLog("RegisterServerManager#_registerServer sendRegisterServerRequest " + "has failed (isOnline", isOnline, ")");
185
+ }
186
+ callback(err1);
187
+ });
188
+ }
189
+ });
190
+ }
191
+ /**
192
+ * RegisterServerManager is responsible to Register an opcua server on a LDS or LDS-ME server
193
+ * This class takes in charge :
194
+ * - the initial registration of a server
195
+ * - the regular registration renewal (every 8 minutes or so ...)
196
+ * - dealing with cases where LDS is not up and running when server starts.
197
+ * ( in this case the connection will be continuously attempted using the infinite
198
+ * back-off strategy
199
+ * - the un-registration of the server ( during shutdown for instance)
200
+ *
201
+ * Events:
202
+ *
203
+ * Emitted when the server is trying to registered the LDS
204
+ * but when the connection to the lds has failed
205
+ * serverRegistrationPending is sent when the backoff signal of the
206
+ * connection process is rained
207
+ * @event serverRegistrationPending
208
+ *
209
+ * emitted when the server is successfully registered to the LDS
210
+ * @event serverRegistered
211
+ *
212
+ * emitted when the server has successfully renewed its registration to the LDS
213
+ * @event serverRegistrationRenewed
214
+ *
215
+ * emitted when the server is successfully unregistered to the LDS
216
+ * ( for instance during shutdown)
217
+ * @event serverUnregistered
218
+ *
219
+ *
220
+ * (LDS => Local Discovery Server)
221
+ * @param options
222
+ * @param options.server {OPCUAServer}
223
+ * @param options.discoveryServerEndpointUrl {String}
224
+ * @constructor
225
+ */
226
+ class RegisterServerManager extends events_1.EventEmitter {
227
+ constructor(options) {
228
+ super();
229
+ this.state = RegisterServerManagerStatus.INACTIVE;
230
+ this._registration_client = null;
231
+ this._serverEndpoints = [];
232
+ this.server = options.server;
233
+ this._setState(RegisterServerManagerStatus.INACTIVE);
234
+ this.timeout = g_DefaultRegistrationServerTimeout;
235
+ this.discoveryServerEndpointUrl = options.discoveryServerEndpointUrl || "opc.tcp://localhost:4840";
236
+ (0, node_opcua_assert_1.assert)(typeof this.discoveryServerEndpointUrl === "string");
237
+ this._registrationTimerId = null;
238
+ }
239
+ dispose() {
240
+ this.server = null;
241
+ debugLog("RegisterServerManager#dispose", this.state.toString());
242
+ (0, node_opcua_assert_1.assert)(this.state === RegisterServerManagerStatus.INACTIVE);
243
+ if (this._registrationTimerId) {
244
+ clearTimeout(this._registrationTimerId);
245
+ this._registrationTimerId = null;
246
+ }
247
+ (0, node_opcua_assert_1.assert)(this._registrationTimerId === null, "stop has not been called");
248
+ this.removeAllListeners();
249
+ }
250
+ _emitEvent(eventName) {
251
+ setImmediate(() => {
252
+ this.emit(eventName);
253
+ });
254
+ }
255
+ _setState(status) {
256
+ const previousState = this.state || RegisterServerManagerStatus.INACTIVE;
257
+ debugLog("RegisterServerManager#setState : ", RegisterServerManagerStatus[previousState], " => ", RegisterServerManagerStatus[status]);
258
+ this.state = status;
259
+ }
260
+ start(callback) {
261
+ debugLog("RegisterServerManager#start");
262
+ if (this.state !== RegisterServerManagerStatus.INACTIVE) {
263
+ return callback(new Error("RegisterServer process already started")); // already started
264
+ }
265
+ this.discoveryServerEndpointUrl = (0, node_opcua_hostname_1.resolveFullyQualifiedDomainName)(this.discoveryServerEndpointUrl);
266
+ // perform initial registration + automatic renewal
267
+ this._establish_initial_connection((err) => {
268
+ if (err) {
269
+ debugLog("RegisterServerManager#start => _establish_initial_connection has failed");
270
+ return callback(err);
271
+ }
272
+ if (this.state !== RegisterServerManagerStatus.INITIALIZING) {
273
+ debugLog("RegisterServerManager#start => _establish_initial_connection has failed");
274
+ return callback();
275
+ }
276
+ this._registerServer(true, (err1) => {
277
+ if (this.state !== RegisterServerManagerStatus.REGISTERING) {
278
+ debugLog("RegisterServerManager#start )=> Registration has been cancelled");
279
+ return callback(new Error("Registration has been cancelled"));
280
+ }
281
+ if (err1) {
282
+ warningLog("RegisterServerManager#start - registering server has failed ! \n" +
283
+ "please check that your server certificate is accepted by the LDS");
284
+ this._setState(RegisterServerManagerStatus.INACTIVE);
285
+ this._emitEvent("serverRegistrationFailure");
286
+ }
287
+ else {
288
+ this._emitEvent("serverRegistered");
289
+ this._setState(RegisterServerManagerStatus.WAITING);
290
+ this._trigger_next();
291
+ }
292
+ callback();
293
+ });
294
+ });
295
+ }
296
+ _establish_initial_connection(outer_callback) {
297
+ var _a;
298
+ /* istanbul ignore next */
299
+ if (!this.server) {
300
+ throw new Error("Internal Error");
301
+ }
302
+ debugLog("RegisterServerManager#_establish_initial_connection");
303
+ (0, node_opcua_assert_1.assert)(!this._registration_client);
304
+ (0, node_opcua_assert_1.assert)(typeof this.discoveryServerEndpointUrl === "string");
305
+ (0, node_opcua_assert_1.assert)(this.state === RegisterServerManagerStatus.INACTIVE);
306
+ this._setState(RegisterServerManagerStatus.INITIALIZING);
307
+ this.selectedEndpoint = undefined;
308
+ const applicationName = ((_a = (0, node_opcua_client_1.coerceLocalizedText)(this.server.serverInfo.applicationName)) === null || _a === void 0 ? void 0 : _a.text) || undefined;
309
+ // Retry Strategy must be set
310
+ this.server.serverCertificateManager.referenceCounter++;
311
+ const registrationClient = node_opcua_client_1.OPCUAClientBase.create({
312
+ clientName: this.server.serverInfo.applicationUri,
313
+ applicationName,
314
+ applicationUri: this.server.serverInfo.applicationUri,
315
+ connectionStrategy: infinite_connectivity_strategy,
316
+ clientCertificateManager: this.server.serverCertificateManager,
317
+ certificateFile: this.server.certificateFile,
318
+ privateKeyFile: this.server.privateKeyFile
319
+ });
320
+ this._registration_client = registrationClient;
321
+ registrationClient.on("backoff", (nbRetry, delay) => {
322
+ debugLog("RegisterServerManager - received backoff");
323
+ warningLog(chalk.bgWhite.cyan("contacting discovery server backoff "), this.discoveryServerEndpointUrl, " attempt #", nbRetry, " retrying in ", delay / 1000.0, " seconds");
324
+ this._emitEvent("serverRegistrationPending");
325
+ });
326
+ async.series([
327
+ // do_initial_connection_with_discovery_server
328
+ (callback) => {
329
+ registrationClient.connect(this.discoveryServerEndpointUrl, (err) => {
330
+ if (err) {
331
+ debugLog("RegisterServerManager#_establish_initial_connection " + ": initial connection to server has failed");
332
+ // xx debugLog(err);
333
+ }
334
+ return callback(err);
335
+ });
336
+ },
337
+ // getEndpoints_on_discovery_server
338
+ (callback) => {
339
+ registrationClient.getEndpoints((err, endpoints) => {
340
+ if (!err) {
341
+ const endpoint = findSecureEndpoint(endpoints);
342
+ if (!endpoint) {
343
+ throw new Error("Cannot find Secure endpoint");
344
+ }
345
+ if (endpoint.serverCertificate) {
346
+ (0, node_opcua_assert_1.assert)(endpoint.serverCertificate);
347
+ this.selectedEndpoint = endpoint;
348
+ }
349
+ else {
350
+ this.selectedEndpoint = undefined;
351
+ }
352
+ }
353
+ else {
354
+ debugLog("RegisterServerManager#_establish_initial_connection " + ": getEndpointsRequest has failed");
355
+ debugLog(err);
356
+ }
357
+ callback(err);
358
+ });
359
+ },
360
+ // function closing_discovery_server_connection
361
+ (callback) => {
362
+ this._serverEndpoints = registrationClient._serverEndpoints;
363
+ registrationClient.disconnect((err) => {
364
+ this._registration_client = null;
365
+ callback(err);
366
+ });
367
+ },
368
+ // function wait_a_little_bit
369
+ (callback) => {
370
+ setTimeout(callback, 10);
371
+ }
372
+ ], (err) => {
373
+ debugLog("-------------------------------", !!err);
374
+ if (this.state !== RegisterServerManagerStatus.INITIALIZING) {
375
+ debugLog("RegisterServerManager#_establish_initial_connection has been interrupted ", RegisterServerManagerStatus[this.state]);
376
+ this._setState(RegisterServerManagerStatus.INACTIVE);
377
+ if (this._registration_client) {
378
+ this._registration_client.disconnect((err2) => {
379
+ this._registration_client = null;
380
+ outer_callback(new Error("Initialization has been canceled"));
381
+ });
382
+ }
383
+ else {
384
+ outer_callback(new Error("Initialization has been canceled"));
385
+ }
386
+ return;
387
+ }
388
+ if (err) {
389
+ this._setState(RegisterServerManagerStatus.INACTIVE);
390
+ if (this._registration_client) {
391
+ this._registration_client.disconnect((err1) => {
392
+ this._registration_client = null;
393
+ debugLog("#######", !!err1);
394
+ outer_callback(err);
395
+ });
396
+ return;
397
+ }
398
+ }
399
+ outer_callback();
400
+ });
401
+ }
402
+ _trigger_next() {
403
+ (0, node_opcua_assert_1.assert)(!this._registrationTimerId);
404
+ (0, node_opcua_assert_1.assert)(this.state === RegisterServerManagerStatus.WAITING);
405
+ // from spec 1.04 part 4:
406
+ // The registration process is designed to be platform independent, robust and able to minimize
407
+ // problems created by configuration errors. For that reason, Servers shall register themselves more
408
+ // than once.
409
+ // Under normal conditions, manually launched Servers shall periodically register with the Discovery
410
+ // Server as long as they are able to receive connections from Clients. If a Server goes offline then it
411
+ // shall register itself once more and indicate that it is going offline. The registration frequency
412
+ // should be configurable; however, the maximum is 10 minutes. If an error occurs during registration
413
+ // (e.g. the Discovery Server is not running) then the Server shall periodically re-attempt registration.
414
+ // The frequency of these attempts should start at 1 second but gradually increase until the
415
+ // registration frequency is the same as what it would be if no errors occurred. The recommended
416
+ // approach would be to double the period of each attempt until reaching the maximum.
417
+ // When an automatically launched Server (or its install program) registers with the Discovery Server
418
+ // it shall provide a path to a semaphore file which the Discovery Server can use to determine if the
419
+ // Server has been uninstalled from the machine. The Discovery Server shall have read access to
420
+ // the file system that contains the file
421
+ // install a registration
422
+ debugLog("RegisterServerManager#_trigger_next " + ": installing timeout to perform registerServer renewal (timeout =", this.timeout, ")");
423
+ this._registrationTimerId = setTimeout(() => {
424
+ if (!this._registrationTimerId) {
425
+ debugLog("RegisterServerManager => cancelling re registration");
426
+ return;
427
+ }
428
+ this._registrationTimerId = null;
429
+ debugLog("RegisterServerManager#_trigger_next : renewing RegisterServer");
430
+ this._registerServer(true, (err) => {
431
+ if (this.state !== RegisterServerManagerStatus.INACTIVE &&
432
+ this.state !== RegisterServerManagerStatus.UNREGISTERING) {
433
+ debugLog("RegisterServerManager#_trigger_next : renewed !", err);
434
+ this._setState(RegisterServerManagerStatus.WAITING);
435
+ this._emitEvent("serverRegistrationRenewed");
436
+ this._trigger_next();
437
+ }
438
+ });
439
+ }, this.timeout);
440
+ }
441
+ stop(callback) {
442
+ debugLog("RegisterServerManager#stop");
443
+ if (this._registrationTimerId) {
444
+ debugLog("RegisterServerManager#stop :clearing timeout");
445
+ clearTimeout(this._registrationTimerId);
446
+ this._registrationTimerId = null;
447
+ }
448
+ this._cancel_pending_client_if_any(() => {
449
+ debugLog("RegisterServerManager#stop _cancel_pending_client_if_any done ", this.state);
450
+ if (!this.selectedEndpoint || this.state === RegisterServerManagerStatus.INACTIVE) {
451
+ this.state = RegisterServerManagerStatus.INACTIVE;
452
+ (0, node_opcua_assert_1.assert)(this._registrationTimerId === null);
453
+ return callback();
454
+ }
455
+ this._registerServer(false, () => {
456
+ this._setState(RegisterServerManagerStatus.INACTIVE);
457
+ this._emitEvent("serverUnregistered");
458
+ callback();
459
+ });
460
+ });
461
+ }
462
+ /**
463
+ * @param isOnline
464
+ * @param outer_callback
465
+ * @private
466
+ */
467
+ _registerServer(isOnline, outer_callback) {
468
+ var _a, _b;
469
+ (0, node_opcua_assert_1.assert)(typeof outer_callback === "function");
470
+ debugLog("RegisterServerManager#_registerServer isOnline:", isOnline, "selectedEndpoint: ", (_a = this.selectedEndpoint) === null || _a === void 0 ? void 0 : _a.endpointUrl);
471
+ (0, node_opcua_assert_1.assert)(this.selectedEndpoint, "must have a selected endpoint => please call _establish_initial_connection");
472
+ (0, node_opcua_assert_1.assert)(this.server.serverType !== undefined, " must have a valid server Type");
473
+ // construct connection
474
+ const server = this.server;
475
+ const selectedEndpoint = this.selectedEndpoint;
476
+ if (!selectedEndpoint) {
477
+ warningLog("Warning : cannot register server - no endpoint available");
478
+ return outer_callback(new Error("Cannot registerServer"));
479
+ }
480
+ server.serverCertificateManager.referenceCounter++;
481
+ const applicationName = ((_b = (0, node_opcua_client_1.coerceLocalizedText)(server.serverInfo.applicationName)) === null || _b === void 0 ? void 0 : _b.text) || undefined;
482
+ const theStatus = isOnline ? RegisterServerManagerStatus.REGISTERING : RegisterServerManagerStatus.UNREGISTERING;
483
+ if (theStatus === this.state) {
484
+ warningLog(`Warning the server is already in the ${RegisterServerManagerStatus[theStatus]} state`);
485
+ return outer_callback();
486
+ }
487
+ if (!(this.state === RegisterServerManagerStatus.INITIALIZING || this.state === RegisterServerManagerStatus.WAITING)) {
488
+ warningLog("Warning : cannot register server - wrong state ", RegisterServerManagerStatus[this.state]);
489
+ return outer_callback();
490
+ }
491
+ ;
492
+ this._setState(theStatus);
493
+ if (this._registration_client) {
494
+ warningLog(`Warning there is already a registering/unregistering task taking place: ${RegisterServerManagerStatus[this.state]} state`);
495
+ }
496
+ const options = {
497
+ securityMode: selectedEndpoint.securityMode,
498
+ securityPolicy: (0, node_opcua_secure_channel_1.coerceSecurityPolicy)(selectedEndpoint.securityPolicyUri),
499
+ serverCertificate: selectedEndpoint.serverCertificate,
500
+ clientCertificateManager: server.serverCertificateManager,
501
+ certificateFile: server.certificateFile,
502
+ privateKeyFile: server.privateKeyFile,
503
+ // xx clientName: server.serverInfo.applicationUri!,
504
+ applicationName,
505
+ applicationUri: server.serverInfo.applicationUri,
506
+ connectionStrategy: no_reconnect_connectivity_strategy,
507
+ clientName: "server client to LDS " + RegisterServerManagerStatus[theStatus]
508
+ };
509
+ const client = node_opcua_client_1.OPCUAClientBase.create(options);
510
+ const tmp = this._serverEndpoints;
511
+ client._serverEndpoints = tmp;
512
+ this._registration_client = client;
513
+ debugLog(" lds endpoint uri : ", selectedEndpoint.endpointUrl);
514
+ debugLog(" securityMode : ", node_opcua_secure_channel_1.MessageSecurityMode[selectedEndpoint.securityMode]);
515
+ debugLog(" securityPolicy : ", selectedEndpoint.securityPolicyUri);
516
+ async.series([
517
+ // establish_connection_with_lds
518
+ (callback) => {
519
+ client.connect(selectedEndpoint.endpointUrl, (err) => {
520
+ debugLog("establish_connection_with_lds => err = ", err);
521
+ if (err) {
522
+ debugLog("RegisterServerManager#_registerServer connection to client has failed");
523
+ debugLog("RegisterServerManager#_registerServer " +
524
+ "=> please check that you server certificate is trusted by the LDS");
525
+ warningLog("RegisterServer to the LDS has failed during secure connection " +
526
+ "=> please check that you server certificate is trusted by the LDS.", "\nerr: " + err.message, "\nLDS endpoint :", selectedEndpoint.endpointUrl, "\nsecurity mode :", node_opcua_secure_channel_1.MessageSecurityMode[selectedEndpoint.securityMode], "\nsecurity policy :", (0, node_opcua_secure_channel_1.coerceSecurityPolicy)(selectedEndpoint.securityPolicyUri));
527
+ // xx debugLog(options);
528
+ client.disconnect(() => {
529
+ this._registration_client = null;
530
+ debugLog("RegisterServerManager#_registerServer client disconnected");
531
+ callback( /* intentionally no error propagation*/);
532
+ });
533
+ }
534
+ else {
535
+ callback();
536
+ }
537
+ });
538
+ },
539
+ (callback) => {
540
+ if (!this._registration_client) {
541
+ callback();
542
+ return;
543
+ }
544
+ sendRegisterServerRequest(this.server, client, isOnline, (err) => {
545
+ callback( /* intentionally no error propagation*/);
546
+ });
547
+ },
548
+ // close_connection_with_lds
549
+ (callback) => {
550
+ if (!this._registration_client) {
551
+ callback();
552
+ return;
553
+ }
554
+ client.disconnect(callback);
555
+ }
556
+ ], (err) => {
557
+ if (!this._registration_client) {
558
+ debugLog("RegisterServerManager#_registerServer end (isOnline", isOnline, ") has been interrupted");
559
+ outer_callback();
560
+ return;
561
+ }
562
+ this._registration_client.disconnect(() => {
563
+ debugLog("RegisterServerManager#_registerServer end (isOnline", isOnline, ")");
564
+ this._registration_client = null;
565
+ outer_callback(err);
566
+ });
567
+ });
568
+ }
569
+ _cancel_pending_client_if_any(callback) {
570
+ debugLog("RegisterServerManager#_cancel_pending_client_if_any");
571
+ if (this._registration_client) {
572
+ debugLog("RegisterServerManager#_cancel_pending_client_if_any " + "=> wee need to disconnect _registration_client");
573
+ this._registration_client.disconnect(() => {
574
+ this._registration_client = null;
575
+ this._cancel_pending_client_if_any(callback);
576
+ });
577
+ }
578
+ else {
579
+ debugLog("RegisterServerManager#_cancel_pending_client_if_any : done");
580
+ callback();
581
+ }
582
+ }
583
+ }
584
+ exports.RegisterServerManager = RegisterServerManager;
585
585
  //# sourceMappingURL=register_server_manager.js.map