Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
opcua-asyncio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nikola Balog
opcua-asyncio
Commits
c1162fb4
Commit
c1162fb4
authored
May 30, 2018
by
oroulet
Committed by
oroulet
Jun 04, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reduce number of dictionnary lookup in address space. might break something...
parent
46a1ebd5
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
57 additions
and
46 deletions
+57
-46
opcua/server/address_space.py
opcua/server/address_space.py
+55
-44
opcua/server/standard_address_space/standard_address_space.py
...a/server/standard_address_space/standard_address_space.py
+2
-2
No files found.
opcua/server/address_space.py
View file @
c1162fb4
...
...
@@ -188,54 +188,60 @@ class NodeManagementService(object):
results
.
append
(
self
.
_add_node
(
item
,
user
))
return
results
def
try_add_nodes
(
self
,
addnodeitems
,
user
=
User
.
Admin
):
def
try_add_nodes
(
self
,
addnodeitems
,
user
=
User
.
Admin
,
check
=
True
):
for
item
in
addnodeitems
:
ret
=
self
.
_add_node
(
item
,
user
)
ret
=
self
.
_add_node
(
item
,
user
,
check
=
check
)
if
not
ret
.
StatusCode
.
is_good
():
yield
item
def
_add_node
(
self
,
item
,
user
):
def
_add_node
(
self
,
item
,
user
,
check
=
True
):
self
.
logger
.
debug
(
"Adding node %s %s"
,
item
.
RequestedNewNodeId
,
item
.
BrowseName
)
result
=
ua
.
AddNodesResult
()
# If Identifier of requested NodeId is null we generate a new NodeId using
# the namespace of the nodeid, this is an extention of the spec to allow
# to requests the server to generate a new nodeid in a specified namespace
if
not
user
==
User
.
Admin
:
result
.
StatusCode
=
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadUserAccessDenied
)
return
result
if
item
.
RequestedNewNodeId
.
has_null_identifier
():
# If Identifier of requested NodeId is null we generate a new NodeId using
# the namespace of the nodeid, this is an extention of the spec to allow
# to requests the server to generate a new nodeid in a specified namespace
self
.
logger
.
debug
(
"RequestedNewNodeId has null identifier, generating Identifier"
)
nodedata
=
NodeData
(
self
.
_aspace
.
generate_nodeid
(
item
.
RequestedNewNodeId
.
NamespaceIndex
)
)
item
.
RequestedNewNodeId
=
self
.
_aspace
.
generate_nodeid
(
item
.
RequestedNewNodeId
.
NamespaceIndex
)
else
:
nodedata
=
NodeData
(
item
.
RequestedNewNodeId
)
if
nodedata
.
nodeid
in
self
.
_aspace
:
self
.
logger
.
warning
(
"AddNodesItem: Requested NodeId %s already exists"
,
nodedata
.
nodeid
)
result
.
StatusCode
=
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadNodeIdExists
)
return
result
if
item
.
RequestedNewNodeId
in
self
.
_aspace
:
self
.
logger
.
warning
(
"AddNodesItem: Requested NodeId %s already exists"
,
item
.
RequestedNewNodeId
)
result
.
StatusCode
=
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadNodeIdExists
)
return
result
if
item
.
ParentNodeId
.
is_null
():
# self.logger.warning("add_node: creating node %s without parent", nodedata.nodeid)
# should return Error here, but the standard namespace define many nodes without parents...
pass
elif
item
.
ParentNodeId
not
in
self
.
_aspace
:
self
.
logger
.
warning
(
"add_node: while adding node %s, requested parent node %s does not exists"
,
nodedata
.
nodeid
,
item
.
ParentNodeId
)
self
.
logger
.
info
(
"add_node: while adding node %s, requested parent node is null %s %s"
,
item
.
RequestedNewNodeId
,
item
.
ParentNodeId
,
item
.
ParentNodeId
.
is_null
())
if
check
:
result
.
StatusCode
=
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadParentNodeIdInvalid
)
return
result
parentdata
=
self
.
_aspace
.
get
(
item
.
ParentNodeId
)
if
parentdata
is
None
and
not
item
.
ParentNodeId
.
is_null
():
self
.
logger
.
info
(
"add_node: while adding node %s, requested parent node %s does not exists"
,
item
.
RequestedNewNodeId
,
item
.
ParentNodeId
)
result
.
StatusCode
=
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadParentNodeIdInvalid
)
return
result
if
not
user
==
User
.
Admin
:
result
.
StatusCode
=
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadUserAccessDenied
)
return
result
nodedata
=
NodeData
(
item
.
RequestedNewNodeId
)
self
.
_add_node_attributes
(
nodedata
,
item
)
# now add our node to db
self
.
_aspace
[
nodedata
.
nodeid
]
=
nodedata
if
not
item
.
ParentNodeId
.
is_null
()
:
self
.
_add_ref_from_parent
(
nodedata
,
item
)
self
.
_add_ref_to_parent
(
nodedata
,
item
,
user
)
if
parentdata
is
not
None
:
self
.
_add_ref_from_parent
(
nodedata
,
item
,
parentdata
)
self
.
_add_ref_to_parent
(
nodedata
,
item
,
parentdata
)
# add type definition
if
item
.
TypeDefinition
!=
ua
.
NodeId
():
self
.
_add_type_definition
(
nodedata
,
item
,
user
)
self
.
_add_type_definition
(
nodedata
,
item
)
result
.
StatusCode
=
ua
.
StatusCode
()
result
.
AddedNodeId
=
nodedata
.
nodeid
...
...
@@ -256,20 +262,18 @@ class NodeManagementService(object):
# add requested attrs
self
.
_add_nodeattributes
(
item
.
NodeAttributes
,
nodedata
)
def
_add_unique_reference
(
self
,
source
,
desc
):
refs
=
self
.
_aspace
[
source
].
references
for
r
in
refs
:
def
_add_unique_reference
(
self
,
nodedata
,
desc
):
for
r
in
nodedata
.
references
:
if
r
.
ReferenceTypeId
==
desc
.
ReferenceTypeId
and
r
.
NodeId
==
desc
.
NodeId
:
if
r
.
IsForward
!=
desc
.
IsForward
:
if
r
.
IsForward
!=
desc
.
IsForward
:
self
.
logger
.
error
(
"Cannot add conflicting reference %s "
,
str
(
desc
))
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadReferenceNotAllowed
)
break
# ref already exists
break
# ref already exists
else
:
ref
s
.
append
(
desc
)
nodedata
.
reference
s
.
append
(
desc
)
return
ua
.
StatusCode
()
def
_add_ref_from_parent
(
self
,
nodedata
,
item
):
def
_add_ref_from_parent
(
self
,
nodedata
,
item
,
parentdata
):
desc
=
ua
.
ReferenceDescription
()
desc
.
ReferenceTypeId
=
item
.
ReferenceTypeId
desc
.
NodeId
=
nodedata
.
nodeid
...
...
@@ -278,25 +282,25 @@ class NodeManagementService(object):
desc
.
DisplayName
=
item
.
NodeAttributes
.
DisplayName
desc
.
TypeDefinition
=
item
.
TypeDefinition
desc
.
IsForward
=
True
self
.
_add_unique_reference
(
item
.
ParentNodeId
,
desc
)
self
.
_add_unique_reference
(
parentdata
,
desc
)
def
_add_ref_to_parent
(
self
,
nodedata
,
item
,
user
):
def
_add_ref_to_parent
(
self
,
nodedata
,
item
,
parentdata
):
addref
=
ua
.
AddReferencesItem
()
addref
.
ReferenceTypeId
=
item
.
ReferenceTypeId
addref
.
SourceNodeId
=
nodedata
.
nodeid
addref
.
TargetNodeId
=
item
.
ParentNodeId
addref
.
TargetNodeClass
=
self
.
_aspace
[
item
.
ParentNodeId
]
.
attributes
[
ua
.
AttributeIds
.
NodeClass
].
value
.
Value
.
Value
addref
.
TargetNodeClass
=
parentdata
.
attributes
[
ua
.
AttributeIds
.
NodeClass
].
value
.
Value
.
Value
addref
.
IsForward
=
False
self
.
_add_reference
(
addref
,
user
)
self
.
_add_reference
_no_check
(
nodedata
,
addref
)
def
_add_type_definition
(
self
,
nodedata
,
item
,
user
):
def
_add_type_definition
(
self
,
nodedata
,
item
):
addref
=
ua
.
AddReferencesItem
()
addref
.
SourceNodeId
=
nodedata
.
nodeid
addref
.
IsForward
=
True
addref
.
ReferenceTypeId
=
ua
.
NodeId
(
ua
.
ObjectIds
.
HasTypeDefinition
)
addref
.
TargetNodeId
=
item
.
TypeDefinition
addref
.
TargetNodeClass
=
ua
.
NodeClass
.
DataType
self
.
_add_reference
(
addref
,
user
)
self
.
_add_reference
_no_check
(
nodedata
,
addref
)
def
delete_nodes
(
self
,
deletenodeitems
,
user
=
User
.
Admin
):
results
=
[]
...
...
@@ -345,12 +349,16 @@ class NodeManagementService(object):
yield
ref
def
_add_reference
(
self
,
addref
,
user
):
if
addref
.
SourceNodeId
not
in
self
.
_aspace
:
sourcedata
=
self
.
_aspace
.
get
(
addref
.
SourceNodeId
)
if
sourcedata
is
None
:
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadSourceNodeIdInvalid
)
if
addref
.
TargetNodeId
not
in
self
.
_aspace
:
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadTargetNodeIdInvalid
)
if
user
!=
User
.
Admin
:
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadUserAccessDenied
)
return
self
.
_add_reference_no_check
(
sourcedata
,
addref
)
def
_add_reference_no_check
(
self
,
sourcedata
,
addref
):
rdesc
=
ua
.
ReferenceDescription
()
rdesc
.
ReferenceTypeId
=
addref
.
ReferenceTypeId
rdesc
.
IsForward
=
addref
.
IsForward
...
...
@@ -362,7 +370,7 @@ class NodeManagementService(object):
dname
=
self
.
_aspace
.
get_attribute_value
(
addref
.
TargetNodeId
,
ua
.
AttributeIds
.
DisplayName
).
Value
.
Value
if
dname
:
rdesc
.
DisplayName
=
dname
return
self
.
_add_unique_reference
(
addref
.
SourceNodeId
,
rdesc
)
return
self
.
_add_unique_reference
(
sourcedata
,
rdesc
)
def
delete_references
(
self
,
refs
,
user
=
User
.
Admin
):
result
=
[]
...
...
@@ -370,7 +378,7 @@ class NodeManagementService(object):
result
.
append
(
self
.
_delete_reference
(
ref
,
user
))
return
result
def
_delete_unique_reference
(
self
,
item
,
invert
=
False
):
def
_delete_unique_reference
(
self
,
item
,
invert
=
False
):
if
invert
:
source
,
target
,
forward
=
item
.
TargetNodeId
,
item
.
SourceNodeId
,
not
item
.
IsForward
else
:
...
...
@@ -485,8 +493,11 @@ class AddressSpace(object):
def
__getitem__
(
self
,
nodeid
):
with
self
.
_lock
:
if
nodeid
in
self
.
_nodes
:
return
self
.
_nodes
.
__getitem__
(
nodeid
)
return
self
.
_nodes
.
__getitem__
(
nodeid
)
def
get
(
self
,
nodeid
):
with
self
.
_lock
:
return
self
.
_nodes
.
get
(
nodeid
,
None
)
def
__setitem__
(
self
,
nodeid
,
value
):
with
self
.
_lock
:
...
...
opcua/server/standard_address_space/standard_address_space.py
View file @
c1162fb4
...
...
@@ -20,7 +20,7 @@ class PostponeReferences(object):
#self.add_nodes = self.server.add_nodes
def
add_nodes
(
self
,
nodes
):
self
.
postponed_nodes
.
extend
(
self
.
server
.
try_add_nodes
(
nodes
))
self
.
postponed_nodes
.
extend
(
self
.
server
.
try_add_nodes
(
nodes
,
check
=
False
))
def
add_references
(
self
,
refs
):
self
.
postponed_refs
.
extend
(
self
.
server
.
try_add_references
(
refs
))
...
...
@@ -33,7 +33,7 @@ class PostponeReferences(object):
def
__exit__
(
self
,
exc_type
,
exc_val
,
exc_tb
):
if
exc_type
is
None
and
exc_val
is
None
:
remaining_nodes
=
list
(
self
.
server
.
try_add_nodes
(
self
.
postponed_nodes
))
remaining_nodes
=
list
(
self
.
server
.
try_add_nodes
(
self
.
postponed_nodes
,
check
=
False
))
assert
len
(
remaining_nodes
)
==
0
,
remaining_nodes
remaining_refs
=
list
(
self
.
server
.
try_add_references
(
self
.
postponed_refs
))
assert
len
(
remaining_refs
)
==
0
,
remaining_refs
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment