Commit 4d2a6fb8 authored by Alexander Schrode's avatar Alexander Schrode Committed by oroulet

add namespace meta data

parent 7456fac3
......@@ -93,6 +93,26 @@ class XmlImporter:
raise ValueError("Server doesn't satisfy required XML-Models. Import them first!")
return None
async def _check_if_namespace_meta_information_is_added(self):
"""
check if the NamespaceMetadata objects in server namespaces exists otherwise add them
to prevent errors when other nodesets depend on this namespace.
"""
descs = await self.server.nodes.namespaces.get_children_descriptions()
ns_objs = [n.BrowseName.Name for n in descs]
for uri, version, pub_date in self.parser.get_nodeset_namespaces():
if uri not in ns_objs:
idx = await self.server.register_namespace(uri)
obj = await self.nodes.namespaces.add_object(idx, uri, ua.ObjectIds.NamespaceMetadataType, False)
ns_uri = await obj.get_child('NamespaceUri')
await ns_uri.write_value(uri, ua.VariantType.String)
ns_ver = await obj.get_child('NamespaceVersion')
await ns_ver.write_value(version, ua.VariantType.String)
ns_date = await obj.get_child('NamespacePublicationDate')
await ns_date.write_value(pub_date)
ns_subset = await obj.get_child('IsNamespaceSubset')
await ns_subset.write_value(True)
async def import_xml(self, xmlpath=None, xmlstring=None):
"""
import xml and return added nodes
......@@ -131,6 +151,7 @@ class XmlImporter:
"The following references could not be imported and are probably broken: %s",
self.refs,
)
await self._check_if_namespace_meta_information_is_added()
return nodes
async def _add_missing_reverse_references(self, new_nodes):
......
......@@ -5,6 +5,7 @@ import re
import asyncio
import base64
import logging
from typing import List, Tuple
import xml.etree.ElementTree as ET
from pytz import utc
......@@ -439,3 +440,20 @@ class XMLParser:
# check if ModelUri X, in Version Y from time Z was already imported
required_models.append(child.attrib)
return required_models
def get_nodeset_namespaces(self) -> List[Tuple[str, ua.String, ua.DateTime]]:
"""
Get all namespaces that are registered with version and date_time
"""
ns = []
for model in self.root.findall('base:Models/base:Model', self.ns):
uri = model.attrib.get('ModelUri')
if uri is not None:
version = model.attrib.get('Version', ua.String())
date_time = model.attrib.get('PublicationDate')
if date_time is None:
date_time = ua.DateTime(1, 1, 1)
else:
date_time = ua.DateTime.strptime(date_time, "%Y-%m-%dT%H:%M:%SZ")
ns.append((uri, version, date_time))
return ns
......@@ -582,3 +582,17 @@ async def test_disable_xml_export_without_value(opc, tmpdir):
assert dv.Value != v.Value
assert v.Value.Value is None
await opc.opc.delete_nodes([o2])
async def test_if_missing_meta_data_is_added(opc):
# check if missing namespace infos are added
urn = "http://yourorganisation.org/testenum104/"
idx = await opc.opc.register_namespace(urn)
await opc.opc.import_xml(CUSTOM_REQ_XML_PASS_PATH)
o = await opc.opc.nodes.namespaces.get_child([f"{idx}:{urn}"])
assert await (await o.get_child("NamespaceUri")).read_value() == urn
assert await (await o.get_child("NamespaceVersion")).read_value() == "1.0.0"
dt = await (await o.get_child("NamespacePublicationDate")).read_value()
assert dt.year == 2020
assert dt.month == 8
assert dt.day == 11
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment