node-opcua-client 2.115.0 → 2.117.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.
@@ -14,8 +14,9 @@ import { BrowsePathResult, makeBrowsePath } from "node-opcua-service-translate-b
14
14
  import { StatusCode, StatusCodes } from "node-opcua-status-code";
15
15
  import { DataType, Variant } from "node-opcua-variant";
16
16
  import { Callback, ErrorCallback } from "node-opcua-status-code";
17
+ import { ResponseCallback } from "node-opcua-pseudo-session";
17
18
 
18
- import { CallMethodRequestLike, ResponseCallback } from "../client_session";
19
+ import { CallMethodRequestLike } from "../client_session";
19
20
  import { ClientSubscription } from "../client_subscription";
20
21
  import { ClientSessionImpl } from "../private/client_session_impl";
21
22
  import { ClientSubscriptionImpl } from "../private/client_subscription_impl";
@@ -13,8 +13,8 @@ import { FindServersOnNetworkRequestOptions, FindServersRequestOptions, ServerOn
13
13
  import { ApplicationDescription, EndpointDescription } from "node-opcua-service-endpoints";
14
14
  import { ChannelSecurityToken, MessageSecurityMode } from "node-opcua-service-secure-channel";
15
15
  import { ErrorCallback } from "node-opcua-status-code";
16
+ import { ResponseCallback } from "node-opcua-pseudo-session";
16
17
 
17
- import { ResponseCallback } from "./client_session";
18
18
  import { Request, Response } from "./common";
19
19
 
20
20
  export type FindServersRequestLike = FindServersRequestOptions;
@@ -10,7 +10,16 @@ import { Certificate, Nonce } from "node-opcua-crypto";
10
10
  import { LocalizedTextLike } from "node-opcua-data-model";
11
11
  import { DataValue, TimestampsToReturn } from "node-opcua-data-value";
12
12
  import { NodeId, NodeIdLike } from "node-opcua-nodeid";
13
- import { IBasicSession } from "node-opcua-pseudo-session";
13
+ import {
14
+ IBasicSession,
15
+ IBasicSessionBrowse,
16
+ IBasicSessionBrowseNext,
17
+ IBasicSessionCall,
18
+ IBasicSessionRead,
19
+ IBasicSessionTranslateBrowsePath,
20
+ IBasicSessionWrite,
21
+ ResponseCallback
22
+ } from "node-opcua-pseudo-session";
14
23
  import { ErrorCallback } from "node-opcua-status-code";
15
24
  import { BrowseDescriptionOptions, BrowseResult } from "node-opcua-service-browse";
16
25
  import { CallMethodRequest, CallMethodRequestOptions, CallMethodResult } from "node-opcua-service-call";
@@ -75,14 +84,6 @@ export { ArgumentDefinition, CallMethodRequestLike, MethodId } from "node-opcua-
75
84
 
76
85
  import { ClientSubscription } from "./client_subscription";
77
86
 
78
- export type ResponseCallback<T> = (err: Error | null, response?: T) => void;
79
-
80
- export interface NodeAttributes {
81
- nodeId: NodeId;
82
- statusCode: StatusCode;
83
-
84
- [key: string]: Variant | NodeId | StatusCode;
85
- }
86
87
 
87
88
  export interface MonitoredItemData {
88
89
  clientHandles: Uint32Array;
@@ -98,7 +99,6 @@ export interface CreateSubscriptionOptions {
98
99
  priority?: UInt8;
99
100
  }
100
101
 
101
- export type BrowseDescriptionLike = string | BrowseDescriptionOptions;
102
102
  export type DeleteMonitoredItemsRequestLike = DeleteMonitoredItemsRequestOptions;
103
103
  export type CreateSubscriptionRequestLike = CreateSubscriptionRequestOptions;
104
104
  export type DeleteSubscriptionsRequestLike = DeleteSubscriptionsRequestOptions;
@@ -167,7 +167,7 @@ export interface ClientSession extends EventEmitter {
167
167
  }
168
168
 
169
169
  // browse services
170
- export interface ClientSessionBrowseService {
170
+ export interface ClientSessionBrowseService extends IBasicSessionBrowse, IBasicSessionBrowseNext {
171
171
  /**
172
172
  * the maximum number of reference that the server should return per browseResult
173
173
  * Continuous points will be return by server to allow retrieving remaining references
@@ -175,32 +175,10 @@ export interface ClientSessionBrowseService {
175
175
  */
176
176
  requestedMaxReferencesPerNode: number;
177
177
 
178
- browse(nodeToBrowse: BrowseDescriptionLike, callback: ResponseCallback<BrowseResult>): void;
179
-
180
- browse(nodesToBrowse: BrowseDescriptionLike[], callback: ResponseCallback<BrowseResult[]>): void;
181
-
182
- browse(nodeToBrowse: BrowseDescriptionLike): Promise<BrowseResult>;
183
-
184
- browse(nodesToBrowse: BrowseDescriptionLike[]): Promise<BrowseResult[]>;
185
-
186
- browseNext(continuationPoint: Buffer, releaseContinuationPoints: boolean, callback: ResponseCallback<BrowseResult>): void;
187
-
188
- browseNext(continuationPoints: Buffer[], releaseContinuationPoints: boolean, callback: ResponseCallback<BrowseResult[]>): void;
189
-
190
- browseNext(continuationPoint: Buffer, releaseContinuationPoints: boolean): Promise<BrowseResult>;
191
-
192
- browseNext(continuationPoints: Buffer[], releaseContinuationPoints: boolean): Promise<BrowseResult[]>;
193
- }
178
+ }
194
179
 
195
180
  // translate browsePathTo NodeId services
196
- export interface ClientSessionTranslateBrowsePathService {
197
- translateBrowsePath(browsesPath: BrowsePath[], callback: ResponseCallback<BrowsePathResult[]>): void;
198
-
199
- translateBrowsePath(browsePath: BrowsePath, callback: ResponseCallback<BrowsePathResult>): void;
200
-
201
- translateBrowsePath(browsePath: BrowsePath): Promise<BrowsePathResult>;
202
-
203
- translateBrowsePath(browsePaths: BrowsePath[]): Promise<BrowsePathResult[]>;
181
+ export interface ClientSessionTranslateBrowsePathService extends IBasicSessionTranslateBrowsePath {
204
182
  }
205
183
 
206
184
  // query services
@@ -211,7 +189,7 @@ export interface ClientSessionQueryService {
211
189
  }
212
190
 
213
191
  // call services
214
- export interface ClientSessionCallService {
192
+ export interface ClientSessionCallService extends IBasicSessionCall {
215
193
  /**
216
194
  *
217
195
  * @method call
@@ -269,13 +247,6 @@ export interface ClientSessionCallService {
269
247
  * ```
270
248
  */
271
249
 
272
- call(methodToCall: CallMethodRequestLike, callback: (err: Error | null, result?: CallMethodResult) => void): void;
273
-
274
- call(methodsToCall: CallMethodRequestLike[], callback: (err: Error | null, results?: CallMethodResult[]) => void): void;
275
-
276
- call(methodToCall: CallMethodRequestLike): Promise<CallMethodResult>;
277
-
278
- call(methodsToCall: CallMethodRequestLike[]): Promise<CallMethodResult[]>;
279
250
 
280
251
  getArgumentDefinition(methodId: MethodId): Promise<ArgumentDefinition>;
281
252
 
@@ -294,19 +265,8 @@ export interface ClientSessionRegisterService {
294
265
  }
295
266
 
296
267
  // read services
297
- export interface ClientSessionReadService {
298
- read(nodeToRead: ReadValueIdOptions, maxAge: number, callback: ResponseCallback<DataValue>): void;
299
-
300
- read(nodesToRead: ReadValueIdOptions[], maxAge: number, callback: ResponseCallback<DataValue[]>): void;
301
-
302
- read(nodeToRead: ReadValueIdOptions, callback: ResponseCallback<DataValue>): void;
303
-
304
- read(nodesToRead: ReadValueIdOptions[], callback: ResponseCallback<DataValue[]>): void;
305
-
306
- read(nodeToRead: ReadValueIdOptions, maxAge?: number): Promise<DataValue>;
307
-
308
- read(nodesToRead: ReadValueIdOptions[], maxAge?: number): Promise<DataValue[]>;
309
-
268
+ export interface ClientSessionReadService extends IBasicSessionRead {
269
+
310
270
  /**
311
271
  * @deprecated
312
272
  */
@@ -326,14 +286,8 @@ export interface ClientSessionReadService {
326
286
  }
327
287
 
328
288
  // write services
329
- export interface ClientSessionWriteService {
330
- write(nodeToWrite: WriteValueOptions, callback: ResponseCallback<StatusCode>): void;
331
-
332
- write(nodesToWrite: WriteValueOptions[], callback: ResponseCallback<StatusCode[]>): void;
333
-
334
- write(nodesToWrite: WriteValueOptions[]): Promise<StatusCode[]>;
289
+ export interface ClientSessionWriteService extends IBasicSessionWrite {
335
290
 
336
- write(nodeToWrite: WriteValueOptions): Promise<StatusCode>;
337
291
 
338
292
  /**
339
293
  * @deprecated
@@ -2,16 +2,13 @@
2
2
  * @module node-opcua-client
3
3
  */
4
4
 
5
- import { assert } from "node-opcua-assert";
6
5
  import { AttributeIds } from "node-opcua-data-model";
7
6
  import { DataValue } from "node-opcua-data-value";
8
7
  import { NodeIdLike, resolveNodeId } from "node-opcua-nodeid";
9
8
  import { ReadValueIdOptions } from "node-opcua-service-read";
10
9
  import { BrowsePath, BrowsePathResult } from "node-opcua-service-translate-browse-path";
11
- import { StatusCodes } from "node-opcua-status-code";
12
10
  import { Variant } from "node-opcua-variant";
13
- import { ClientSession, ResponseCallback } from "./client_session";
14
- import { ClientSessionImpl } from "./private/client_session_impl";
11
+ import { IBasicSessionAsync } from "node-opcua-pseudo-session";
15
12
 
16
13
  const hasPropertyRefId = resolveNodeId("HasProperty");
17
14
 
@@ -47,16 +44,7 @@ interface AnalogDataItemSnapshot {
47
44
  * @param nodeId
48
45
  * @param callback
49
46
  */
50
- export function readUAAnalogItem(session: ClientSession, nodeId: NodeIdLike): Promise<AnalogDataItemSnapshot>;
51
- export function readUAAnalogItem(
52
- session: ClientSession,
53
- nodeId: NodeIdLike,
54
- callback: ResponseCallback<AnalogDataItemSnapshot>
55
- ): void;
56
- export function readUAAnalogItem(session: ClientSession, nodeId: NodeIdLike, ...args: [any?, ...any[]]): any {
57
- const callback = args[0] as ResponseCallback<AnalogDataItemSnapshot>;
58
- assert(typeof callback === "function");
59
-
47
+ export async function readUAAnalogItem(session: IBasicSessionAsync, nodeId: NodeIdLike): Promise<AnalogDataItemSnapshot> {
60
48
  const browsePath = [
61
49
  browsePathPropertyRequest(nodeId, "EngineeringUnits"),
62
50
  browsePathPropertyRequest(nodeId, "EURange"),
@@ -73,51 +61,35 @@ export function readUAAnalogItem(session: ClientSession, nodeId: NodeIdLike, ...
73
61
  valuePrecision: null
74
62
  };
75
63
 
76
- session.translateBrowsePath(browsePath, (err: Error | null, browsePathResults?: BrowsePathResult[]) => {
77
- if (err) {
78
- return callback(err);
79
- }
80
- browsePathResults = browsePathResults || [];
64
+ const browsePathResults = await session.translateBrowsePath(browsePath);
81
65
 
82
- const actions: any[] = [];
83
- const nodesToRead: ReadValueIdOptions[] = [];
66
+ const actions: ( (readResult: DataValue) =>void)[] = [];
67
+ const nodesToRead: ReadValueIdOptions[] = [];
84
68
 
85
- function processProperty(browsePathResult: BrowsePathResult, propertyName: string) {
86
- if (browsePathResult.statusCode.isGood()) {
87
- browsePathResult.targets = browsePathResult.targets || [];
88
- nodesToRead.push({
89
- attributeId: AttributeIds.Value,
90
- nodeId: browsePathResult.targets[0].targetId
91
- });
92
- actions.push((readResult: DataValue) => ((analogItemData as any)[propertyName] = readResult.value.value));
93
- }
69
+ function processProperty(browsePathResult: BrowsePathResult, propertyName: string) {
70
+ if (browsePathResult.statusCode.isGood()) {
71
+ browsePathResult.targets = browsePathResult.targets || [];
72
+ nodesToRead.push({
73
+ attributeId: AttributeIds.Value,
74
+ nodeId: browsePathResult.targets[0].targetId
75
+ });
76
+ actions.push(
77
+ (readResult: DataValue) =>
78
+ ((analogItemData as unknown as Record<string, unknown>)[propertyName] = readResult.value.value)
79
+ );
94
80
  }
81
+ }
95
82
 
96
- processProperty(browsePathResults[0], "engineeringUnits");
97
- processProperty(browsePathResults[1], "engineeringUnitsRange");
98
- processProperty(browsePathResults[2], "instrumentRange");
99
- processProperty(browsePathResults[3], "valuePrecision");
100
- processProperty(browsePathResults[4], "definition");
83
+ processProperty(browsePathResults[0], "engineeringUnits");
84
+ processProperty(browsePathResults[1], "engineeringUnitsRange");
85
+ processProperty(browsePathResults[2], "instrumentRange");
86
+ processProperty(browsePathResults[3], "valuePrecision");
87
+ processProperty(browsePathResults[4], "definition");
101
88
 
102
- session.read(nodesToRead, (err1: Error | null, dataValues?: DataValue[]) => {
103
- if (err1) {
104
- return callback(err1);
105
- }
106
- /* istanbul ignore next */
107
- if (!dataValues) {
108
- return callback(new Error("Internal Error"));
109
- }
110
-
111
- dataValues.forEach((result: DataValue, index: number) => {
112
- actions[index].call(null, result);
113
- });
89
+ const dataValues = await session.read(nodesToRead);
114
90
 
115
- callback(err1, analogItemData);
116
- });
91
+ dataValues.forEach((result: DataValue, index: number) => {
92
+ actions[index].call(null, result);
117
93
  });
94
+ return analogItemData;
118
95
  }
119
- // tslint:disable:no-var-requires
120
- // tslint:disable:max-line-length
121
- const thenify = require("thenify");
122
- const opts = { multiArgs: false };
123
- (module as any).exports.readUAAnalogItem = thenify.withCallback((module as any).exports.readUAAnalogItem, opts);
package/source/index.ts CHANGED
@@ -72,5 +72,5 @@ export * from "node-opcua-service-subscription";
72
72
  export * from "node-opcua-service-translate-browse-path";
73
73
  export * from "node-opcua-service-write";
74
74
  export * from "node-opcua-service-filter";
75
- export { IBasicSession, browseAll, readNamespaceArray } from "node-opcua-pseudo-session";
75
+ export * from "node-opcua-pseudo-session";
76
76
  export * from "node-opcua-client-dynamic-extension-object";
@@ -2,16 +2,12 @@
2
2
  * @module node-opcua-client
3
3
  */
4
4
 
5
- import { ByteString } from "node-opcua-basic-types";
6
- import { Certificate, PrivateKeyPEM } from "node-opcua-crypto";
7
- import { ConnectionStrategyOptions, Message, SecurityPolicy } from "node-opcua-secure-channel";
8
- import { ApplicationDescription, EndpointDescription, UserTokenType } from "node-opcua-service-endpoints";
9
- import { MessageSecurityMode } from "node-opcua-service-secure-channel";
10
- import { X509IdentityTokenOptions } from "node-opcua-types";
5
+ import { ApplicationDescription, EndpointDescription } from "node-opcua-service-endpoints";
11
6
  import { CallbackT, ErrorCallback, StatusCode } from "node-opcua-status-code";
7
+ import { ResponseCallback } from "node-opcua-pseudo-session";
12
8
  import { FindServersRequestLike, GetEndpointsOptions, OPCUAClientBase, OPCUAClientBaseOptions } from "./client_base";
13
9
 
14
- import { ClientSession, ResponseCallback } from "./client_session";
10
+ import { ClientSession } from "./client_session";
15
11
  import { ClientSubscription, ClientSubscriptionOptions } from "./client_subscription";
16
12
  import { OPCUAClientImpl } from "./private/opcua_client_impl";
17
13
  import { UserIdentityInfo } from "./user_identity_info";
@@ -15,7 +15,7 @@ import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "n
15
15
 
16
16
  import { makeApplicationUrn } from "node-opcua-common";
17
17
  import { getHostname } from "node-opcua-hostname";
18
- import { IBasicTransportSettings } from "node-opcua-pseudo-session";
18
+ import { IBasicTransportSettings, ResponseCallback } from "node-opcua-pseudo-session";
19
19
  import {
20
20
  ClientSecureChannelLayer,
21
21
  coerceConnectionStrategy,
@@ -48,7 +48,6 @@ import { matchUri } from "node-opcua-utils";
48
48
  import { getDefaultCertificateManager, makeSubject, OPCUACertificateManager } from "node-opcua-certificate-manager";
49
49
  import { VerificationStatus } from "node-opcua-pki";
50
50
  import { CloseSessionRequest, CloseSessionResponse } from "node-opcua-service-session";
51
- import { ResponseCallback } from "../client_session";
52
51
  import { Request, Response } from "../common";
53
52
 
54
53
  import {
@@ -21,7 +21,16 @@ import { DataValue } from "node-opcua-data-value";
21
21
  import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
22
22
  import { ExtensionObject } from "node-opcua-extension-object";
23
23
  import { coerceNodeId, NodeId, NodeIdLike, resolveNodeId } from "node-opcua-nodeid";
24
- import { getBuiltInDataType, getArgumentDefinitionHelper, IBasicSession, IBasicTransportSettings } from "node-opcua-pseudo-session";
24
+ import {
25
+ getBuiltInDataType,
26
+ getArgumentDefinitionHelper,
27
+ IBasicSession,
28
+ IBasicTransportSettings,
29
+ readAllAttributes,
30
+ NodeAttributes,
31
+ ResponseCallback,
32
+ BrowseDescriptionLike
33
+ } from "node-opcua-pseudo-session";
25
34
  import { AnyConstructorFunc } from "node-opcua-schemas";
26
35
  import { ClientSecureChannelLayer, requestHandleNotSetValue, SignatureData } from "node-opcua-secure-channel";
27
36
  import { BrowseDescription, BrowseRequest, BrowseResponse, BrowseResult } from "node-opcua-service-browse";
@@ -98,7 +107,6 @@ import { DataType, Variant, VariantLike } from "node-opcua-variant";
98
107
 
99
108
  import {
100
109
  ArgumentDefinition,
101
- BrowseDescriptionLike,
102
110
  CallMethodRequestLike,
103
111
  ClientSession,
104
112
  CreateMonitoredItemsRequestLike,
@@ -109,7 +117,6 @@ import {
109
117
  ModifyMonitoredItemsRequestLike,
110
118
  ModifySubscriptionRequestLike,
111
119
  MonitoredItemData,
112
- NodeAttributes,
113
120
  QueryFirstRequestLike,
114
121
  SetMonitoringModeRequestLike,
115
122
  SubscriptionId,
@@ -127,8 +134,6 @@ import { ClientSidePublishEngine } from "./client_publish_engine";
127
134
  import { ClientSubscriptionImpl } from "./client_subscription_impl";
128
135
  import { IClientBase } from "./i_private_client";
129
136
 
130
- export type ResponseCallback<T> = (err: Error | null, response?: T) => void;
131
-
132
137
  const helpAPIChange = process.env.DEBUG && process.env.DEBUG.match(/API/);
133
138
  const debugLog = make_debugLog(__filename);
134
139
  const doDebug = checkDebugFlag(__filename);
@@ -168,55 +173,6 @@ function coerceReadValueId(node: any): ReadValueId {
168
173
  }
169
174
  }
170
175
 
171
- const keys = Object.keys(AttributeIds).filter((k: any) => (AttributeIds as any)[k] !== AttributeIds.INVALID);
172
-
173
- const attributeNames: string[] = ((): string[] => {
174
- const r: string[] = [];
175
- for (let i = 1; i <= 22; i++) {
176
- r.push(attributeNameById[i].toString());
177
- }
178
- return r;
179
- })();
180
-
181
- function composeResult(nodes: any[], nodesToRead: ReadValueIdOptions[], dataValues: DataValue[]): NodeAttributes[] {
182
- assert(nodesToRead.length === dataValues.length);
183
- let c = 0;
184
- const results = [];
185
- let dataValue;
186
- let k;
187
- let nodeToRead;
188
-
189
- for (const node of nodes) {
190
- const data: NodeAttributes = {
191
- nodeId: resolveNodeId(node),
192
- statusCode: StatusCodes.BadNodeIdUnknown
193
- };
194
-
195
- let addedProperty = 0;
196
-
197
- for (const key of attributeNames) {
198
- dataValue = dataValues[c];
199
- nodeToRead = nodesToRead[c];
200
- c++;
201
- if (dataValue.statusCode.equals(StatusCodes.Good)) {
202
- k = lowerFirstLetter(key);
203
- data[k] = dataValue.value ? dataValue.value.value : null;
204
- addedProperty += 1;
205
- }
206
- }
207
-
208
- /* istanbul ignore if */
209
- if (addedProperty > 0) {
210
- data.statusCode = StatusCodes.Good;
211
- } else {
212
- data.statusCode = StatusCodes.BadNodeIdUnknown;
213
- }
214
- results.push(data);
215
- }
216
-
217
- return results;
218
- }
219
-
220
176
  const emptyUint32Array = new Uint32Array(0);
221
177
 
222
178
  type EmptyCallback = (err?: Error) => void;
@@ -1113,48 +1069,11 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1113
1069
  public readAllAttributes(nodes: NodeIdLike[], callback: (err: Error | null, data?: NodeAttributes[]) => void): void;
1114
1070
 
1115
1071
  public readAllAttributes(...args: any[]): void {
1116
- const arg0 = args[0];
1117
- const callback = args[1];
1118
- assert(typeof callback === "function");
1119
-
1120
- const isArray = Array.isArray(arg0);
1121
-
1122
- const nodes = isArray ? arg0 : [arg0];
1123
-
1124
- const nodesToRead: ReadValueIdOptions[] = [];
1125
-
1126
- for (const node of nodes) {
1127
- const nodeId = resolveNodeId(node);
1128
-
1129
- /* istanbul ignore next */
1130
- if (!nodeId) {
1131
- throw new Error("cannot coerce " + node + " to a valid NodeId");
1132
- }
1133
-
1134
- for (let attributeId = 1; attributeId <= 22; attributeId++) {
1135
- nodesToRead.push({
1136
- attributeId,
1137
- dataEncoding: undefined,
1138
- indexRange: undefined,
1139
- nodeId
1140
- });
1141
- }
1142
- }
1143
-
1144
- this.read(nodesToRead, (err: Error | null, dataValues?: DataValue[]) => {
1145
- /* istanbul ignore next */
1146
- if (err) {
1147
- return callback(err);
1148
- }
1149
-
1150
- /* istanbul ignore next */
1151
- if (!dataValues) {
1152
- return callback(new Error("Internal Error"));
1153
- }
1154
-
1155
- const results = composeResult(nodes, nodesToRead, dataValues);
1156
- callback(err, isArray ? results : results[0]);
1157
- });
1072
+ const nodes = args[0] as NodeIdLike[];
1073
+ const callback = args[1] as (err: Error | null, data?: NodeAttributes[]) => void;
1074
+ readAllAttributes(this, nodes)
1075
+ .then((data: any) => callback(null, data))
1076
+ .catch((err: Error) => callback(err));
1158
1077
  }
1159
1078
 
1160
1079
  /**
@@ -1797,7 +1716,6 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1797
1716
  public hasBeenClosed(): boolean {
1798
1717
  return isNullOrUndefined(this._client) || this._closed || this._closeEventHasBeenEmitted;
1799
1718
  }
1800
-
1801
1719
 
1802
1720
  public async call(methodToCall: CallMethodRequestLike): Promise<CallMethodResult>;
1803
1721
  public async call(methodToCall: CallMethodRequestLike[]): Promise<CallMethodResult[]>;
@@ -2085,7 +2003,9 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
2085
2003
  public getBuiltInDataType(...args: any[]): any {
2086
2004
  const nodeId = args[0];
2087
2005
  const callback = args[1];
2088
- return getBuiltInDataType(this, nodeId, callback);
2006
+ return getBuiltInDataType(this, nodeId)
2007
+ .then((dataType: DataType) => callback(null, dataType))
2008
+ .catch(callback);
2089
2009
  }
2090
2010
 
2091
2011
  public resumePublishEngine(): void {
@@ -1,8 +1,8 @@
1
1
  import { ClientSecureChannelLayer } from "node-opcua-secure-channel";
2
2
  import { EndpointDescription } from "node-opcua-service-endpoints";
3
- import { IBasicTransportSettings } from "node-opcua-pseudo-session";
3
+ import { IBasicTransportSettings, ResponseCallback } from "node-opcua-pseudo-session";
4
4
 
5
- import { ClientSession, ResponseCallback } from "../client_session";
5
+ import { ClientSession } from "../client_session";
6
6
  import { Request, Response } from "../common";
7
7
  import { UserIdentityInfo } from "../user_identity_info";
8
8
  import { ClientSessionImpl } from "./client_session_impl";
@@ -125,6 +125,8 @@ function _ask_for_subscription_republish(session: ClientSessionImpl, callback: (
125
125
  }
126
126
  doDebug && debugLog(chalk.bgCyan.green.bold("_ask_for_subscription_republish done "), err ? err.message : "OK");
127
127
  if (err) {
128
+ warningLog("republish has failed with error :", err.message);
129
+
128
130
  doDebug && debugLog("_ask_for_subscription_republish has : recreating subscription");
129
131
  return repair_client_session_by_recreating_a_new_session(session._client!, session, callback);
130
132
  }
@@ -190,6 +192,36 @@ function repair_client_session_by_recreating_a_new_session(
190
192
 
191
193
  const listenerCountBefore = session.listenerCount("");
192
194
 
195
+ function recreateSubscription(subscriptionsToRecreate: number[], innerCallback: ErrorCallback) {
196
+ async.forEach(
197
+ subscriptionsToRecreate,
198
+ (subscriptionId: SubscriptionId, next: ErrorCallback) => {
199
+ if (!session.getPublishEngine().hasSubscription(subscriptionId)) {
200
+ doDebug && debugLog(chalk.red(" => CANNOT RECREATE SUBSCRIPTION "), subscriptionId);
201
+ return next();
202
+ }
203
+ const subscription = session.getPublishEngine().getSubscription(subscriptionId);
204
+ assert(subscription.constructor.name === "ClientSubscriptionImpl");
205
+ doDebug && debugLog(chalk.red(" => RECREATING SUBSCRIPTION "), subscriptionId);
206
+ assert(subscription.session === newSession, "must have the session");
207
+
208
+ (subscription as ClientSubscriptionImpl).recreateSubscriptionAndMonitoredItem((err1?: Error) => {
209
+ if (err1) {
210
+ doDebug && debugLog("_recreateSubscription failed !" + err1.message);
211
+ }
212
+
213
+ doDebug &&
214
+ debugLog(chalk.cyan(" => RECREATING SUBSCRIPTION AND MONITORED ITEM DONE "), subscriptionId);
215
+
216
+ next();
217
+ });
218
+ },
219
+ (err1?: Error | null) => {
220
+ innerCallback(err1!);
221
+ }
222
+ );
223
+ }
224
+
193
225
  async.series(
194
226
  [
195
227
  function suspend_old_session_publish_engine(innerCallback: ErrorCallback) {
@@ -278,28 +310,24 @@ function repair_client_session_by_recreating_a_new_session(
278
310
  newSession.transferSubscriptions(
279
311
  subscriptionsToTransfer,
280
312
  (err: Error | null, transferSubscriptionsResponse?: TransferSubscriptionsResponse) => {
281
- if (err) {
282
- warningLog(chalk.bgCyan("Warning TransferSubscription has failed " + err.message));
313
+ if (err || !transferSubscriptionsResponse) {
314
+ warningLog(chalk.bgCyan("Warning TransferSubscription has failed " + err?.message));
283
315
  warningLog(chalk.bgCyan("May be the server is not supporting this feature"));
284
316
  // when transfer subscription has failed, we have no other choice but
285
317
  // recreate the subscriptions on the server side
286
- return innerCallback();
287
- }
288
-
289
- // istanbul ignore next
290
- if (!transferSubscriptionsResponse) {
291
- return innerCallback(new Error("Internal Error"));
318
+ const subscriptionsToRecreate = [...(subscriptionsToTransfer.subscriptionIds || [])];
319
+ warningLog(chalk.bgCyan("We need to recreate entirely the subscription"));
320
+ recreateSubscription(subscriptionsToRecreate, innerCallback);
321
+ return;
292
322
  }
293
323
 
294
324
  const results = transferSubscriptionsResponse.results || [];
295
-
296
325
  // istanbul ignore next
297
326
  if (doDebug) {
298
- doDebug &&
299
- debugLog(
300
- chalk.cyan(" => transfer subscriptions done"),
301
- results.map((x: any) => x.statusCode.toString()).join(" ")
302
- );
327
+ debugLog(
328
+ chalk.cyan(" => transfer subscriptions done"),
329
+ results.map((x: any) => x.statusCode.toString()).join(" ")
330
+ );
303
331
  }
304
332
 
305
333
  const subscriptionsToRecreate = [];
@@ -333,36 +361,7 @@ function repair_client_session_by_recreating_a_new_session(
333
361
  }
334
362
  doDebug && debugLog(" new session subscriptionCount = ", newSession.getPublishEngine().subscriptionCount);
335
363
 
336
- async.forEach(
337
- subscriptionsToRecreate,
338
- (subscriptionId: SubscriptionId, next: ErrorCallback) => {
339
- if (!session.getPublishEngine().hasSubscription(subscriptionId)) {
340
- doDebug && debugLog(chalk.red(" => CANNOT RECREATE SUBSCRIPTION "), subscriptionId);
341
- return next();
342
- }
343
- const subscription = session.getPublishEngine().getSubscription(subscriptionId);
344
- assert(subscription.constructor.name === "ClientSubscriptionImpl");
345
- doDebug && debugLog(chalk.red(" => RECREATING SUBSCRIPTION "), subscriptionId);
346
- assert(subscription.session === newSession, "must have the session");
347
-
348
- (subscription as ClientSubscriptionImpl).recreateSubscriptionAndMonitoredItem((err1?: Error) => {
349
- if (err1) {
350
- doDebug && debugLog("_recreateSubscription failed !" + err1.message);
351
- }
352
-
353
- doDebug &&
354
- debugLog(
355
- chalk.cyan(" => RECREATING SUBSCRIPTION AND MONITORED ITEM DONE "),
356
- subscriptionId
357
- );
358
-
359
- next();
360
- });
361
- },
362
- (err1?: Error | null) => {
363
- innerCallback(err1!);
364
- }
365
- );
364
+ recreateSubscription(subscriptionsToRecreate, innerCallback);
366
365
  }
367
366
  );
368
367
  },
@@ -432,12 +431,11 @@ function _repair_client_session(client: IClientBase, session: ClientSessionImpl,
432
431
  type EmptyCallback = (err?: Error) => void;
433
432
 
434
433
  export function repair_client_session(client: IClientBase, session: ClientSessionImpl, callback: EmptyCallback): void {
435
-
436
434
  if (!client) {
437
435
  doDebug && debugLog("Aborting reactivation of old session because user requested session to be close");
438
436
  return callback();
439
437
  }
440
-
438
+
441
439
  doDebug && debugLog(chalk.yellow("Starting client session repair"));
442
440
 
443
441
  const privateSession = session as any as Reconnectable;
@@ -448,13 +446,12 @@ export function repair_client_session(client: IClientBase, session: ClientSessio
448
446
  privateSession._reconnecting.pendingCallbacks.push(callback);
449
447
  return;
450
448
  }
451
-
449
+
452
450
  privateSession._reconnecting.reconnecting = true;
453
451
 
454
452
  // get old transaction queue ...
455
453
  const transactionQueue = privateSession.pendingTransactions ? privateSession.pendingTransactions.splice(0) : [];
456
454
 
457
-
458
455
  const repeatedAction = (callback: EmptyCallback) => {
459
456
  _repair_client_session(client, session, (err) => {
460
457
  if (err) {
@@ -490,10 +487,10 @@ export function repair_client_session(client: IClientBase, session: ClientSessio
490
487
  privateSession._reconnecting.pendingCallbacks = [];
491
488
 
492
489
  // re-inject element in queue
493
-
490
+
494
491
  // istanbul ignore next
495
492
  doDebug && debugLog(chalk.yellow("re-injecting transaction queue"), transactionQueue.length);
496
-
493
+
497
494
  transactionQueue.forEach((e: any) => privateSession.pendingTransactions.push(e));
498
495
  otherCallbacks.forEach((c: EmptyCallback) => c(err));
499
496
  callback(err);