node-opcua-server 2.105.1 → 2.107.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addressSpace_accessor.d.ts +29 -0
- package/dist/addressSpace_accessor.js +346 -0
- package/dist/addressSpace_accessor.js.map +1 -0
- package/dist/base_server.js +1 -1
- package/dist/base_server.js.map +1 -1
- package/dist/i_address_space_accessor.d.ts +11 -0
- package/dist/i_address_space_accessor.js +3 -0
- package/dist/i_address_space_accessor.js.map +1 -0
- package/dist/monitored_item.js +1 -1
- package/dist/monitored_item.js.map +1 -1
- package/dist/opcua_server.d.ts +1 -1
- package/dist/opcua_server.js +46 -46
- package/dist/opcua_server.js.map +1 -1
- package/dist/register_server_manager.js +1 -1
- package/dist/register_server_manager.js.map +1 -1
- package/dist/server_engine.d.ts +15 -103
- package/dist/server_engine.js +36 -370
- package/dist/server_engine.js.map +1 -1
- package/dist/server_publish_engine.js +1 -1
- package/dist/server_publish_engine.js.map +1 -1
- package/dist/server_session.js +1 -1
- package/dist/server_session.js.map +1 -1
- package/dist/server_subscription.d.ts +1 -1
- package/dist/server_subscription.js +7 -5
- package/dist/server_subscription.js.map +1 -1
- package/package.json +26 -26
- package/source/addressSpace_accessor.ts +393 -0
- package/source/i_address_space_accessor.ts +12 -0
- package/source/monitored_item.ts +2 -2
- package/source/opcua_server.ts +70 -83
- package/source/register_server_manager.ts +0 -1
- package/source/server_engine.ts +40 -512
- package/source/server_subscription.ts +2 -2
package/dist/server_engine.d.ts
CHANGED
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
* @module node-opcua-server
|
|
4
4
|
*/
|
|
5
5
|
import { EventEmitter } from "events";
|
|
6
|
-
import { AddressSpace, ISessionContext,
|
|
6
|
+
import { AddressSpace, ISessionContext, IServerBase } from "node-opcua-address-space";
|
|
7
7
|
import { DataValue } from "node-opcua-data-value";
|
|
8
8
|
import { ServerDiagnosticsSummaryDataType, ServerState, ServerStatusDataType } from "node-opcua-common";
|
|
9
|
-
import {
|
|
10
|
-
import { NodeId
|
|
9
|
+
import { LocalizedTextLike } from "node-opcua-data-model";
|
|
10
|
+
import { NodeId } from "node-opcua-nodeid";
|
|
11
11
|
import { BrowseResult } from "node-opcua-service-browse";
|
|
12
|
-
import { ReadRequest, TimestampsToReturn } from "node-opcua-service-read";
|
|
13
12
|
import { CreateSubscriptionRequestLike } from "node-opcua-client";
|
|
14
13
|
import { ObjectRegistry } from "node-opcua-object-registry";
|
|
15
14
|
import { TransferResult } from "node-opcua-service-subscription";
|
|
16
15
|
import { ApplicationDescription } from "node-opcua-service-endpoints";
|
|
17
16
|
import { HistoryReadRequest, HistoryReadResult, HistoryReadValueId } from "node-opcua-service-history";
|
|
18
17
|
import { StatusCode } from "node-opcua-status-code";
|
|
19
|
-
import { BrowseDescription, BrowsePath, BrowsePathResult, BuildInfo, BuildInfoOptions,
|
|
18
|
+
import { BrowseDescription, BrowsePath, BrowsePathResult, BuildInfo, BuildInfoOptions, WriteValue, ReadValueId, CallMethodResultOptions, ReadRequestOptions, BrowseDescriptionOptions, CallMethodRequest } from "node-opcua-types";
|
|
20
19
|
import { HistoryServerCapabilities, HistoryServerCapabilitiesOptions } from "./history_server_capabilities";
|
|
21
20
|
import { ServerCapabilities, ServerCapabilitiesOptions } from "./server_capabilities";
|
|
22
21
|
import { ServerSession } from "./server_session";
|
|
23
22
|
import { Subscription } from "./server_subscription";
|
|
24
23
|
import { OPCUAServerOptions } from "./opcua_server";
|
|
24
|
+
import { IAddressSpaceAccessor } from "./i_address_space_accessor";
|
|
25
25
|
export type StringGetter = () => string;
|
|
26
26
|
export interface ServerEngineOptions {
|
|
27
27
|
applicationUri: string | StringGetter;
|
|
@@ -44,7 +44,7 @@ export type ServerEngineShutdownTask = (this: ServerEngine) => void | Promise<vo
|
|
|
44
44
|
/**
|
|
45
45
|
*
|
|
46
46
|
*/
|
|
47
|
-
export declare class ServerEngine extends EventEmitter {
|
|
47
|
+
export declare class ServerEngine extends EventEmitter implements IAddressSpaceAccessor {
|
|
48
48
|
static readonly registry: ObjectRegistry;
|
|
49
49
|
isAuditing: boolean;
|
|
50
50
|
serverDiagnosticsSummary: ServerDiagnosticsSummaryDataType;
|
|
@@ -53,6 +53,7 @@ export declare class ServerEngine extends EventEmitter {
|
|
|
53
53
|
historyServerCapabilities: HistoryServerCapabilities;
|
|
54
54
|
clientDescription?: ApplicationDescription;
|
|
55
55
|
addressSpace: AddressSpace | null;
|
|
56
|
+
addressSpaceAccessor: IAddressSpaceAccessor | null;
|
|
56
57
|
_internalState: "creating" | "initializing" | "initialized" | "shutdown" | "disposed";
|
|
57
58
|
private _sessions;
|
|
58
59
|
private _closedSessions;
|
|
@@ -142,97 +143,12 @@ export declare class ServerEngine extends EventEmitter {
|
|
|
142
143
|
* @param callback
|
|
143
144
|
*/
|
|
144
145
|
initialize(options: OPCUAServerOptions, callback: () => void): void;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
* @param browseDescription.referenceTypeId {String|NodeId}
|
|
152
|
-
* @param [context]
|
|
153
|
-
* @return the browse result
|
|
154
|
-
*/
|
|
155
|
-
browseSingleNode(nodeId: NodeIdLike, browseDescription: BrowseDescription, context?: ISessionContext): BrowseResult;
|
|
156
|
-
browseWithAutomaticExpansion(nodesToBrowse: BrowseDescription[], context?: ISessionContext): Promise<BrowseResult[]>;
|
|
157
|
-
/**
|
|
158
|
-
*
|
|
159
|
-
*/
|
|
160
|
-
browse(nodesToBrowse: BrowseDescription[], context?: ISessionContext): BrowseResult[];
|
|
161
|
-
/**
|
|
162
|
-
*
|
|
163
|
-
* @method readSingleNode
|
|
164
|
-
* @param context
|
|
165
|
-
* @param nodeId
|
|
166
|
-
* @param attributeId
|
|
167
|
-
* @param [timestampsToReturn=TimestampsToReturn.Neither]
|
|
168
|
-
* @return DataValue
|
|
169
|
-
*/
|
|
170
|
-
readSingleNode(context: ISessionContext, nodeId: NodeId | string, attributeId: AttributeIds, timestampsToReturn?: TimestampsToReturn): DataValue;
|
|
171
|
-
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* Maximum age of the value to be read in milliseconds. The age of the value is based on the difference between
|
|
175
|
-
* the ServerTimestamp and the time when the Server starts processing the request. For example if the Client
|
|
176
|
-
* specifies a maxAge of 500 milliseconds and it takes 100 milliseconds until the Server starts processing
|
|
177
|
-
* the request, the age of the returned value could be 600 milliseconds prior to the time it was requested.
|
|
178
|
-
* If the Server has one or more values of an Attribute that are within the maximum age, it can return any one
|
|
179
|
-
* of the values or it can read a new value from the data source. The number of values of an Attribute that
|
|
180
|
-
* a Server has depends on the number of MonitoredItems that are defined for the Attribute. In any case,
|
|
181
|
-
* the Client can make no assumption about which copy of the data will be returned.
|
|
182
|
-
* If the Server does not have a value that is within the maximum age, it shall attempt to read a new value
|
|
183
|
-
* from the data source.
|
|
184
|
-
* If the Server cannot meet the requested maxAge, it returns its 'best effort' value rather than rejecting the
|
|
185
|
-
* request.
|
|
186
|
-
* This may occur when the time it takes the Server to process and return the new data value after it has been
|
|
187
|
-
* accessed is greater than the specified maximum age.
|
|
188
|
-
* If maxAge is set to 0, the Server shall attempt to read a new value from the data source.
|
|
189
|
-
* If maxAge is set to the max Int32 value or greater, the Server shall attempt to get a cached value.
|
|
190
|
-
* Negative values are invalid for maxAge.
|
|
191
|
-
*
|
|
192
|
-
* @return an array of DataValue
|
|
193
|
-
*/
|
|
194
|
-
read(context: ISessionContext, readRequest: ReadRequest): DataValue[];
|
|
195
|
-
/**
|
|
196
|
-
*
|
|
197
|
-
* @method writeSingleNode
|
|
198
|
-
* @param context
|
|
199
|
-
* @param writeValue
|
|
200
|
-
* @param callback
|
|
201
|
-
* @param callback.err
|
|
202
|
-
* @param callback.statusCode
|
|
203
|
-
* @async
|
|
204
|
-
*/
|
|
205
|
-
writeSingleNode(context: ISessionContext, writeValue: WriteValue, callback: (err: Error | null, statusCode?: StatusCode) => void): void;
|
|
206
|
-
/**
|
|
207
|
-
* write a collection of nodes
|
|
208
|
-
* @method write
|
|
209
|
-
* @param context
|
|
210
|
-
* @param nodesToWrite
|
|
211
|
-
* @param callback
|
|
212
|
-
* @param callback.err
|
|
213
|
-
* @param callback.results
|
|
214
|
-
* @async
|
|
215
|
-
*/
|
|
216
|
-
write(context: ISessionContext, nodesToWrite: WriteValue[], callback: (err: Error | null, statusCodes?: StatusCode[]) => void): void;
|
|
217
|
-
/**
|
|
218
|
-
*
|
|
219
|
-
*/
|
|
220
|
-
historyReadSingleNode(context: ISessionContext, nodeId: NodeId, attributeId: AttributeIds, historyReadDetails: ReadRawModifiedDetails | ReadEventDetails | ReadProcessedDetails | ReadAtTimeDetails, timestampsToReturn: TimestampsToReturn, continuationData: ContinuationData, callback: (err: Error | null, results?: HistoryReadResult) => void): void;
|
|
221
|
-
/**
|
|
222
|
-
*
|
|
223
|
-
* @method historyRead
|
|
224
|
-
* @param context {SessionContext}
|
|
225
|
-
* @param historyReadRequest {HistoryReadRequest}
|
|
226
|
-
* @param historyReadRequest.requestHeader {RequestHeader}
|
|
227
|
-
* @param historyReadRequest.historyReadDetails {HistoryReadDetails}
|
|
228
|
-
* @param historyReadRequest.timestampsToReturn {TimestampsToReturn}
|
|
229
|
-
* @param historyReadRequest.releaseContinuationPoints {Boolean}
|
|
230
|
-
* @param historyReadRequest.nodesToRead {HistoryReadValueId[]}
|
|
231
|
-
* @param callback
|
|
232
|
-
* @param callback.err
|
|
233
|
-
* @param callback.results {HistoryReadResult[]}
|
|
234
|
-
*/
|
|
235
|
-
historyRead(context: ISessionContext, historyReadRequest: HistoryReadRequest, callback: (err: Error | null, results: HistoryReadResult[]) => void): void;
|
|
146
|
+
browseWithAutomaticExpansion(nodesToBrowse: BrowseDescription[], context: ISessionContext): Promise<BrowseResult[]>;
|
|
147
|
+
browse(context: ISessionContext, nodesToBrowse: BrowseDescriptionOptions[]): Promise<BrowseResult[]>;
|
|
148
|
+
read(context: ISessionContext, readRequest: ReadRequestOptions): Promise<DataValue[]>;
|
|
149
|
+
write(context: ISessionContext, nodesToWrite: WriteValue[]): Promise<StatusCode[]>;
|
|
150
|
+
call(context: ISessionContext, methodsToCall: CallMethodRequest[]): Promise<CallMethodResultOptions[]>;
|
|
151
|
+
historyRead(context: ISessionContext, historyReadRequest: HistoryReadRequest): Promise<HistoryReadResult[]>;
|
|
236
152
|
getOldestInactiveSession(): ServerSession | null;
|
|
237
153
|
/**
|
|
238
154
|
* create a new server session object.
|
|
@@ -282,9 +198,8 @@ export declare class ServerEngine extends EventEmitter {
|
|
|
282
198
|
* @return {ServerSession}
|
|
283
199
|
*/
|
|
284
200
|
getSession(authenticationToken: NodeId, activeOnly?: boolean): ServerSession | null;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
browsePath(browsePath: BrowsePath): BrowsePathResult;
|
|
201
|
+
translateBrowsePaths(browsePaths: BrowsePath[]): Promise<BrowsePathResult[]>;
|
|
202
|
+
translateBrowsePath(browsePath: BrowsePath): Promise<BrowsePathResult>;
|
|
288
203
|
/**
|
|
289
204
|
*
|
|
290
205
|
* performs a call to ```asyncRefresh``` on all variable nodes that provide an async refresh func.
|
|
@@ -309,9 +224,6 @@ export declare class ServerEngine extends EventEmitter {
|
|
|
309
224
|
* @return {Subscription}
|
|
310
225
|
*/
|
|
311
226
|
_createSubscriptionOnSession(session: ServerSession, request: CreateSubscriptionRequestLike): Subscription;
|
|
312
|
-
private __findNode;
|
|
313
|
-
private _readSingleNode;
|
|
314
|
-
private _historyReadSingleNode;
|
|
315
227
|
/**
|
|
316
228
|
*/
|
|
317
229
|
private __internal_bindMethod;
|
package/dist/server_engine.js
CHANGED
|
@@ -47,11 +47,9 @@ const node_opcua_assert_1 = require("node-opcua-assert");
|
|
|
47
47
|
const node_opcua_binary_stream_1 = require("node-opcua-binary-stream");
|
|
48
48
|
const node_opcua_address_space_1 = require("node-opcua-address-space");
|
|
49
49
|
const nodeJS_1 = require("node-opcua-address-space/nodeJS");
|
|
50
|
-
const node_opcua_data_value_1 = require("node-opcua-data-value");
|
|
51
50
|
const node_opcua_common_1 = require("node-opcua-common");
|
|
52
51
|
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
53
52
|
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
|
|
54
|
-
const node_opcua_service_read_1 = require("node-opcua-service-read");
|
|
55
53
|
const node_opcua_constants_1 = require("node-opcua-constants");
|
|
56
54
|
const node_opcua_date_time_1 = require("node-opcua-date-time");
|
|
57
55
|
const node_opcua_debug_1 = require("node-opcua-debug");
|
|
@@ -60,7 +58,6 @@ const node_opcua_object_registry_1 = require("node-opcua-object-registry");
|
|
|
60
58
|
const node_opcua_service_call_1 = require("node-opcua-service-call");
|
|
61
59
|
const node_opcua_service_subscription_1 = require("node-opcua-service-subscription");
|
|
62
60
|
const node_opcua_service_endpoints_1 = require("node-opcua-service-endpoints");
|
|
63
|
-
const node_opcua_service_history_1 = require("node-opcua-service-history");
|
|
64
61
|
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
65
62
|
const node_opcua_types_1 = require("node-opcua-types");
|
|
66
63
|
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
@@ -72,6 +69,7 @@ const server_publish_engine_for_orphan_subscriptions_1 = require("./server_publi
|
|
|
72
69
|
const server_session_1 = require("./server_session");
|
|
73
70
|
const server_subscription_1 = require("./server_subscription");
|
|
74
71
|
const sessions_compatible_for_transfer_1 = require("./sessions_compatible_for_transfer");
|
|
72
|
+
const addressSpace_accessor_1 = require("./addressSpace_accessor");
|
|
75
73
|
const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
|
|
76
74
|
const errorLog = (0, node_opcua_debug_1.make_errorLog)(__filename);
|
|
77
75
|
const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
|
|
@@ -230,42 +228,13 @@ function _get_next_subscriptionId() {
|
|
|
230
228
|
debugLog(" next_subscriptionId = ", next_subscriptionId);
|
|
231
229
|
return next_subscriptionId++;
|
|
232
230
|
}
|
|
233
|
-
function checkReadProcessedDetails(historyReadDetails) {
|
|
234
|
-
if (!historyReadDetails.aggregateConfiguration) {
|
|
235
|
-
historyReadDetails.aggregateConfiguration = new node_opcua_types_1.AggregateConfiguration({
|
|
236
|
-
useServerCapabilitiesDefaults: true
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
if (historyReadDetails.aggregateConfiguration.useServerCapabilitiesDefaults) {
|
|
240
|
-
return node_opcua_status_code_1.StatusCodes.Good;
|
|
241
|
-
}
|
|
242
|
-
// The PercentDataGood and PercentDataBad shall follow the following relationship
|
|
243
|
-
// PercentDataGood ≥ (100 – PercentDataBad).
|
|
244
|
-
// If they are equal the result of the PercentDataGood calculation is used.
|
|
245
|
-
// If the values entered for PercentDataGood and PercentDataBad do not result in a valid calculation
|
|
246
|
-
// (e.g. Bad = 80; Good = 0) the result will have a StatusCode of Bad_AggregateInvalidInputs.
|
|
247
|
-
if (historyReadDetails.aggregateConfiguration.percentDataGood <
|
|
248
|
-
100 - historyReadDetails.aggregateConfiguration.percentDataBad) {
|
|
249
|
-
return node_opcua_status_code_1.StatusCodes.BadAggregateInvalidInputs;
|
|
250
|
-
}
|
|
251
|
-
// The StatusCode Bad_AggregateInvalidInputs will be returned if the value of PercentDataGood
|
|
252
|
-
// or PercentDataBad exceed 100.
|
|
253
|
-
if (historyReadDetails.aggregateConfiguration.percentDataGood > 100 ||
|
|
254
|
-
historyReadDetails.aggregateConfiguration.percentDataGood < 0) {
|
|
255
|
-
return node_opcua_status_code_1.StatusCodes.BadAggregateInvalidInputs;
|
|
256
|
-
}
|
|
257
|
-
if (historyReadDetails.aggregateConfiguration.percentDataBad > 100 ||
|
|
258
|
-
historyReadDetails.aggregateConfiguration.percentDataBad < 0) {
|
|
259
|
-
return node_opcua_status_code_1.StatusCodes.BadAggregateInvalidInputs;
|
|
260
|
-
}
|
|
261
|
-
return node_opcua_status_code_1.StatusCodes.Good;
|
|
262
|
-
}
|
|
263
231
|
/**
|
|
264
232
|
*
|
|
265
233
|
*/
|
|
266
234
|
class ServerEngine extends events_1.EventEmitter {
|
|
267
235
|
constructor(options) {
|
|
268
236
|
super();
|
|
237
|
+
this.addressSpaceAccessor = null;
|
|
269
238
|
this._globalCounter = { totalMonitoredItemCount: 0 };
|
|
270
239
|
options = options || { applicationUri: "" };
|
|
271
240
|
options.buildInfo = options.buildInfo || {};
|
|
@@ -583,6 +552,7 @@ class ServerEngine extends events_1.EventEmitter {
|
|
|
583
552
|
const startTime = new Date();
|
|
584
553
|
debugLog("Loading ", options.nodeset_filename, "...");
|
|
585
554
|
this.addressSpace = node_opcua_address_space_1.AddressSpace.create();
|
|
555
|
+
this.addressSpaceAccessor = new addressSpace_accessor_1.AddressSpaceAccessor(this.addressSpace);
|
|
586
556
|
// register namespace 1 (our namespace);
|
|
587
557
|
const serverNamespace = this.addressSpace.registerNamespace(this.serverNamespaceUrn);
|
|
588
558
|
(0, node_opcua_assert_1.assert)(serverNamespace.index === 1);
|
|
@@ -1023,20 +993,6 @@ class ServerEngine extends events_1.EventEmitter {
|
|
|
1023
993
|
setImmediate(() => callback());
|
|
1024
994
|
});
|
|
1025
995
|
}
|
|
1026
|
-
/**
|
|
1027
|
-
*
|
|
1028
|
-
* @method browseSingleNode
|
|
1029
|
-
* @param nodeId {NodeId|String} : the nodeid of the element to browse
|
|
1030
|
-
* @param browseDescription
|
|
1031
|
-
* @param browseDescription.browseDirection {BrowseDirection} :
|
|
1032
|
-
* @param browseDescription.referenceTypeId {String|NodeId}
|
|
1033
|
-
* @param [context]
|
|
1034
|
-
* @return the browse result
|
|
1035
|
-
*/
|
|
1036
|
-
browseSingleNode(nodeId, browseDescription, context) {
|
|
1037
|
-
const addressSpace = this.addressSpace;
|
|
1038
|
-
return addressSpace.browseSingleNode(nodeId, browseDescription, context);
|
|
1039
|
-
}
|
|
1040
996
|
browseWithAutomaticExpansion(nodesToBrowse, context) {
|
|
1041
997
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1042
998
|
// do expansion first
|
|
@@ -1059,239 +1015,32 @@ class ServerEngine extends events_1.EventEmitter {
|
|
|
1059
1015
|
}
|
|
1060
1016
|
}
|
|
1061
1017
|
}
|
|
1062
|
-
return this.browse(
|
|
1018
|
+
return yield this.browse(context, nodesToBrowse);
|
|
1063
1019
|
});
|
|
1064
1020
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
const results = [];
|
|
1070
|
-
for (const browseDescription of nodesToBrowse) {
|
|
1071
|
-
const nodeId = (0, node_opcua_nodeid_1.resolveNodeId)(browseDescription.nodeId);
|
|
1072
|
-
const r = this.browseSingleNode(nodeId, browseDescription, context);
|
|
1073
|
-
results.push(r);
|
|
1074
|
-
}
|
|
1075
|
-
return results;
|
|
1076
|
-
}
|
|
1077
|
-
/**
|
|
1078
|
-
*
|
|
1079
|
-
* @method readSingleNode
|
|
1080
|
-
* @param context
|
|
1081
|
-
* @param nodeId
|
|
1082
|
-
* @param attributeId
|
|
1083
|
-
* @param [timestampsToReturn=TimestampsToReturn.Neither]
|
|
1084
|
-
* @return DataValue
|
|
1085
|
-
*/
|
|
1086
|
-
readSingleNode(context, nodeId, attributeId, timestampsToReturn) {
|
|
1087
|
-
context.currentTime = (0, node_opcua_date_time_1.getCurrentClock)();
|
|
1088
|
-
return this._readSingleNode(context, new node_opcua_types_1.ReadValueId({
|
|
1089
|
-
attributeId,
|
|
1090
|
-
nodeId: (0, node_opcua_nodeid_1.resolveNodeId)(nodeId)
|
|
1091
|
-
}), timestampsToReturn);
|
|
1021
|
+
browse(context, nodesToBrowse) {
|
|
1022
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1023
|
+
return this.addressSpaceAccessor.browse(context, nodesToBrowse);
|
|
1024
|
+
});
|
|
1092
1025
|
}
|
|
1093
|
-
/**
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1096
|
-
* Maximum age of the value to be read in milliseconds. The age of the value is based on the difference between
|
|
1097
|
-
* the ServerTimestamp and the time when the Server starts processing the request. For example if the Client
|
|
1098
|
-
* specifies a maxAge of 500 milliseconds and it takes 100 milliseconds until the Server starts processing
|
|
1099
|
-
* the request, the age of the returned value could be 600 milliseconds prior to the time it was requested.
|
|
1100
|
-
* If the Server has one or more values of an Attribute that are within the maximum age, it can return any one
|
|
1101
|
-
* of the values or it can read a new value from the data source. The number of values of an Attribute that
|
|
1102
|
-
* a Server has depends on the number of MonitoredItems that are defined for the Attribute. In any case,
|
|
1103
|
-
* the Client can make no assumption about which copy of the data will be returned.
|
|
1104
|
-
* If the Server does not have a value that is within the maximum age, it shall attempt to read a new value
|
|
1105
|
-
* from the data source.
|
|
1106
|
-
* If the Server cannot meet the requested maxAge, it returns its 'best effort' value rather than rejecting the
|
|
1107
|
-
* request.
|
|
1108
|
-
* This may occur when the time it takes the Server to process and return the new data value after it has been
|
|
1109
|
-
* accessed is greater than the specified maximum age.
|
|
1110
|
-
* If maxAge is set to 0, the Server shall attempt to read a new value from the data source.
|
|
1111
|
-
* If maxAge is set to the max Int32 value or greater, the Server shall attempt to get a cached value.
|
|
1112
|
-
* Negative values are invalid for maxAge.
|
|
1113
|
-
*
|
|
1114
|
-
* @return an array of DataValue
|
|
1115
|
-
*/
|
|
1116
1026
|
read(context, readRequest) {
|
|
1117
|
-
(0,
|
|
1118
|
-
|
|
1119
|
-
(0, node_opcua_assert_1.assert)(readRequest.maxAge >= 0);
|
|
1120
|
-
const timestampsToReturn = readRequest.timestampsToReturn;
|
|
1121
|
-
const nodesToRead = readRequest.nodesToRead || [];
|
|
1122
|
-
(0, node_opcua_assert_1.assert)(Array.isArray(nodesToRead));
|
|
1123
|
-
context.currentTime = (0, node_opcua_date_time_1.getCurrentClock)();
|
|
1124
|
-
const dataValues = [];
|
|
1125
|
-
for (const readValueId of nodesToRead) {
|
|
1126
|
-
const dataValue = this._readSingleNode(context, readValueId, timestampsToReturn);
|
|
1127
|
-
if (timestampsToReturn === node_opcua_service_read_1.TimestampsToReturn.Server) {
|
|
1128
|
-
dataValue.sourceTimestamp = null;
|
|
1129
|
-
dataValue.sourcePicoseconds = 0;
|
|
1130
|
-
}
|
|
1131
|
-
if ((timestampsToReturn === node_opcua_service_read_1.TimestampsToReturn.Both || timestampsToReturn === node_opcua_service_read_1.TimestampsToReturn.Server) &&
|
|
1132
|
-
(!dataValue.serverTimestamp || dataValue.serverTimestamp.getTime() === node_opcua_date_time_1.minOPCUADate.getTime())) {
|
|
1133
|
-
dataValue.serverTimestamp = context.currentTime.timestamp;
|
|
1134
|
-
dataValue.serverPicoseconds = 0; // context.currentTime.picoseconds;
|
|
1135
|
-
}
|
|
1136
|
-
dataValues.push(dataValue);
|
|
1137
|
-
}
|
|
1138
|
-
return dataValues;
|
|
1139
|
-
}
|
|
1140
|
-
/**
|
|
1141
|
-
*
|
|
1142
|
-
* @method writeSingleNode
|
|
1143
|
-
* @param context
|
|
1144
|
-
* @param writeValue
|
|
1145
|
-
* @param callback
|
|
1146
|
-
* @param callback.err
|
|
1147
|
-
* @param callback.statusCode
|
|
1148
|
-
* @async
|
|
1149
|
-
*/
|
|
1150
|
-
writeSingleNode(context, writeValue, callback) {
|
|
1151
|
-
(0, node_opcua_assert_1.assert)(context instanceof node_opcua_address_space_1.SessionContext);
|
|
1152
|
-
(0, node_opcua_assert_1.assert)(typeof callback === "function");
|
|
1153
|
-
(0, node_opcua_assert_1.assert)(writeValue.schema.name === "WriteValue");
|
|
1154
|
-
(0, node_opcua_assert_1.assert)(writeValue.value instanceof node_opcua_data_value_1.DataValue);
|
|
1155
|
-
if (writeValue.value.value === null) {
|
|
1156
|
-
return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
|
|
1157
|
-
}
|
|
1158
|
-
(0, node_opcua_assert_1.assert)(writeValue.value.value instanceof node_opcua_variant_1.Variant);
|
|
1159
|
-
const nodeId = writeValue.nodeId;
|
|
1160
|
-
const obj = this.__findNode(nodeId);
|
|
1161
|
-
if (!obj) {
|
|
1162
|
-
return callback(null, node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown);
|
|
1163
|
-
}
|
|
1164
|
-
else {
|
|
1165
|
-
obj.writeAttribute(context, writeValue, callback);
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
/**
|
|
1169
|
-
* write a collection of nodes
|
|
1170
|
-
* @method write
|
|
1171
|
-
* @param context
|
|
1172
|
-
* @param nodesToWrite
|
|
1173
|
-
* @param callback
|
|
1174
|
-
* @param callback.err
|
|
1175
|
-
* @param callback.results
|
|
1176
|
-
* @async
|
|
1177
|
-
*/
|
|
1178
|
-
write(context, nodesToWrite, callback) {
|
|
1179
|
-
(0, node_opcua_assert_1.assert)(context instanceof node_opcua_address_space_1.SessionContext);
|
|
1180
|
-
(0, node_opcua_assert_1.assert)(typeof callback === "function");
|
|
1181
|
-
context.currentTime = (0, node_opcua_date_time_1.getCurrentClock)();
|
|
1182
|
-
(0, node_opcua_address_space_1.ensureDatatypeExtractedWithCallback)(this.addressSpace, (err2, extraDataTypeManager) => {
|
|
1183
|
-
if (err2) {
|
|
1184
|
-
return callback(err2);
|
|
1185
|
-
}
|
|
1186
|
-
const performWrite = (writeValue, inner_callback) => {
|
|
1187
|
-
(0, node_opcua_address_space_1.resolveOpaqueOnAddressSpace)(this.addressSpace, writeValue.value.value)
|
|
1188
|
-
.then(() => {
|
|
1189
|
-
this.writeSingleNode(context, writeValue, inner_callback);
|
|
1190
|
-
})
|
|
1191
|
-
.catch(inner_callback);
|
|
1192
|
-
};
|
|
1193
|
-
// tslint:disable:array-type
|
|
1194
|
-
async.map(nodesToWrite, performWrite, (err, statusCodes) => {
|
|
1195
|
-
(0, node_opcua_assert_1.assert)(Array.isArray(statusCodes));
|
|
1196
|
-
callback(err, statusCodes);
|
|
1197
|
-
});
|
|
1027
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1028
|
+
return this.addressSpaceAccessor.read(context, readRequest);
|
|
1198
1029
|
});
|
|
1199
1030
|
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
historyReadSingleNode(context, nodeId, attributeId, historyReadDetails, timestampsToReturn, continuationData, callback) {
|
|
1204
|
-
if (timestampsToReturn === node_opcua_service_read_1.TimestampsToReturn.Invalid) {
|
|
1205
|
-
callback(null, new node_opcua_service_history_1.HistoryReadResult({
|
|
1206
|
-
statusCode: node_opcua_status_code_1.StatusCodes.BadTimestampsToReturnInvalid
|
|
1207
|
-
}));
|
|
1208
|
-
return;
|
|
1209
|
-
}
|
|
1210
|
-
(0, node_opcua_assert_1.assert)(context instanceof node_opcua_address_space_1.SessionContext);
|
|
1211
|
-
this._historyReadSingleNode(context, new node_opcua_service_history_1.HistoryReadValueId({
|
|
1212
|
-
nodeId
|
|
1213
|
-
}), historyReadDetails, timestampsToReturn, continuationData, callback);
|
|
1214
|
-
}
|
|
1215
|
-
/**
|
|
1216
|
-
*
|
|
1217
|
-
* @method historyRead
|
|
1218
|
-
* @param context {SessionContext}
|
|
1219
|
-
* @param historyReadRequest {HistoryReadRequest}
|
|
1220
|
-
* @param historyReadRequest.requestHeader {RequestHeader}
|
|
1221
|
-
* @param historyReadRequest.historyReadDetails {HistoryReadDetails}
|
|
1222
|
-
* @param historyReadRequest.timestampsToReturn {TimestampsToReturn}
|
|
1223
|
-
* @param historyReadRequest.releaseContinuationPoints {Boolean}
|
|
1224
|
-
* @param historyReadRequest.nodesToRead {HistoryReadValueId[]}
|
|
1225
|
-
* @param callback
|
|
1226
|
-
* @param callback.err
|
|
1227
|
-
* @param callback.results {HistoryReadResult[]}
|
|
1228
|
-
*/
|
|
1229
|
-
historyRead(context, historyReadRequest, callback) {
|
|
1230
|
-
(0, node_opcua_assert_1.assert)(context instanceof node_opcua_address_space_1.SessionContext);
|
|
1231
|
-
(0, node_opcua_assert_1.assert)(historyReadRequest instanceof node_opcua_service_history_1.HistoryReadRequest);
|
|
1232
|
-
(0, node_opcua_assert_1.assert)(typeof callback === "function");
|
|
1233
|
-
const timestampsToReturn = historyReadRequest.timestampsToReturn;
|
|
1234
|
-
const historyReadDetails = historyReadRequest.historyReadDetails;
|
|
1235
|
-
const releaseContinuationPoints = historyReadRequest.releaseContinuationPoints;
|
|
1236
|
-
(0, node_opcua_assert_1.assert)(historyReadDetails instanceof node_opcua_service_history_1.HistoryReadDetails);
|
|
1237
|
-
// ReadAnnotationDataDetails | ReadAtTimeDetails | ReadEventDetails | ReadProcessedDetails | ReadRawModifiedDetails;
|
|
1238
|
-
const nodesToRead = historyReadRequest.nodesToRead || [];
|
|
1239
|
-
(0, node_opcua_assert_1.assert)(Array.isArray(nodesToRead));
|
|
1240
|
-
const _q = (m) => __awaiter(this, void 0, void 0, function* () {
|
|
1241
|
-
return new Promise((resolve) => {
|
|
1242
|
-
const continuationPoint = m.nodeToRead.continuationPoint;
|
|
1243
|
-
this._historyReadSingleNode(context, m.nodeToRead, m.processDetail, timestampsToReturn, { continuationPoint, releaseContinuationPoints /**, index = ??? */ }, (err, result) => {
|
|
1244
|
-
if (err && !result) {
|
|
1245
|
-
errorLog("Internal error", err.message);
|
|
1246
|
-
result = new node_opcua_service_history_1.HistoryReadResult({ statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError });
|
|
1247
|
-
}
|
|
1248
|
-
resolve(result);
|
|
1249
|
-
});
|
|
1250
|
-
});
|
|
1031
|
+
write(context, nodesToWrite) {
|
|
1032
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1033
|
+
return yield this.addressSpaceAccessor.write(context, nodesToWrite);
|
|
1251
1034
|
});
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
}
|
|
1257
|
-
// chkec parameters
|
|
1258
|
-
const parameterStatus = checkReadProcessedDetails(historyReadDetails);
|
|
1259
|
-
if (parameterStatus !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
1260
|
-
return callback(null, [new node_opcua_service_history_1.HistoryReadResult({ statusCode: parameterStatus })]);
|
|
1261
|
-
}
|
|
1262
|
-
const promises = [];
|
|
1263
|
-
let index = 0;
|
|
1264
|
-
for (const nodeToRead of nodesToRead) {
|
|
1265
|
-
const aggregateType = historyReadDetails.aggregateType[index];
|
|
1266
|
-
const processDetail = new node_opcua_types_1.ReadProcessedDetails(Object.assign(Object.assign({}, historyReadDetails), { aggregateType: [aggregateType] }));
|
|
1267
|
-
promises.push(_q({ nodeToRead, processDetail, index }));
|
|
1268
|
-
index++;
|
|
1269
|
-
}
|
|
1270
|
-
Promise.all(promises).then((results) => {
|
|
1271
|
-
callback(null, results);
|
|
1272
|
-
});
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
|
-
const _r = (nodeToRead, index) => __awaiter(this, void 0, void 0, function* () {
|
|
1276
|
-
const continuationPoint = nodeToRead.continuationPoint;
|
|
1277
|
-
return new Promise((resolve, reject) => {
|
|
1278
|
-
this._historyReadSingleNode(context, nodeToRead, historyReadDetails, timestampsToReturn, { continuationPoint, releaseContinuationPoints, index }, (err, result) => {
|
|
1279
|
-
if (err && !result) {
|
|
1280
|
-
result = new node_opcua_service_history_1.HistoryReadResult({ statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError });
|
|
1281
|
-
}
|
|
1282
|
-
resolve(result);
|
|
1283
|
-
// it's not guaranteed that the historical read process is really asynchronous
|
|
1284
|
-
});
|
|
1285
|
-
});
|
|
1035
|
+
}
|
|
1036
|
+
call(context, methodsToCall) {
|
|
1037
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1038
|
+
return yield this.addressSpaceAccessor.call(context, methodsToCall);
|
|
1286
1039
|
});
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
index++;
|
|
1292
|
-
}
|
|
1293
|
-
Promise.all(promises).then((results) => {
|
|
1294
|
-
callback(null, results);
|
|
1040
|
+
}
|
|
1041
|
+
historyRead(context, historyReadRequest) {
|
|
1042
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1043
|
+
return this.addressSpaceAccessor.historyRead(context, historyReadRequest);
|
|
1295
1044
|
});
|
|
1296
1045
|
}
|
|
1297
1046
|
getOldestInactiveSession() {
|
|
@@ -1526,10 +1275,20 @@ class ServerEngine extends events_1.EventEmitter {
|
|
|
1526
1275
|
}
|
|
1527
1276
|
return session;
|
|
1528
1277
|
}
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1278
|
+
translateBrowsePaths(browsePaths) {
|
|
1279
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1280
|
+
const browsePathResults = [];
|
|
1281
|
+
for (const browsePath of browsePaths) {
|
|
1282
|
+
const result = yield this.translateBrowsePath(browsePath);
|
|
1283
|
+
browsePathResults.push(result);
|
|
1284
|
+
}
|
|
1285
|
+
return browsePathResults;
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
translateBrowsePath(browsePath) {
|
|
1289
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1290
|
+
return this.addressSpace.browsePath(browsePath);
|
|
1291
|
+
});
|
|
1533
1292
|
}
|
|
1534
1293
|
/**
|
|
1535
1294
|
*
|
|
@@ -1664,99 +1423,6 @@ class ServerEngine extends events_1.EventEmitter {
|
|
|
1664
1423
|
});
|
|
1665
1424
|
return subscription;
|
|
1666
1425
|
}
|
|
1667
|
-
__findNode(nodeId) {
|
|
1668
|
-
var _a;
|
|
1669
|
-
if (nodeId.namespace >= (((_a = this.addressSpace) === null || _a === void 0 ? void 0 : _a.getNamespaceArray().length) || 0)) {
|
|
1670
|
-
return null;
|
|
1671
|
-
}
|
|
1672
|
-
const namespace = this.addressSpace.getNamespace(nodeId.namespace);
|
|
1673
|
-
return namespace.findNode2(nodeId);
|
|
1674
|
-
}
|
|
1675
|
-
_readSingleNode(context, nodeToRead, timestampsToReturn) {
|
|
1676
|
-
(0, node_opcua_assert_1.assert)(context instanceof node_opcua_address_space_1.SessionContext);
|
|
1677
|
-
const nodeId = nodeToRead.nodeId;
|
|
1678
|
-
const attributeId = nodeToRead.attributeId;
|
|
1679
|
-
const indexRange = nodeToRead.indexRange;
|
|
1680
|
-
const dataEncoding = nodeToRead.dataEncoding;
|
|
1681
|
-
if (timestampsToReturn === node_opcua_service_read_1.TimestampsToReturn.Invalid) {
|
|
1682
|
-
return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadTimestampsToReturnInvalid });
|
|
1683
|
-
}
|
|
1684
|
-
timestampsToReturn = (0, node_opcua_data_value_1.coerceTimestampsToReturn)(timestampsToReturn);
|
|
1685
|
-
const obj = this.__findNode(nodeId);
|
|
1686
|
-
let dataValue;
|
|
1687
|
-
if (!obj) {
|
|
1688
|
-
// may be return BadNodeIdUnknown in dataValue instead ?
|
|
1689
|
-
// Object Not Found
|
|
1690
|
-
return new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown });
|
|
1691
|
-
}
|
|
1692
|
-
else {
|
|
1693
|
-
// check access
|
|
1694
|
-
// BadUserAccessDenied
|
|
1695
|
-
// BadNotReadable
|
|
1696
|
-
// invalid attributes : BadNodeAttributesInvalid
|
|
1697
|
-
// invalid range : BadIndexRangeInvalid
|
|
1698
|
-
dataValue = obj.readAttribute(context, attributeId, indexRange, dataEncoding);
|
|
1699
|
-
dataValue = (0, node_opcua_data_value_1.apply_timestamps_no_copy)(dataValue, timestampsToReturn, attributeId);
|
|
1700
|
-
return dataValue;
|
|
1701
|
-
}
|
|
1702
|
-
}
|
|
1703
|
-
_historyReadSingleNode(context, nodeToRead, historyReadDetails, timestampsToReturn, continuationData, callback) {
|
|
1704
|
-
(0, node_opcua_assert_1.assert)(context instanceof node_opcua_address_space_1.SessionContext);
|
|
1705
|
-
(0, node_opcua_assert_1.assert)(typeof callback === "function");
|
|
1706
|
-
const nodeId = nodeToRead.nodeId;
|
|
1707
|
-
const indexRange = nodeToRead.indexRange;
|
|
1708
|
-
const dataEncoding = nodeToRead.dataEncoding;
|
|
1709
|
-
const continuationPoint = nodeToRead.continuationPoint;
|
|
1710
|
-
timestampsToReturn = (0, node_opcua_data_value_1.coerceTimestampsToReturn)(timestampsToReturn);
|
|
1711
|
-
if (timestampsToReturn === node_opcua_service_read_1.TimestampsToReturn.Invalid) {
|
|
1712
|
-
return callback(null, new node_opcua_service_history_1.HistoryReadResult({ statusCode: node_opcua_status_code_1.StatusCodes.BadTimestampsToReturnInvalid }));
|
|
1713
|
-
}
|
|
1714
|
-
const obj = this.__findNode(nodeId);
|
|
1715
|
-
if (!obj) {
|
|
1716
|
-
// may be return BadNodeIdUnknown in dataValue instead ?
|
|
1717
|
-
// Object Not Found
|
|
1718
|
-
callback(null, new node_opcua_service_history_1.HistoryReadResult({ statusCode: node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown }));
|
|
1719
|
-
return;
|
|
1720
|
-
}
|
|
1721
|
-
else {
|
|
1722
|
-
// istanbul ignore next
|
|
1723
|
-
if (!obj.historyRead) {
|
|
1724
|
-
// note : Object and View may also support historyRead to provide Event historical data
|
|
1725
|
-
// todo implement historyRead for Object and View
|
|
1726
|
-
const msg = " this node doesn't provide historyRead! probably not a UAVariable\n " +
|
|
1727
|
-
obj.nodeId.toString() +
|
|
1728
|
-
" " +
|
|
1729
|
-
obj.browseName.toString() +
|
|
1730
|
-
"\n" +
|
|
1731
|
-
"with " +
|
|
1732
|
-
nodeToRead.toString() +
|
|
1733
|
-
"\n" +
|
|
1734
|
-
"HistoryReadDetails " +
|
|
1735
|
-
historyReadDetails.toString();
|
|
1736
|
-
if (doDebug) {
|
|
1737
|
-
debugLog(chalk_1.default.cyan("ServerEngine#_historyReadSingleNode "), chalk_1.default.white.bold(msg));
|
|
1738
|
-
}
|
|
1739
|
-
const err = new Error(msg);
|
|
1740
|
-
// object has no historyRead method
|
|
1741
|
-
setImmediate(callback.bind(null, err));
|
|
1742
|
-
return;
|
|
1743
|
-
}
|
|
1744
|
-
// check access
|
|
1745
|
-
// BadUserAccessDenied
|
|
1746
|
-
// BadNotReadable
|
|
1747
|
-
// invalid attributes : BadNodeAttributesInvalid
|
|
1748
|
-
// invalid range : BadIndexRangeInvalid
|
|
1749
|
-
obj.historyRead(context, historyReadDetails, indexRange, dataEncoding, continuationData, (err, result) => {
|
|
1750
|
-
if (err || !result) {
|
|
1751
|
-
return callback(err);
|
|
1752
|
-
}
|
|
1753
|
-
(0, node_opcua_assert_1.assert)(result.statusCode instanceof node_opcua_status_code_1.StatusCode);
|
|
1754
|
-
(0, node_opcua_assert_1.assert)(result.isValid());
|
|
1755
|
-
// result = apply_timestamps(result, timestampsToReturn, attributeId);
|
|
1756
|
-
callback(err, result);
|
|
1757
|
-
});
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
1426
|
/**
|
|
1761
1427
|
*/
|
|
1762
1428
|
__internal_bindMethod(nodeId, func) {
|
|
@@ -1793,6 +1459,6 @@ class ServerEngine extends events_1.EventEmitter {
|
|
|
1793
1459
|
return subscriptionDiagnosticsArrayNode;
|
|
1794
1460
|
}
|
|
1795
1461
|
}
|
|
1796
|
-
ServerEngine.registry = new node_opcua_object_registry_1.ObjectRegistry();
|
|
1797
1462
|
exports.ServerEngine = ServerEngine;
|
|
1463
|
+
ServerEngine.registry = new node_opcua_object_registry_1.ObjectRegistry();
|
|
1798
1464
|
//# sourceMappingURL=server_engine.js.map
|