Skip to content

Commit

Permalink
export AccessLevel to xml
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed May 19, 2020
1 parent 60a65f2 commit 9b40b9a
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 34 deletions.
8 changes: 2 additions & 6 deletions packages/node-opcua-address-space/source/address_space_ts.ts
Expand Up @@ -276,8 +276,6 @@ export type ContinuationPoint = Buffer;

export interface VariableAttributes {
dataType: NodeId;
accessLevel: number;
userAccessLevel: number;
valueRank: number;
minimumSamplingInterval: number;
}
Expand Down Expand Up @@ -980,8 +978,6 @@ export declare class UAVariableType extends BaseNode implements VariableAttribut
public readonly subtypeOf: NodeId | null;

public dataType: NodeId;
public accessLevel: number;
public userAccessLevel: number;
public valueRank: number;
public minimumSamplingInterval: number;
public arrayDimensions: number[];
Expand Down Expand Up @@ -1097,7 +1093,7 @@ export interface VariableStuff {
* Note that the maximum length of an array transferred on the wire is 2147483647 (max Int32)
* and a multi-dimensional array is encoded as a one dimensional array.
*/
arrayDimensions?: UInt32[];
arrayDimensions?: UInt32[] | null;

/**
* The AccessLevel Attribute is used to indicate how the Value of a Variable can be accessed
Expand Down Expand Up @@ -1495,7 +1491,7 @@ export interface UASessionDiagnosticsSummary extends UAObject {

export interface UAServerDiagnostics extends UAObject {
sessionsDiagnosticsSummary: UASessionDiagnosticsSummary;

enabledFlag: UAVariableT<boolean, DataType.Boolean>;
bindExtensionObject(obj: UAServerDiagnosticsSummary): UAServerDiagnosticsSummary;
}

Expand Down
Expand Up @@ -13,13 +13,13 @@ function isChannelSecure(channel: IChannelBase): boolean {
}

function newIsUserReadable(this: BaseNode, context: SessionContext): boolean {
if (context ) {
if (context) {
if (!context.session) {
console.log(" context has no session", context);
// console.log(" context has no session", context);
return false;
}
if (!context.session.channel) {
console.log(" context has no channel", context);
// console.log(" context has no channel", context);
return false;
}
if (!isChannelSecure(context.session.channel)) {
Expand All @@ -35,7 +35,7 @@ function replaceMethod(obj: any, method: string, func: any) {
throw new Error("Icannot find method " + method + " on object " + obj.browseName.toString());
}
obj[method] = function (this: any, ...args: any[]) {
const ret = func.apply(this, args);
const ret = func.apply(this, args);
if (!ret) {
return false;
}
Expand All @@ -57,7 +57,7 @@ export function ensureObjectIsSecure(node: BaseNode) {

variable.setPermissions({
CurrentRead: ["!*", "Supervisor", "ConfigAdmin", "SystemAdmin"],
CurrentWrite: ["!*" ]
CurrentWrite: ["!*"]
});

}
Expand Down
24 changes: 15 additions & 9 deletions packages/node-opcua-address-space/src/base_node_private.ts
Expand Up @@ -73,7 +73,7 @@ export function BaseNode_removePrivate(self: BaseNode): void {
export function BaseNode_getPrivate(self: BaseNode): BaseNodeCache {
return g_weakMap.get(self);
}

const hasTypeDefinition_ReferenceTypeNodeId = resolveNodeId("HasTypeDefinition");

export interface ToStringOption {
Expand Down Expand Up @@ -245,6 +245,7 @@ export function UAVariable_toString(
BaseNode_toString.call(this, options);
_UAInstance_toString.call(this, options);
VariableOrVariableType_toString.call(this, options);
AccessLevelFlags_toString.call(this, options);
BaseNode_References_toString.call(this, options);
}

Expand Down Expand Up @@ -278,6 +279,19 @@ function accessLevelFlagToString(flag: AccessLevelFlag): string {
return str.join(" | ");
}

function AccessLevelFlags_toString(
this: UAVariable,
options: ToStringOption
) {
assert(options);

const _private = BaseNode_getPrivate(this);
options.add(options.padding + chalk.yellow(" accessLevel : ") + " " +
accessLevelFlagToString(this.accessLevel));
options.add(options.padding + chalk.yellow(" userAccessLevel : ") + " " +
accessLevelFlagToString(this.userAccessLevel));

}
export function VariableOrVariableType_toString(
this: UAVariableType | UAVariable,
options: ToStringOption
Expand All @@ -301,14 +315,6 @@ export function VariableOrVariableType_toString(
}
}

if (this.accessLevel) {
options.add(options.padding + chalk.yellow(" accessLevel : ") + " " +
accessLevelFlagToString(this.accessLevel));
}
if (this.userAccessLevel) {
options.add(options.padding + chalk.yellow(" userAccessLevel : ") + " " +
accessLevelFlagToString(this.userAccessLevel));
}
if (this.hasOwnProperty("valueRank")) {
options.add(options.padding + chalk.yellow(" valueRank : ") + " " +
this.valueRank.toString());
Expand Down
14 changes: 9 additions & 5 deletions packages/node-opcua-address-space/src/namespace.ts
Expand Up @@ -108,8 +108,12 @@ const regExpNamespaceDotBrowseName = /^[0-9]+:(.*)/;

export interface AddFolderOptions {
browseName: QualifiedNameLike;

}

interface AddVariableOptions2 extends AddVariableOptions {
nodeClass?: NodeClass.Variable
};

function detachNode(node: BaseNode) {
const addressSpace = node.addressSpace;

Expand Down Expand Up @@ -415,7 +419,7 @@ export class UANamespace implements NamespacePublic {
} else {
assert(!options.typeDefinition || options.typeDefinition !== "PropertyType");
}
return this._addVariable(options);
return this._addVariable(options as AddVariableOptions2);
}

public addView(options: AddViewOptions): UAView {
Expand Down Expand Up @@ -2086,7 +2090,7 @@ export class UANamespace implements NamespacePublic {
/**
* @private
*/
private _addVariable(options: any): UAVariablePublic {
private _addVariable(options: AddVariableOptions2): UAVariablePublic {

const addressSpace = this.addressSpace;

Expand All @@ -2113,7 +2117,7 @@ export class UANamespace implements NamespacePublic {
assert(typeDefinition instanceof NodeId);

// ------------------------------------------ DataType
options.dataType = addressSpace._coerce_DataType(options.dataType);
options.dataType = addressSpace._coerce_DataType(options.dataType!);

options.valueRank = utils.isNullOrUndefined(options.valueRank) ? -1 : options.valueRank;
assert(_.isFinite(options.valueRank));
Expand All @@ -2123,7 +2127,7 @@ export class UANamespace implements NamespacePublic {
assert(_.isArray(options.arrayDimensions) || options.arrayDimensions === null);
// -----------------------------------------------------

options.minimumSamplingInterval = +options.minimumSamplingInterval || 0;
options.minimumSamplingInterval = (options.minimumSamplingInterval !== undefined) ? +options.minimumSamplingInterval : 0;
let references = options.references || ([] as AddReferenceOpts[]);

references = ([] as AddReferenceOpts[]).concat(references, [
Expand Down
Expand Up @@ -9,7 +9,7 @@ const XMLWriter = require("xml-writer");
import * as _ from "underscore";

import { assert } from "node-opcua-assert";
import { BrowseDirection, LocalizedText, makeNodeClassMask, makeResultMask, NodeClass } from "node-opcua-data-model";
import { BrowseDirection, LocalizedText, makeNodeClassMask, makeResultMask, NodeClass, makeAccessLevelFlag } from "node-opcua-data-model";
import { QualifiedName } from "node-opcua-data-model";
import {
FieldBasic,
Expand Down Expand Up @@ -586,6 +586,7 @@ function dumpReferencedNodes(
}
}

const currentReadFlag = makeAccessLevelFlag("CurrentRead");
function dumpCommonAttributes(
xw: XmlWriter,
node: BaseNode
Expand All @@ -602,6 +603,12 @@ function dumpCommonAttributes(
xw.writeAttribute("IsAbstract", (node as any).isAbstract ? "true" : "false");
}
}
if (node.hasOwnProperty("accessLevel")) {
// CurrentRead is by default
if ((node as any).accessLevel !== currentReadFlag) {
xw.writeAttribute("AccessLevel", (node as any).accessLevel);
}
}
}

function dumpCommonElements(
Expand Down
4 changes: 2 additions & 2 deletions packages/node-opcua-address-space/src/ua_variable.ts
Expand Up @@ -69,14 +69,14 @@ function isGoodish(statusCode: StatusCode) {
return statusCode.value < 0x10000000;
}

function adjust_accessLevel(accessLevel: any) {
export function adjust_accessLevel(accessLevel: any): AccessLevelFlag {
accessLevel = utils.isNullOrUndefined(accessLevel) ? "CurrentRead | CurrentWrite" : accessLevel;
accessLevel = makeAccessLevelFlag(accessLevel);
assert(_.isFinite(accessLevel));
return accessLevel;
}

function adjust_userAccessLevel(userAccessLevel: any, accessLevel: any) {
export function adjust_userAccessLevel(userAccessLevel: any, accessLevel: any): AccessLevelFlag {
userAccessLevel = utils.isNullOrUndefined(userAccessLevel) ? "CurrentRead | CurrentWrite" : userAccessLevel;
userAccessLevel = makeAccessLevelFlag(userAccessLevel);
accessLevel = utils.isNullOrUndefined(accessLevel) ? "CurrentRead | CurrentWrite" : accessLevel;
Expand Down
6 changes: 1 addition & 5 deletions packages/node-opcua-address-space/src/ua_variable_type.ts
Expand Up @@ -42,7 +42,7 @@ import * as tools from "./tool_isSupertypeOf";
import { get_subtypeOfObj } from "./tool_isSupertypeOf";
import { get_subtypeOf } from "./tool_isSupertypeOf";
import { UAObjectType } from "./ua_object_type";
import { UAVariable } from "./ua_variable";
import { UAVariable, adjust_accessLevel, adjust_userAccessLevel } from "./ua_variable";

const debugLog = make_debugLog(__filename);
const doDebug = checkDebugFlag(__filename);
Expand All @@ -62,8 +62,6 @@ export class UAVariableType extends BaseNode implements UAVariableTypePublic {

public readonly isAbstract: boolean;
public dataType: NodeId;
public readonly accessLevel: number;
public readonly userAccessLevel: number;
public valueRank: number;
public arrayDimensions: number[];
public readonly minimumSamplingInterval: number;
Expand All @@ -74,8 +72,6 @@ export class UAVariableType extends BaseNode implements UAVariableTypePublic {

super(options);

this.accessLevel = 0;
this.userAccessLevel = 0;
this.minimumSamplingInterval = 0;

this.historizing = isNullOrUndefined(options.historizing) ? false : options.historizing;
Expand Down
43 changes: 42 additions & 1 deletion packages/node-opcua-address-space/test/test_nodeset_to_xml.ts
Expand Up @@ -21,7 +21,7 @@ import {

import * as nodesets from "node-opcua-nodesets";
import { randomGuid } from "node-opcua-basic-types";
import { coerceLocalizedText } from "../../node-opcua-data-model/dist";
import { coerceLocalizedText, makeAccessLevelFlag } from "../../node-opcua-data-model/dist";

const doDebug = process.env.DEBUGTEST || false;

Expand Down Expand Up @@ -485,6 +485,47 @@ describe("Namespace to NodeSet2.xml", () => {
</UANodeSet>`
);
});

it("should emit AccessLevel attribute when needed (UAVariable)", () => {

const acessLevelFlag = makeAccessLevelFlag("CurrentRead | CurrentWrite | HistoryRead");

const myVariable = namespace.addVariable({
accessLevel: acessLevelFlag,
browseName: "MyVariable",
dataType: DataType.Double,
typeDefinition: "BaseVariableType",
});

myVariable.accessLevel.should.eql(acessLevelFlag);

let xml = namespace.toNodeset2XML();
xml = xml.replace(/LastModified="([^"]*)"/g, "LastModified=\"YYYY-MM-DD\"");
xml.should.eql(
`<?xml version="1.0"?>
<UANodeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd">
<NamespaceUris>
<Uri>http://MYNAMESPACE</Uri>
</NamespaceUris>
<Models/>
<Aliases>
<Alias Alias="Double">i=11</Alias>
<Alias Alias="HasTypeDefinition">i=40</Alias>
</Aliases>
<!--ReferenceTypes-->
<!--ObjectTypes-->
<!--VariableTypes-->
<!--Other Nodes-->
<UAVariable NodeId="ns=1;i=1000" BrowseName="1:MyVariable" AccessLevel="7" DataType="Double">
<DisplayName>MyVariable</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=62</Reference>
</References>
</UAVariable>
</UANodeSet>`);

});

});

describe("nodeset2.xml with more than one referenced namespace", function (this: any) {
Expand Down

0 comments on commit 9b40b9a

Please sign in to comment.