node-opcua-server 2.156.0 → 2.158.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.
Files changed (54) hide show
  1. package/dist/addressSpace_accessor.js +1 -0
  2. package/dist/addressSpace_accessor.js.map +1 -1
  3. package/dist/base_server.js +7 -1
  4. package/dist/base_server.js.map +1 -1
  5. package/dist/factory.js +1 -0
  6. package/dist/factory.js.map +1 -1
  7. package/dist/history_server_capabilities.js +14 -0
  8. package/dist/history_server_capabilities.js.map +1 -1
  9. package/dist/i_register_server_manager.d.ts +63 -3
  10. package/dist/i_register_server_manager.js +47 -0
  11. package/dist/i_register_server_manager.js.map +1 -1
  12. package/dist/i_server_side_publish_engine.js +4 -0
  13. package/dist/i_server_side_publish_engine.js.map +1 -1
  14. package/dist/index.d.ts +22 -0
  15. package/dist/index.js +22 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/monitored_item.d.ts +3 -6
  18. package/dist/monitored_item.js +44 -17
  19. package/dist/monitored_item.js.map +1 -1
  20. package/dist/opcua_server.js +44 -26
  21. package/dist/opcua_server.js.map +1 -1
  22. package/dist/queue.js +2 -1
  23. package/dist/queue.js.map +1 -1
  24. package/dist/register_server_manager.d.ts +14 -26
  25. package/dist/register_server_manager.js +282 -293
  26. package/dist/register_server_manager.js.map +1 -1
  27. package/dist/register_server_manager_hidden.d.ts +4 -3
  28. package/dist/register_server_manager_hidden.js +7 -5
  29. package/dist/register_server_manager_hidden.js.map +1 -1
  30. package/dist/register_server_manager_mdns_only.d.ts +5 -3
  31. package/dist/register_server_manager_mdns_only.js +25 -14
  32. package/dist/register_server_manager_mdns_only.js.map +1 -1
  33. package/dist/server_capabilities.js +33 -0
  34. package/dist/server_capabilities.js.map +1 -1
  35. package/dist/server_end_point.js +29 -3
  36. package/dist/server_end_point.js.map +1 -1
  37. package/dist/server_engine.js +20 -3
  38. package/dist/server_engine.js.map +1 -1
  39. package/dist/server_publish_engine.js +95 -98
  40. package/dist/server_publish_engine.js.map +1 -1
  41. package/dist/server_session.js +33 -5
  42. package/dist/server_session.js.map +1 -1
  43. package/dist/server_subscription.js +70 -15
  44. package/dist/server_subscription.js.map +1 -1
  45. package/dist/user_manager.js +1 -0
  46. package/dist/user_manager.js.map +1 -1
  47. package/package.json +49 -47
  48. package/source/i_register_server_manager.ts +66 -5
  49. package/source/index.ts +22 -0
  50. package/source/monitored_item.ts +28 -19
  51. package/source/opcua_server.ts +33 -23
  52. package/source/register_server_manager.ts +294 -354
  53. package/source/register_server_manager_hidden.ts +6 -5
  54. package/source/register_server_manager_mdns_only.ts +25 -14
@@ -2,16 +2,77 @@
2
2
  * @module node-opcua-server
3
3
  */
4
4
  import { EventEmitter } from "events";
5
- import { ErrorCallback } from "node-opcua-status-code";
6
5
 
7
- export interface IRegisterServerManager extends EventEmitter {
8
- discoveryServerEndpointUrl: string;
6
+ /**
7
+ * Finite State Machine for RegisterServerManager.
8
+ *
9
+ * This state machine defines the lifecycle of the server's registration with an LDS.
10
+ * It's designed to handle all transitions, including successful operations,
11
+ * failures, and interruptions (e.g., a stop call during a start operation).
12
+ *
13
+ * **States:**
14
+ * - **INACTIVE**: The manager is not running.
15
+ * - **INITIALIZING**: The initial connection phase to retrieve endpoints from the LDS.
16
+ * - **INITIALIZED**: The initial connection was successful, and endpoints were retrieved.
17
+ * - **REGISTERING**: The manager is actively sending a RegisterServer request.
18
+ * - **REGISTERED**: The server has successfully registered.
19
+ * - **WAITING**: The server is registered and waiting for the next renewal period.
20
+ * - **UNREGISTERING**: The manager is sending an unregister request.
21
+ * - **UNREGISTERED**: The server has been successfully unregistered.
22
+ *
23
+ * **Transitions:**
24
+ * - `INACTIVE` -> `INITIALIZING`: Triggered by `start()`.
25
+ * - `INITIALIZING` -> `INITIALIZED`: On successful initial connection.
26
+ * - `INITIALIZING` -> `INACTIVE`: On connection failure.
27
+ * - `INITIALIZED` -> `REGISTERING`: Immediately after initialization.
28
+ * - `REGISTERING` -> `REGISTERED`: On successful registration.
29
+ * - `REGISTERING` -> `INACTIVE`: On registration failure.
30
+ * - `REGISTERED` -> `WAITING`: Immediately after registration.
31
+ * - `WAITING` -> `REGISTERING`: On renewal timer expiration.
32
+ * - `WAITING` -> `UNREGISTERING`: Triggered by `stop()`.
33
+ * - `UNREGISTERING` -> `UNREGISTERED`: On successful unregistration.
34
+ * - `UNREGISTERING` -> `INACTIVE`: On unregistration failure.
35
+ * - `UNREGISTERED` -> `INACTIVE`: Immediately after unregistration.
36
+ * - Any state can transition to `INACTIVE` on a fatal interruption.
37
+ *
38
+ */
39
+ export enum RegisterServerManagerStatus {
40
+ INACTIVE = 1,
41
+ INITIALIZING = 2,
42
+ INITIALIZED = 3,
43
+ REGISTERING = 4,
44
+ REGISTERED = 5,
45
+ WAITING = 6,
46
+ UNREGISTERING = 7,
47
+ UNREGISTERED = 8,
48
+ NOT_APPLICABLE = -1,
49
+
50
+ DISPOSING = 9
51
+ }
9
52
 
10
- start(callback: ErrorCallback): void;
11
53
 
12
- stop(callback: ErrorCallback): void;
13
54
 
55
+ export interface IRegisterServerManager extends EventEmitter {
56
+ /** The URL of the discovery server the manager is configured to connect to. */
57
+ discoveryServerEndpointUrl: string;
58
+ /**
59
+ * Initiates the server registration process with the discovery server.
60
+ * This method is idempotent and will throw an error if called when the manager is not in the INACTIVE state.
61
+ */
62
+ start(): Promise<void>;
63
+ /**
64
+ * Gracefully unregisters the server from the discovery server and halts the renewal process.
65
+ * This method can be safely called at any point; it will ensure a clean shutdown.
66
+ */
67
+ stop(): Promise<void>;
68
+ /**
69
+ * Disposes of all resources, rendering the manager unusable.
70
+ */
14
71
  dispose(): void;
72
+ /**
73
+ * Returns the current state of the registration manager.
74
+ */
75
+ getState(): RegisterServerManagerStatus;
15
76
 
16
77
  // tslint:disable:unified-signatures
17
78
  on(eventName: "serverRegistrationPending", eventHandler: () => void): this;
package/source/index.ts CHANGED
@@ -1,3 +1,25 @@
1
+ /*!
2
+ * The MIT License (MIT)
3
+ * Copyright (c) 2022-2025 Sterfive SAS - 833264583 RCS ORLEANS - France (https://www.sterfive.com)
4
+ * Copyright (c) 2014-2022 Etienne Rossignon
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ * this software and associated documentation files (the "Software"), to deal in
8
+ * the Software without restriction, including without limitation the rights to
9
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10
+ * the Software, and to permit persons to whom the Software is furnished to do so,
11
+ * subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ */
1
23
  /**
2
24
  * @module node-opcua-server
3
25
  */
@@ -376,7 +376,7 @@ const badDataUnavailable = new DataValue({ statusCode: StatusCodes.BadDataUnavai
376
376
  *
377
377
  */
378
378
  export class MonitoredItem extends EventEmitter implements MonitoredItemBase {
379
- public get node(): UAVariable | UAObject | UAMethod |null {
379
+ public get node(): UAVariable | UAObject | UAMethod | null {
380
380
  return this._node;
381
381
  }
382
382
 
@@ -393,7 +393,12 @@ export class MonitoredItem extends EventEmitter implements MonitoredItemBase {
393
393
  public monitoredItemId: number;
394
394
  public overflow: boolean;
395
395
  public oldDataValue: DataValue;
396
- public monitoringMode: MonitoringMode;
396
+
397
+
398
+ #monitoringMode: MonitoringMode = MonitoringMode.Invalid;
399
+
400
+ public get monitoringMode() { return this.#monitoringMode; }
401
+
397
402
  public timestampsToReturn: TimestampsToReturn;
398
403
  public itemToMonitor: any;
399
404
  public filter: MonitoringFilter | null;
@@ -437,7 +442,7 @@ export class MonitoredItem extends EventEmitter implements MonitoredItemBase {
437
442
  this.oldDataValue = badDataUnavailable;
438
443
 
439
444
  // user has to call setMonitoringMode
440
- this.monitoringMode = MonitoringMode.Invalid;
445
+ this.#monitoringMode = MonitoringMode.Invalid;
441
446
 
442
447
  this.timestampsToReturn = coerceTimestampsToReturn(options.timestampsToReturn);
443
448
 
@@ -464,26 +469,26 @@ export class MonitoredItem extends EventEmitter implements MonitoredItemBase {
464
469
  (this._node as BaseNode).on("dispose", this._on_node_disposed_listener);
465
470
  }
466
471
 
467
- public setMonitoringMode(monitoringMode: MonitoringMode): void {
468
- assert(monitoringMode !== MonitoringMode.Invalid);
472
+ public setMonitoringMode(monitoringMode: MonitoringMode): StatusCode {
469
473
 
470
474
  if (monitoringMode === this.monitoringMode) {
471
475
  // nothing to do
472
- return;
476
+ return StatusCodes.BadNothingToDo;
477
+ }
478
+ if (monitoringMode === MonitoringMode.Invalid) {
479
+ return StatusCodes.BadInvalidArgument;
473
480
  }
474
-
475
481
  const old_monitoringMode = this.monitoringMode;
476
482
 
477
- this.monitoringMode = monitoringMode;
478
483
 
479
- if (this.monitoringMode === MonitoringMode.Disabled) {
484
+ if (monitoringMode === MonitoringMode.Disabled) {
485
+ this.#monitoringMode = monitoringMode;
480
486
  this._stop_sampling();
481
-
482
487
  // OPCUA 1.03 part 4 : $5.12.4
483
488
  // setting the mode to DISABLED causes all queued Notifications to be deleted
484
489
  this._empty_queue();
485
- } else {
486
- assert(this.monitoringMode === MonitoringMode.Sampling || this.monitoringMode === MonitoringMode.Reporting);
490
+ } else if (monitoringMode === MonitoringMode.Sampling || monitoringMode === MonitoringMode.Reporting) {
491
+ this.#monitoringMode = monitoringMode;
487
492
 
488
493
  // OPCUA 1.03 part 4 : $5.12.1.3
489
494
  // When a MonitoredItem is enabled (i.e. when the MonitoringMode is changed from DISABLED to
@@ -494,10 +499,14 @@ export class MonitoredItem extends EventEmitter implements MonitoredItemBase {
494
499
  old_monitoringMode === MonitoringMode.Invalid || old_monitoringMode === MonitoringMode.Disabled;
495
500
  const installEventHandler = old_monitoringMode === MonitoringMode.Invalid;
496
501
  this._start_sampling(recordInitialValue);
502
+ } else {
503
+ return StatusCodes.BadInternalError;
497
504
  }
505
+
506
+ return StatusCodes.Good;
498
507
  }
499
508
 
500
- /**
509
+ /*
501
510
  * Terminate the MonitoredItem.
502
511
  * This will stop the internal sampling timer.
503
512
  */
@@ -1132,7 +1141,7 @@ export class MonitoredItem extends EventEmitter implements MonitoredItemBase {
1132
1141
  if (this.node.nodeClass == NodeClass.Variable) {
1133
1142
  this.node.on("value_changed", this._value_changed_callback);
1134
1143
  this.node.on("semantic_changed", this._semantic_changed_callback);
1135
- }
1144
+ }
1136
1145
  }
1137
1146
 
1138
1147
  // initiate first read
@@ -1292,11 +1301,11 @@ export class MonitoredItem extends EventEmitter implements MonitoredItemBase {
1292
1301
  ) {
1293
1302
  throw new Error(
1294
1303
  "dataValue.value.value cannot be the same object twice! " +
1295
- this.node!.browseName.toString() +
1296
- " " +
1297
- dataValue.toString() +
1298
- " " +
1299
- chalk.cyan(this.oldDataValue.toString())
1304
+ this.node!.browseName.toString() +
1305
+ " " +
1306
+ dataValue.toString() +
1307
+ " " +
1308
+ chalk.cyan(this.oldDataValue.toString())
1300
1309
  );
1301
1310
  }
1302
1311
 
@@ -1315,7 +1315,9 @@ export class OPCUAServer extends OPCUABaseServer {
1315
1315
  } else {
1316
1316
  // we start the registration process asynchronously
1317
1317
  // as we want to make server immediately available
1318
- this.registerServerManager!.start(() => {
1318
+ this.registerServerManager!.start().then(() => {
1319
+ /* empty */
1320
+ }).catch((err) => {
1319
1321
  /* empty */
1320
1322
  });
1321
1323
 
@@ -1379,20 +1381,28 @@ export class OPCUAServer extends OPCUABaseServer {
1379
1381
  this.engine.setShutdownTime(shutdownTime);
1380
1382
 
1381
1383
  debugLog("OPCUAServer is now un-registering itself from the discovery server " + this.buildInfo);
1382
- this.registerServerManager!.stop((err?: Error | null) => {
1383
- debugLog("OPCUAServer unregistered from discovery server", err);
1384
- setTimeout(async () => {
1385
- await this.engine.shutdown();
1384
+ this.registerServerManager!.stop()
1385
+ .then(() => {
1386
+ debugLog("OPCUAServer unregistered from discovery server successfully");
1386
1387
 
1387
- debugLog("OPCUAServer#shutdown: started");
1388
- OPCUABaseServer.prototype.shutdown.call(this, (err1?: Error) => {
1389
- debugLog("OPCUAServer#shutdown: completed");
1388
+ })
1389
+ .catch((err) => {
1390
+ debugLog("OPCUAServer unregistered from discovery server with err: ", err.message);
1391
+ }).finally(() => {
1390
1392
 
1391
- this.dispose();
1392
- callback(err1);
1393
- });
1394
- }, timeout);
1395
- });
1393
+ setTimeout(async () => {
1394
+ await this.engine.shutdown();
1395
+
1396
+ debugLog("OPCUAServer#shutdown: started");
1397
+ OPCUABaseServer.prototype.shutdown.call(this, (err1?: Error) => {
1398
+ debugLog("OPCUAServer#shutdown: completed");
1399
+
1400
+ this.dispose();
1401
+ callback(err1);
1402
+ });
1403
+ }, timeout);
1404
+
1405
+ });
1396
1406
  }
1397
1407
 
1398
1408
  public dispose(): void {
@@ -3323,8 +3333,8 @@ export class OPCUAServer extends OPCUABaseServer {
3323
3333
  if (!monitoredItem) {
3324
3334
  return StatusCodes.BadMonitoredItemIdInvalid;
3325
3335
  }
3326
- monitoredItem.setMonitoringMode(monitoringMode);
3327
- return StatusCodes.Good;
3336
+ const statusCode = monitoredItem.setMonitoringMode(monitoringMode);
3337
+ return statusCode;
3328
3338
  });
3329
3339
 
3330
3340
  const response = new SetMonitoringModeResponse({
@@ -3621,11 +3631,11 @@ export class OPCUAServer extends OPCUABaseServer {
3621
3631
 
3622
3632
  const userIdentityTokenPasswordRemoved = (userIdentityToken?: UserIdentityToken): UserIdentityToken => {
3623
3633
  if (!userIdentityToken) return new AnonymousIdentityToken();
3624
- const a: UserIdentityToken = userIdentityToken.clone();
3634
+ const a: UserIdentityToken = userIdentityToken.clone();
3625
3635
  // For Username/Password tokens the password shall not be included.
3626
3636
  if (a instanceof UserNameIdentityToken) {
3627
3637
  // remove password
3628
- a.password = Buffer.from("*************","ascii");
3638
+ a.password = Buffer.from("*************", "ascii");
3629
3639
  }
3630
3640
  // if (a instanceof X509IdentityToken) {
3631
3641
  // a.certificateData = Buffer.alloc(0);
@@ -3745,7 +3755,7 @@ export interface RaiseEventAuditActivateSessionEventData extends RaiseEventAudit
3745
3755
  }
3746
3756
 
3747
3757
  // tslint:disable:no-empty-interface
3748
- export interface RaiseEventTransitionEventData extends RaiseEventData {}
3758
+ export interface RaiseEventTransitionEventData extends RaiseEventData { }
3749
3759
 
3750
3760
  export interface RaiseEventAuditUrlMismatchEventTypeData extends RaiseEventData {
3751
3761
  endpointUrl: PseudoVariantString;
@@ -3775,7 +3785,7 @@ export interface RaiseAuditCertificateDataMismatchEventData extends RaiseAuditCe
3775
3785
  */
3776
3786
  invalidUri: PseudoVariantString;
3777
3787
  }
3778
- export interface RaiseAuditCertificateUntrustedEventData extends RaiseAuditCertificateEventData {}
3788
+ export interface RaiseAuditCertificateUntrustedEventData extends RaiseAuditCertificateEventData { }
3779
3789
  /**
3780
3790
  * This EventType inherits all Properties of the AuditCertificateEventType.
3781
3791
  *
@@ -3787,7 +3797,7 @@ export interface RaiseAuditCertificateUntrustedEventData extends RaiseAuditCerti
3787
3797
  * There are no additional Properties defined for this EventType.
3788
3798
  *
3789
3799
  */
3790
- export interface RaiseAuditCertificateExpiredEventData extends RaiseAuditCertificateEventData {}
3800
+ export interface RaiseAuditCertificateExpiredEventData extends RaiseAuditCertificateEventData { }
3791
3801
  /**
3792
3802
  * This EventType inherits all Properties of the AuditCertificateEventType.
3793
3803
  *
@@ -3797,7 +3807,7 @@ export interface RaiseAuditCertificateExpiredEventData extends RaiseAuditCertifi
3797
3807
  *
3798
3808
  * There are no additional Properties defined for this EventType.
3799
3809
  */
3800
- export interface RaiseAuditCertificateInvalidEventData extends RaiseAuditCertificateEventData {}
3810
+ export interface RaiseAuditCertificateInvalidEventData extends RaiseAuditCertificateEventData { }
3801
3811
  /**
3802
3812
  * This EventType inherits all Properties of the AuditCertificateEventType.
3803
3813
  *
@@ -3807,7 +3817,7 @@ export interface RaiseAuditCertificateInvalidEventData extends RaiseAuditCertifi
3807
3817
  * If a trust chain is involved then the certificate that failed in the trust chain should be described.
3808
3818
  * There are no additional Properties defined for this EventType.
3809
3819
  */
3810
- export interface RaiseAuditCertificateUntrustedEventData extends RaiseAuditCertificateEventData {}
3820
+ export interface RaiseAuditCertificateUntrustedEventData extends RaiseAuditCertificateEventData { }
3811
3821
  /**
3812
3822
  * This EventType inherits all Properties of the AuditCertificateEventType.
3813
3823
  *
@@ -3830,7 +3840,7 @@ export interface RaiseAuditCertificateRevokedEventData extends RaiseAuditCertifi
3830
3840
  *
3831
3841
  * There are no additional Properties defined for this EventType
3832
3842
  */
3833
- export interface RaiseAuditCertificateMismatchEventData extends RaiseAuditCertificateEventData {}
3843
+ export interface RaiseAuditCertificateMismatchEventData extends RaiseAuditCertificateEventData { }
3834
3844
  export interface OPCUAServer {
3835
3845
  /**
3836
3846
  * @internal