Browse Source

Server: Move the nodestore from the config to the server

Custom implementations of the nodestore require the library to be
rebuild.
Julius Pfrommer 5 years ago
parent
commit
522804cafc

+ 3 - 2
CMakeLists.txt

@@ -61,7 +61,6 @@ if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build" FORCE)
 endif()
 
-
 option(UA_ENABLE_AMALGAMATION "Concatenate the library to a single file open62541.h/.c" OFF)
 set(UA_AMALGAMATION_ARCHITECTURES "" CACHE STRING "List of architectures to include in amalgamation")
 mark_as_advanced(UA_AMALGAMATION_ARCHITECTURES)
@@ -195,6 +194,9 @@ if(UA_ENABLE_MULTITHREADING)
     set(UA_ENABLE_IMMUTABLE_NODES ON)
 endif()
 
+option(UA_ENABLE_CUSTOM_NODESTORE "Do not compile the default Nodestore implementation into the library" OFF)
+mark_as_advanced(UA_ENABLE_CUSTOM_NODESTORE)
+
 option(UA_ENABLE_PUBSUB "Enable publish/subscribe" OFF)
 mark_as_advanced(UA_ENABLE_PUBSUB)
 
@@ -651,7 +653,6 @@ set(lib_sources ${PROJECT_SOURCE_DIR}/src/ua_types.c
 set(default_plugin_headers ${PROJECT_SOURCE_DIR}/plugins/include/open62541/plugin/accesscontrol_default.h
                            ${PROJECT_SOURCE_DIR}/plugins/include/open62541/plugin/pki_default.h
                            ${PROJECT_SOURCE_DIR}/plugins/include/open62541/plugin/log_stdout.h
-                           ${PROJECT_SOURCE_DIR}/plugins/include/open62541/plugin/nodestore_default.h
                            ${PROJECT_SOURCE_DIR}/plugins/include/open62541/server_config_default.h
                            ${PROJECT_SOURCE_DIR}/plugins/include/open62541/client_config_default.h
                            ${PROJECT_SOURCE_DIR}/plugins/include/open62541/plugin/securitypolicy_default.h

+ 1 - 0
include/open62541/config.h.in

@@ -46,6 +46,7 @@
 #endif
 
 /* Advanced Options */
+#cmakedefine UA_ENABLE_CUSTOM_NODESTORE
 #cmakedefine UA_ENABLE_STATUSCODE_DESCRIPTIONS
 #cmakedefine UA_ENABLE_TYPENAMES
 #cmakedefine UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS

+ 59 - 51
include/open62541/plugin/nodestore.h

@@ -428,7 +428,8 @@ typedef struct {
 
 /**
  * Nodestore Plugin API
- * --------------------
+ * ====================
+ *
  * The following definitions are used for implementing custom node storage
  * backends. **Most users will want to use the default nodestore and don't need
  * to work with the nodestore API**.
@@ -437,66 +438,73 @@ typedef struct {
  * nodes. Please use the OPC UA services for that. Otherwise, all consistency
  * checks are omitted. This can crash the application eventually. */
 
-typedef void (*UA_NodestoreVisitor)(void *visitorContext, const UA_Node *node);
-
-typedef struct {
-    /* Nodestore context and lifecycle */
-    void *context;
-    void (*deleteNodestore)(void *nodestoreContext);
-
-    /* For non-multithreaded access, some nodestores allow that nodes are edited
-     * without a copy/replace. This is not possible when the node is only an
-     * intermediate representation and stored e.g. in a database backend. */
-    UA_Boolean inPlaceEditAllowed;
-
-    /* The following definitions are used to create empty nodes of the different
-     * node types. The memory is managed by the nodestore. Therefore, the node
-     * has to be removed via a special deleteNode function. (If the new node is
-     * not added to the nodestore.) */
-    UA_Node * (*newNode)(void *nodestoreContext, UA_NodeClass nodeClass);
-
-    void (*deleteNode)(void *nodestoreContext, UA_Node *node);
+/* For non-multithreaded access, some nodestores allow that nodes are edited
+ * without a copy/replace. This is not possible when the node is only an
+ * intermediate representation and stored e.g. in a database backend. */
+extern const UA_Boolean inPlaceEditAllowed;
 
-    /* ``Get`` returns a pointer to an immutable node. ``Release`` indicates
-     * that the pointer is no longer accessed afterwards. */
+/* Nodestore context and lifecycle */
+UA_StatusCode UA_Nodestore_new(void **nsCtx);
+void UA_Nodestore_delete(void *nsCtx);
 
-    const UA_Node * (*getNode)(void *nodestoreContext, const UA_NodeId *nodeId);
-
-    void (*releaseNode)(void *nodestoreContext, const UA_Node *node);
-
-    /* Returns an editable copy of a node (needs to be deleted with the
-     * deleteNode function or inserted / replaced into the nodestore). */
-    UA_StatusCode (*getNodeCopy)(void *nodestoreContext, const UA_NodeId *nodeId,
-                                 UA_Node **outNode);
-
-    /* Inserts a new node into the nodestore. If the NodeId is zero, then a
-     * fresh numeric NodeId is assigned. If insertion fails, the node is
-     * deleted. */
-    UA_StatusCode (*insertNode)(void *nodestoreContext, UA_Node *node,
-                                UA_NodeId *addedNodeId);
-
-    /* To replace a node, get an editable copy of the node, edit and replace
-     * with this function. If the node was already replaced since the copy was
-     * made, UA_STATUSCODE_BADINTERNALERROR is returned. If the NodeId is not
-     * found, UA_STATUSCODE_BADNODEIDUNKNOWN is returned. In both error cases,
-     * the editable node is deleted. */
-    UA_StatusCode (*replaceNode)(void *nodestoreContext, UA_Node *node);
+/**
+ * The following definitions are used to create empty nodes of the different
+ * node types. The memory is managed by the nodestore. Therefore, the node has
+ * to be removed via a special deleteNode function. (If the new node is not
+ * added to the nodestore.) */
 
-    /* Removes a node from the nodestore. */
-    UA_StatusCode (*removeNode)(void *nodestoreContext, const UA_NodeId *nodeId);
+UA_Node *
+UA_Nodestore_newNode(void *nsCtx, UA_NodeClass nodeClass);
 
-    /* Execute a callback for every node in the nodestore. */
-    void (*iterate)(void *nodestoreContext, void* visitorContext,
-                    UA_NodestoreVisitor visitor);
-} UA_Nodestore;
+void
+UA_Nodestore_deleteNode(void *nsCtx, UA_Node *node);
 
+/**
+ *``Get`` returns a pointer to an immutable node. ``Release`` indicates that the
+ * pointer is no longer accessed afterwards. */
+
+const UA_Node *
+UA_Nodestore_getNode(void *nsCtx, const UA_NodeId *nodeId);
+
+void
+UA_Nodestore_releaseNode(void *nsCtx, const UA_Node *node);
+
+/* Returns an editable copy of a node (needs to be deleted with the
+ * deleteNode function or inserted / replaced into the nodestore). */
+UA_StatusCode
+UA_Nodestore_getNodeCopy(void *nsCtx, const UA_NodeId *nodeId,
+                         UA_Node **outNode);
+
+/* Inserts a new node into the nodestore. If the NodeId is zero, then a fresh
+ * numeric NodeId is assigned. If insertion fails, the node is deleted. */
+UA_StatusCode
+UA_Nodestore_insertNode(void *nsCtx, UA_Node *node, UA_NodeId *addedNodeId);
+
+/* To replace a node, get an editable copy of the node, edit and replace with
+ * this function. If the node was already replaced since the copy was made,
+ * UA_STATUSCODE_BADINTERNALERROR is returned. If the NodeId is not found,
+ * UA_STATUSCODE_BADNODEIDUNKNOWN is returned. In both error cases, the editable
+ * node is deleted. */
+UA_StatusCode
+UA_Nodestore_replaceNode(void *nsCtx, UA_Node *node);
+
+/* Removes a node from the nodestore. */
+UA_StatusCode
+UA_Nodestore_removeNode(void *nsCtx, const UA_NodeId *nodeId);
+
+/* Execute a callback for every node in the nodestore. */
+typedef void (*UA_NodestoreVisitor)(void *visitorCtx, const UA_Node *node);
+void
+UA_Nodestore_iterate(void *nsCtx, UA_NodestoreVisitor visitor,
+                     void *visitorCtx);
 
 /**
  * Node Handling
  * =============
  *
- * The following methods specialize internally for the different node classes,
- * distinguished by the NodeClass attribute. */
+ * To be used only in the nodestore and internally in the SDK. The following
+ * methods specialize internally for the different node classes, distinguished
+ * by the NodeClass attribute. */
 
 /* Attributes must be of a matching type (VariableAttributes, ObjectAttributes,
  * and so on). The attributes are copied. Note that the attributes structs do

+ 0 - 4
include/open62541/server_config.h

@@ -14,7 +14,6 @@
 #include <open62541/plugin/accesscontrol.h>
 #include <open62541/plugin/log.h>
 #include <open62541/plugin/network.h>
-#include <open62541/plugin/nodestore.h>
 #include <open62541/plugin/pki.h>
 #include <open62541/plugin/securitypolicy.h>
 #include <open62541/server.h>
@@ -86,9 +85,6 @@ struct UA_ServerConfig {
      *    with custom data types are provided in
      *    ``/examples/custom_datatype/``. */
 
-    /* Nodestore */
-    UA_Nodestore nodestore;
-
     /* Networking */
     size_t networkLayersSize;
     UA_ServerNetworkLayer *networkLayers;

+ 0 - 22
plugins/include/open62541/plugin/nodestore_default.h

@@ -1,22 +0,0 @@
-/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
- * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
- *
- *    Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
- *    Copyright 2017 (c) Julian Grothoff
- *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
- */
-
-#ifndef UA_NODESTORE_DEFAULT_H_
-#define UA_NODESTORE_DEFAULT_H_
-
-#include <open62541/plugin/nodestore.h>
-
-_UA_BEGIN_DECLS
-
-/* Initializes the nodestore, sets the context and function pointers */
-UA_StatusCode UA_EXPORT
-UA_Nodestore_default_new(UA_Nodestore *ns);
-
-_UA_END_DECLS
-
-#endif /* UA_NODESTORE_DEFAULT_H_ */

+ 0 - 7
plugins/ua_config_default.c

@@ -14,7 +14,6 @@
 #include <open62541/network_tcp.h>
 #include <open62541/plugin/accesscontrol_default.h>
 #include <open62541/plugin/log_stdout.h>
-#include <open62541/plugin/nodestore_default.h>
 #include <open62541/plugin/pki_default.h>
 #include <open62541/plugin/securitypolicy_default.h>
 #include <open62541/server_config_default.h>
@@ -442,12 +441,6 @@ UA_ServerConfig_new_basic256sha256(UA_UInt16 portNumber,
         return NULL;
     }
 
-    retval = UA_Nodestore_default_new(&conf->nodestore);
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_ServerConfig_delete(conf);
-        return NULL;
-    }
-
     retval = addDefaultNetworkLayers(conf, portNumber, 0, 0);
     if(retval != UA_STATUSCODE_GOOD) {
         UA_ServerConfig_delete(conf);

+ 73 - 76
plugins/ua_nodestore_default.c

@@ -6,10 +6,11 @@
  *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
  */
 
-#include <open62541/plugin/nodestore_default.h>
-
+#include <open62541/plugin/nodestore.h>
 #include "ziptree.h"
 
+#ifndef UA_ENABLE_CUSTOM_NODESTORE
+
 #ifdef UA_ENABLE_MULTITHREADING
 #include <pthread.h>
 #define BEGIN_CRITSECT(NODEMAP) pthread_mutex_lock(&(NODEMAP)->mutex)
@@ -176,8 +177,8 @@ cleanupEntry(NodeEntry *entry) {
 /***********************/
 
 /* Not yet inserted into the NodeMap */
-static UA_Node *
-NodeMap_newNode(void *context, UA_NodeClass nodeClass) {
+UA_Node *
+UA_Nodestore_newNode(void *nsCtx, UA_NodeClass nodeClass) {
     NodeEntry *entry = newEntry(nodeClass);
     if(!entry)
         return NULL;
@@ -185,18 +186,18 @@ NodeMap_newNode(void *context, UA_NodeClass nodeClass) {
 }
 
 /* Not yet inserted into the NodeMap */
-static void
-NodeMap_deleteNode(void *context, UA_Node *node) {
+void
+UA_Nodestore_deleteNode(void *nsCtx, UA_Node *node) {
     deleteEntry(container_of(node, NodeEntry, nodeId));
 }
 
-static const UA_Node *
-NodeMap_getNode(void *context, const UA_NodeId *nodeid) {
-    NodeMap *ns = (NodeMap*)context;
+const UA_Node *
+UA_Nodestore_getNode(void *nsCtx, const UA_NodeId *nodeId) {
+    NodeMap *ns = (NodeMap*)nsCtx;
     BEGIN_CRITSECT(ns);
     NodeEntry dummy;
-    dummy.nodeIdHash = UA_NodeId_hash(nodeid);
-    dummy.nodeId = *nodeid;
+    dummy.nodeIdHash = UA_NodeId_hash(nodeId);
+    dummy.nodeId = *nodeId;
     NodeEntry *entry = ZIP_FIND(NodeTree, &ns->root, &dummy);
     if(!entry) {
         END_CRITSECT(ns);
@@ -207,12 +208,12 @@ NodeMap_getNode(void *context, const UA_NodeId *nodeid) {
     return (const UA_Node*)&entry->nodeId;
 }
 
-static void
-NodeMap_releaseNode(void *context, const UA_Node *node) {
+void
+UA_Nodestore_releaseNode(void *nsCtx, const UA_Node *node) {
     if(!node)
         return;
 #ifdef UA_ENABLE_MULTITHREADING
-    NodeMap *ns = (NodeMap*)context;
+    NodeMap *ns = (NodeMap*)nsCtx;
 #endif
     BEGIN_CRITSECT(ns);
     NodeEntry *entry = container_of(node, NodeEntry, nodeId);
@@ -222,25 +223,25 @@ NodeMap_releaseNode(void *context, const UA_Node *node) {
     END_CRITSECT(ns);
 }
 
-static UA_StatusCode
-NodeMap_getNodeCopy(void *context, const UA_NodeId *nodeid,
-                    UA_Node **outNode) {
+UA_StatusCode
+UA_Nodestore_getNodeCopy(void *nsCtx, const UA_NodeId *nodeId,
+                         UA_Node **outNode) {
     /* Find the node */
-    const UA_Node *node = NodeMap_getNode(context, nodeid);
+    const UA_Node *node = UA_Nodestore_getNode(nsCtx, nodeId);
     if(!node)
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
 
     /* Create the new entry */
     NodeEntry *ne = newEntry(node->nodeClass);
     if(!ne) {
-        NodeMap_releaseNode(context, node);
+        UA_Nodestore_releaseNode(nsCtx, node);
         return UA_STATUSCODE_BADOUTOFMEMORY;
     }
 
     /* Copy the node content */
     UA_Node *nnode = (UA_Node*)&ne->nodeId;
     UA_StatusCode retval = UA_Node_copy(node, nnode);
-    NodeMap_releaseNode(context, node);
+    UA_Nodestore_releaseNode(nsCtx, node);
     if(retval != UA_STATUSCODE_GOOD) {
         deleteEntry(ne);
         return retval;
@@ -251,30 +252,10 @@ NodeMap_getNodeCopy(void *context, const UA_NodeId *nodeid,
     return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode
-NodeMap_removeNode(void *context, const UA_NodeId *nodeid) {
-    NodeMap *ns = (NodeMap*)context;
-    BEGIN_CRITSECT(ns);
-    NodeEntry dummy;
-    dummy.nodeIdHash = UA_NodeId_hash(nodeid);
-    dummy.nodeId = *nodeid;
-    NodeEntry *entry = ZIP_FIND(NodeTree, &ns->root, &dummy);
-    if(!entry) {
-        END_CRITSECT(ns);
-        return UA_STATUSCODE_BADNODEIDUNKNOWN;
-    }
-    ZIP_REMOVE(NodeTree, &ns->root, entry);
-    entry->deleted = true;
-    cleanupEntry(entry);
-    END_CRITSECT(ns);
-    return UA_STATUSCODE_GOOD;
-}
-
-static UA_StatusCode
-NodeMap_insertNode(void *context, UA_Node *node,
-                   UA_NodeId *addedNodeId) {
+UA_StatusCode
+UA_Nodestore_insertNode(void *nsCtx, UA_Node *node, UA_NodeId *addedNodeId) {
     NodeEntry *entry = container_of(node, NodeEntry, nodeId);
-    NodeMap *ns = (NodeMap*)context;
+    NodeMap *ns = (NodeMap*)nsCtx;
     BEGIN_CRITSECT(ns);
 
     /* Ensure that the NodeId is unique */
@@ -313,10 +294,10 @@ NodeMap_insertNode(void *context, UA_Node *node,
     return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode
-NodeMap_replaceNode(void *context, UA_Node *node) {
+UA_StatusCode
+UA_Nodestore_replaceNode(void *nsCtx, UA_Node *node) {
     /* Find the node */
-    const UA_Node *oldNode = NodeMap_getNode(context, &node->nodeId);
+    const UA_Node *oldNode = UA_Nodestore_getNode(nsCtx, &node->nodeId);
     if(!oldNode)
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
 
@@ -326,12 +307,12 @@ NodeMap_replaceNode(void *context, UA_Node *node) {
     if(oldEntry != entry->orig) {
         /* The node was already updated since the copy was made */
         deleteEntry(entry);
-        NodeMap_releaseNode(context, oldNode);
+        UA_Nodestore_releaseNode(nsCtx, oldNode);
         return UA_STATUSCODE_BADINTERNALERROR;
     }
 
     /* Replace */
-    NodeMap *ns = (NodeMap*)context;
+    NodeMap *ns = (NodeMap*)nsCtx;
     BEGIN_CRITSECT(ns);
     ZIP_REMOVE(NodeTree, &ns->root, oldEntry);
     entry->nodeIdHash = oldEntry->nodeIdHash;
@@ -339,7 +320,26 @@ NodeMap_replaceNode(void *context, UA_Node *node) {
     oldEntry->deleted = true;
     END_CRITSECT(ns);
 
-    NodeMap_releaseNode(context, oldNode);
+    UA_Nodestore_releaseNode(nsCtx, oldNode);
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_StatusCode
+UA_Nodestore_removeNode(void *nsCtx, const UA_NodeId *nodeId) {
+    NodeMap *ns = (NodeMap*)nsCtx;
+    BEGIN_CRITSECT(ns);
+    NodeEntry dummy;
+    dummy.nodeIdHash = UA_NodeId_hash(nodeId);
+    dummy.nodeId = *nodeId;
+    NodeEntry *entry = ZIP_FIND(NodeTree, &ns->root, &dummy);
+    if(!entry) {
+        END_CRITSECT(ns);
+        return UA_STATUSCODE_BADNODEIDUNKNOWN;
+    }
+    ZIP_REMOVE(NodeTree, &ns->root, entry);
+    entry->deleted = true;
+    cleanupEntry(entry);
+    END_CRITSECT(ns);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -354,13 +354,13 @@ nodeVisitor(NodeEntry *entry, void *data) {
     d->visitor(d->visitorContext, (UA_Node*)&entry->nodeId);
 }
 
-static void
-NodeMap_iterate(void *context, void *visitorContext,
-                UA_NodestoreVisitor visitor) {
+void
+UA_Nodestore_iterate(void *nsCtx, UA_NodestoreVisitor visitor,
+                     void *visitorCtx) {
     struct VisitorData d;
     d.visitor = visitor;
-    d.visitorContext = visitorContext;
-    NodeMap *ns = (NodeMap*)context;
+    d.visitorContext = visitorCtx;
+    NodeMap *ns = (NodeMap*)nsCtx;
     BEGIN_CRITSECT(ns);
     ZIP_ITER(NodeTree, &ns->root, nodeVisitor, &d);
     END_CRITSECT(ns);
@@ -371,18 +371,14 @@ deleteNodeVisitor(NodeEntry *entry, void *data) {
     deleteEntry(entry);
 }
 
-static void
-NodeMap_delete(void *context) {
-    NodeMap *ns = (NodeMap*)context;
-#ifdef UA_ENABLE_MULTITHREADING
-    pthread_mutex_destroy(&ns->mutex);
-#endif
-    ZIP_ITER(NodeTree, &ns->root, deleteNodeVisitor, NULL);
-    UA_free(ns);
-}
+/***********************/
+/* Nodestore Lifecycle */
+/***********************/
+
+const UA_Boolean inPlaceEditAllowed = true;
 
 UA_StatusCode
-UA_Nodestore_default_new(UA_Nodestore *ns) {
+UA_Nodestore_new(void **nsCtx) {
     /* Allocate and initialize the nodemap */
     NodeMap *nodemap = (NodeMap*)UA_malloc(sizeof(NodeMap));
     if(!nodemap)
@@ -394,17 +390,18 @@ UA_Nodestore_default_new(UA_Nodestore *ns) {
     ZIP_INIT(&nodemap->root);
 
     /* Populate the nodestore */
-    ns->context = nodemap;
-    ns->deleteNodestore = NodeMap_delete;
-    ns->inPlaceEditAllowed = true;
-    ns->newNode = NodeMap_newNode;
-    ns->deleteNode = NodeMap_deleteNode;
-    ns->getNode = NodeMap_getNode;
-    ns->releaseNode = NodeMap_releaseNode;
-    ns->getNodeCopy = NodeMap_getNodeCopy;
-    ns->insertNode = NodeMap_insertNode;
-    ns->replaceNode = NodeMap_replaceNode;
-    ns->removeNode = NodeMap_removeNode;
-    ns->iterate = NodeMap_iterate;
+    *nsCtx = (void*)nodemap;
     return UA_STATUSCODE_GOOD;
 }
+
+void
+UA_Nodestore_delete(void *nsCtx) {
+    NodeMap *ns = (NodeMap*)nsCtx;
+#ifdef UA_ENABLE_MULTITHREADING
+    pthread_mutex_destroy(&ns->mutex);
+#endif
+    ZIP_ITER(NodeTree, &ns->root, deleteNodeVisitor, NULL);
+    UA_free(ns);
+}
+
+#endif /* UA_ENABLE_CUSTOM_NODESTORE */

+ 2 - 2
src/pubsub/ua_pubsub_manager.c

@@ -282,8 +282,8 @@ UA_PubSubConfigurationVersionTimeDifference() {
 void
 UA_PubSubManager_generateUniqueNodeId(UA_Server *server, UA_NodeId *nodeId) {
     UA_NodeId newNodeId = UA_NODEID_NUMERIC(0, 0);
-    UA_Node *newNode = UA_Nodestore_new(server, UA_NODECLASS_OBJECT);
-    UA_Nodestore_insert(server, newNode, &newNodeId);
+    UA_Node *newNode = UA_Nodestore_newNode(server->nsCtx, UA_NODECLASS_OBJECT);
+    UA_Nodestore_insertNode(server->nsCtx, newNode, &newNodeId);
     UA_NodeId_copy(&newNodeId, nodeId);
 }
 

+ 2 - 2
src/pubsub/ua_pubsub_ns0.c

@@ -219,7 +219,7 @@ addPubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connec
     memcpy(connectionName, connection->config->name.data, connection->config->name.length);
     connectionName[connection->config->name.length] = '\0';
     //This code block must use a lock
-    UA_Nodestore_remove(server, &connection->identifier);
+    UA_Nodestore_removeNode(server->nsCtx, &connection->identifier);
     UA_NodeId pubSubConnectionNodeId;
     UA_ObjectAttributes attr = UA_ObjectAttributes_default;
     attr.displayName = UA_LOCALIZEDTEXT("de-DE", connectionName);
@@ -799,7 +799,7 @@ addDataSetWriterRepresentation(UA_Server *server, UA_DataSetWriter *dataSetWrite
     memcpy(dswName, dataSetWriter->config.name.data, dataSetWriter->config.name.length);
     dswName[dataSetWriter->config.name.length] = '\0';
     //This code block must use a lock
-    UA_Nodestore_remove(server, &dataSetWriter->identifier);
+    UA_Nodestore_removeNode(server->nsCtx, &dataSetWriter->identifier);
     retVal |= addPubSubObjectNode(server, dswName, dataSetWriter->identifier.identifier.numeric,
                                   dataSetWriter->linkedWriterGroup.identifier.numeric,
                                   UA_NS0ID_HASDATASETWRITER, UA_NS0ID_DATASETWRITERTYPE);

+ 18 - 15
src/server/ua_server.c

@@ -93,9 +93,7 @@ UA_Server_getNamespaceByName(UA_Server *server, const UA_String namespaceUri,
 UA_StatusCode
 UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
                                UA_NodeIteratorCallback callback, void *handle) {
-    const UA_Node *parent =
-        server->config.nodestore.getNode(server->config.nodestore.context,
-                                         &parentNodeId);
+    const UA_Node *parent = UA_Nodestore_getNode(server->nsCtx, &parentNodeId);
     if(!parent)
         return UA_STATUSCODE_BADNODEIDINVALID;
 
@@ -108,7 +106,7 @@ UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
      * */
     UA_Node *parentCopy = UA_Node_copy_alloc(parent);
     if(!parentCopy) {
-        server->config.nodestore.releaseNode(server->config.nodestore.context, parent);
+        UA_Nodestore_releaseNode(server->nsCtx, parent);
         return UA_STATUSCODE_BADUNEXPECTEDERROR;
     }
 
@@ -127,7 +125,7 @@ cleanup:
     UA_Node_deleteMembers(parentCopy);
     UA_free(parentCopy);
 
-    server->config.nodestore.releaseNode(server->config.nodestore.context, parent);
+    UA_Nodestore_releaseNode(server->nsCtx, parent);
     return retval;
 }
 
@@ -167,6 +165,9 @@ void UA_Server_delete(UA_Server *server) {
     /* Delete the timed work */
     UA_Timer_deleteMembers(&server->timer);
 
+    /* Clean up the nodestore */
+    UA_Nodestore_delete(server->nsCtx);
+
     /* Delete the server itself */
     UA_free(server);
 }
@@ -240,15 +241,13 @@ UA_Server_new(const UA_ServerConfig *config) {
 #endif
 
     /* Initialize namespace 0*/
-    UA_StatusCode retVal = UA_Server_initNS0(server);
-    if(retVal != UA_STATUSCODE_GOOD) {
-        UA_LOG_ERROR(&config->logger, UA_LOGCATEGORY_SERVER,
-                     "Namespace 0 could not be bootstrapped with error %s. "
-                     "Shutting down the server.",
-                     UA_StatusCode_name(retVal));
-        UA_Server_delete(server);
-        return NULL;
-    }
+    UA_StatusCode retVal = UA_Nodestore_new(&server->nsCtx);
+    if(retVal != UA_STATUSCODE_GOOD)
+        goto cleanup;
+
+    retVal = UA_Server_initNS0(server);
+    if(retVal != UA_STATUSCODE_GOOD)
+        goto cleanup;
 
     /* Build PubSub information model */
 #ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
@@ -256,6 +255,10 @@ UA_Server_new(const UA_ServerConfig *config) {
 #endif
 
     return server;
+
+ cleanup:
+    UA_Server_delete(server);
+    return NULL;
 }
 
 /*******************/
@@ -590,4 +593,4 @@ UA_Server_AccessControl_allowHistoryUpdateDeleteRawModified(UA_Server *server,
     return true;
 
 }
-#endif // UA_ENABLE_HISTORIZING
+#endif /* UA_ENABLE_HISTORIZING */

+ 9 - 26
src/server/ua_server_internal.h

@@ -16,6 +16,7 @@
 
 #include <open62541/server.h>
 #include <open62541/server_config.h>
+#include <open62541/plugin/nodestore.h>
 
 #include "ua_connection_internal.h"
 #include "ua_securechannel_manager.h"
@@ -53,6 +54,9 @@ struct UA_Server {
     UA_ServerConfig config;
     UA_DateTime startTime;
 
+    /* Nodestore */
+    void *nsCtx;
+
     /* Security */
     UA_SecureChannelManager secureChannelManager;
     UA_SessionManager sessionManager;
@@ -100,27 +104,6 @@ struct UA_Server {
 /* Node Handling */
 /*****************/
 
-#define UA_Nodestore_get(SERVER, NODEID)                                \
-    (SERVER)->config.nodestore.getNode((SERVER)->config.nodestore.context, NODEID)
-
-#define UA_Nodestore_release(SERVER, NODEID)                            \
-    (SERVER)->config.nodestore.releaseNode((SERVER)->config.nodestore.context, NODEID)
-
-#define UA_Nodestore_new(SERVER, NODECLASS)                               \
-    (SERVER)->config.nodestore.newNode((SERVER)->config.nodestore.context, NODECLASS)
-
-#define UA_Nodestore_getCopy(SERVER, NODEID, OUTNODE)                   \
-    (SERVER)->config.nodestore.getNodeCopy((SERVER)->config.nodestore.context, NODEID, OUTNODE)
-
-#define UA_Nodestore_insert(SERVER, NODE, OUTNODEID)                    \
-    (SERVER)->config.nodestore.insertNode((SERVER)->config.nodestore.context, NODE, OUTNODEID)
-
-#define UA_Nodestore_delete(SERVER, NODE)                               \
-    (SERVER)->config.nodestore.deleteNode((SERVER)->config.nodestore.context, NODE)
-
-#define UA_Nodestore_remove(SERVER, NODEID)                             \
-    (SERVER)->config.nodestore.removeNode((SERVER)->config.nodestore.context, NODEID)
-
 /* Deletes references from the node which are not matching any type in the given
  * array. Could be used to e.g. delete all the references, except
  * 'HASMODELINGRULE' */
@@ -152,7 +135,7 @@ UA_Node_hasSubTypeOrInstances(const UA_Node *node);
 
 /* Recursively searches "upwards" in the tree following specific reference types */
 UA_Boolean
-isNodeInTree(UA_Nodestore *ns, const UA_NodeId *leafNode,
+isNodeInTree(void *nsCtx, const UA_NodeId *leafNode,
              const UA_NodeId *nodeToFind, const UA_NodeId *referenceTypeIds,
              size_t referenceTypeIdsSize);
 
@@ -166,16 +149,16 @@ isNodeInTree(UA_Nodestore *ns, const UA_NodeId *leafNode,
  * If set to FALSE it will get all the parent types of the given
  * leafType (including leafType)*/
 UA_StatusCode
-getTypeHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType,
+getTypeHierarchy(void *nsCtx, const UA_NodeId *leafType,
                  UA_NodeId **typeHierarchy, size_t *typeHierarchySize,
                  UA_Boolean walkDownwards);
 
 /* Same as getTypeHierarchy but takes multiple leafTypes as parameter and returns
  * an combined list of all the found types for all the leaf types */
 UA_StatusCode
-getTypesHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType, size_t leafTypeSize,
-                 UA_NodeId **typeHierarchy, size_t *typeHierarchySize,
-                 UA_Boolean walkDownwards);
+getTypesHierarchy(void *nsCtx, const UA_NodeId *leafType, size_t leafTypeSize,
+                  UA_NodeId **typeHierarchy, size_t *typeHierarchySize,
+                  UA_Boolean walkDownwards);
 
 /* Returns the type node from the node on the stack top. The type node is pushed
  * on the stack and returned. */

+ 23 - 23
src/server/ua_server_utils.c

@@ -26,7 +26,7 @@ struct ref_history {
 };
 
 static UA_Boolean
-isNodeInTreeNoCircular(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind,
+isNodeInTreeNoCircular(void *nsCtx, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind,
                        struct ref_history *visitedRefs, const UA_NodeId *referenceTypeIds,
                        size_t referenceTypeIdsSize) {
     if(UA_NodeId_equal(nodeToFind, leafNode))
@@ -35,7 +35,7 @@ isNodeInTreeNoCircular(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_Nod
     if(visitedRefs->depth >= UA_MAX_TREE_RECURSE)
         return false;
 
-    const UA_Node *node = ns->getNode(ns->context, leafNode);
+    const UA_Node *node = UA_Nodestore_getNode(nsCtx, leafNode);
     if(!node)
         return false;
 
@@ -80,24 +80,25 @@ isNodeInTreeNoCircular(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_Nod
 
             /* Recurse */
             UA_Boolean foundRecursive =
-                isNodeInTreeNoCircular(ns, &refs->targetIds[j].nodeId, nodeToFind, &nextVisitedRefs,
+                isNodeInTreeNoCircular(nsCtx, &refs->targetIds[j].nodeId, nodeToFind, &nextVisitedRefs,
                                        referenceTypeIds, referenceTypeIdsSize);
             if(foundRecursive) {
-                ns->releaseNode(ns->context, node);
+                UA_Nodestore_releaseNode(nsCtx, node);
                 return true;
             }
         }
     }
 
-    ns->releaseNode(ns->context, node);
+    UA_Nodestore_releaseNode(nsCtx, node);
     return false;
 }
 
 UA_Boolean
-isNodeInTree(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind,
+isNodeInTree(void *nsCtx, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind,
              const UA_NodeId *referenceTypeIds, size_t referenceTypeIdsSize) {
     struct ref_history visitedRefs = {NULL, leafNode, 0};
-    return isNodeInTreeNoCircular(ns, leafNode, nodeToFind, &visitedRefs, referenceTypeIds, referenceTypeIdsSize);
+    return isNodeInTreeNoCircular(nsCtx, leafNode, nodeToFind, &visitedRefs,
+                                  referenceTypeIds, referenceTypeIdsSize);
 }
 
 const UA_Node *
@@ -137,12 +138,12 @@ getNodeType(UA_Server *server, const UA_Node *node) {
             continue;
         UA_assert(node->references[i].targetIdsSize > 0);
         const UA_NodeId *targetId = &node->references[i].targetIds[0].nodeId;
-        const UA_Node *type = UA_Nodestore_get(server, targetId);
+        const UA_Node *type = UA_Nodestore_getNode(server->nsCtx, targetId);
         if(!type)
             continue;
         if(type->nodeClass == typeNodeClass)
             return type;
-        UA_Nodestore_release(server, type);
+        UA_Nodestore_releaseNode(server->nsCtx, type);
     }
 
     return NULL;
@@ -220,7 +221,7 @@ getTypeHierarchyFromNode(UA_NodeId **results_ptr, size_t *results_count,
 }
 
 UA_StatusCode
-getTypeHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType,
+getTypeHierarchy(void *nsCtx, const UA_NodeId *leafType,
                  UA_NodeId **typeHierarchy, size_t *typeHierarchySize,
                  UA_Boolean walkDownwards) {
     /* Allocate the results array. Probably too big, but saves mallocs. */
@@ -240,7 +241,7 @@ getTypeHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType,
     /* Loop over the array members .. and add new elements to the end */
     for(size_t idx = 0; idx < results_count; ++idx) {
         /* Get the node */
-        const UA_Node *node = ns->getNode(ns->context, &results[idx]);
+        const UA_Node *node = UA_Nodestore_getNode(nsCtx, &results[idx]);
 
         /* Invalid node, remove from the array */
         if(!node) {
@@ -255,7 +256,7 @@ getTypeHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType,
                                           &results_size, node, walkDownwards);
 
         /* Release the node */
-        ns->releaseNode(ns->context, node);
+        UA_Nodestore_releaseNode(nsCtx, node);
 
         if(retval != UA_STATUSCODE_GOOD) {
             UA_Array_delete(results, results_count, &UA_TYPES[UA_TYPES_NODEID]);
@@ -276,15 +277,15 @@ getTypeHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType,
 
 
 UA_StatusCode
-getTypesHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType, size_t leafTypeSize,
-                 UA_NodeId **typeHierarchy, size_t *typeHierarchySize,
-                 UA_Boolean walkDownwards) {
+getTypesHierarchy(void *nsCtx, const UA_NodeId *leafType, size_t leafTypeSize,
+                  UA_NodeId **typeHierarchy, size_t *typeHierarchySize,
+                  UA_Boolean walkDownwards) {
     UA_NodeId *results = NULL;
     size_t results_count = 0;
-    for (size_t i=0; i<leafTypeSize; i++) {
+    for (size_t i = 0; i < leafTypeSize; i++) {
         UA_NodeId *tmpResults = NULL;
         size_t tmpResults_size = 0;
-        UA_StatusCode retval = getTypeHierarchy(ns, &leafType[i], &tmpResults, &tmpResults_size, walkDownwards);
+        UA_StatusCode retval = getTypeHierarchy(nsCtx, &leafType[i], &tmpResults, &tmpResults_size, walkDownwards);
         if(retval != UA_STATUSCODE_GOOD) {
             UA_Array_delete(results, results_count, &UA_TYPES[UA_TYPES_NODEID]);
             return retval;
@@ -316,31 +317,30 @@ UA_Server_editNode(UA_Server *server, UA_Session *session,
                    void *data) {
 #ifndef UA_ENABLE_IMMUTABLE_NODES
     /* Get the node and process it in-situ */
-    const UA_Node *node = UA_Nodestore_get(server, nodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId);
     if(!node)
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
     UA_StatusCode retval = callback(server, session, (UA_Node*)(uintptr_t)node, data);
-    UA_Nodestore_release(server, node);
+    UA_Nodestore_releaseNode(server->nsCtx, node);
     return retval;
 #else
     UA_StatusCode retval;
     do {
         /* Get an editable copy of the node */
         UA_Node *node;
-        retval = server->config.nodestore.
-            getNodeCopy(server->config.nodestore.context, nodeId, &node);
+        retval = UA_Nodestore_getNodeCopy(server->nsCtx, nodeId, &node);
         if(retval != UA_STATUSCODE_GOOD)
             return retval;
 
         /* Run the operation on the copy */
         retval = callback(server, session, node, data);
         if(retval != UA_STATUSCODE_GOOD) {
-            server->config.nodestore.deleteNode(server->config.nodestore.context, node);
+            UA_Nodestore_deleteNode(server->nsCtx, node);
             return retval;
         }
 
         /* Replace the node */
-        retval = server->config.nodestore.replaceNode(server->config.nodestore.context, node);
+        retval = UA_Nodestore_replaceNode(server->nsCtx, node);
     } while(retval != UA_STATUSCODE_GOOD);
     return retval;
 #endif

+ 12 - 12
src/server/ua_services_attribute.c

@@ -125,8 +125,8 @@ readValueAttributeFromNode(UA_Server *server, UA_Session *session,
                                        vn->context, rangeptr, &vn->value.data.value);
         const UA_Node *old = (const UA_Node *)vn;
         /* Reopen the node to see the changes from onRead */
-        vn = (const UA_VariableNode*)UA_Nodestore_get(server, &vn->nodeId);
-        UA_Nodestore_release(server, old);
+        vn = (const UA_VariableNode*)UA_Nodestore_getNode(server->nsCtx, &vn->nodeId);
+        UA_Nodestore_releaseNode(server->nsCtx, old);
     }
     if(rangeptr)
         return UA_Variant_copyRange(&vn->value.data.value.value, &v->value, *rangeptr);
@@ -387,7 +387,7 @@ Operation_Read(UA_Server *server, UA_Session *session, UA_MessageContext *mc,
     UA_DataValue_init(&dv);
 
     /* Get the node */
-    const UA_Node *node = UA_Nodestore_get(server, &id->nodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &id->nodeId);
 
     /* Perform the read operation */
     if(node) {
@@ -402,7 +402,7 @@ Operation_Read(UA_Server *server, UA_Session *session, UA_MessageContext *mc,
 
     /* Free copied data and release the node */
     UA_Variant_deleteMembers(&dv.value);
-    UA_Nodestore_release(server, node);
+    UA_Nodestore_releaseNode(server->nsCtx, node);
     return retval;
 }
 
@@ -463,7 +463,7 @@ UA_Server_readWithSession(UA_Server *server, UA_Session *session,
     UA_DataValue_init(&dv);
 
     /* Get the node */
-    const UA_Node *node = UA_Nodestore_get(server, &item->nodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &item->nodeId);
     if(!node) {
         dv.hasStatus = true;
         dv.status = UA_STATUSCODE_BADNODEIDUNKNOWN;
@@ -487,7 +487,7 @@ UA_Server_readWithSession(UA_Server *server, UA_Session *session,
     }
 
     /* Release the node and return */
-    UA_Nodestore_release(server, node);
+    UA_Nodestore_releaseNode(server->nsCtx, node);
     return dv;
 }
 
@@ -598,12 +598,12 @@ compatibleDataType(UA_Server *server, const UA_NodeId *dataType,
         return true;
 
     /* Is the value-type a subtype of the required type? */
-    if(isNodeInTree(&server->config.nodestore, dataType, constraintDataType, &subtypeId, 1))
+    if(isNodeInTree(server->nsCtx, dataType, constraintDataType, &subtypeId, 1))
         return true;
 
     /* Enum allows Int32 (only) */
     if(UA_NodeId_equal(dataType, &UA_TYPES[UA_TYPES_INT32].typeId) &&
-       isNodeInTree(&server->config.nodestore, constraintDataType, &enumNodeId, &subtypeId, 1))
+       isNodeInTree(server->nsCtx, constraintDataType, &enumNodeId, &subtypeId, 1))
         return true;
 
     /* More checks for the data type of real values (variants) */
@@ -615,7 +615,7 @@ compatibleDataType(UA_Server *server, const UA_NodeId *dataType,
         if(dataType->namespaceIndex == 0 &&
            dataType->identifierType == UA_NODEIDTYPE_NUMERIC &&
            dataType->identifier.numeric <= 25 &&
-           isNodeInTree(&server->config.nodestore, constraintDataType,
+           isNodeInTree(server->nsCtx, constraintDataType,
                         dataType, &subtypeId, 1))
             return true;
     }
@@ -1310,7 +1310,7 @@ copyAttributeIntoNode(UA_Server *server, UA_Session *session,
         GET_NODETYPE
         retval = writeDataTypeAttribute(server, session, (UA_VariableNode*)node,
                                         type, (const UA_NodeId*)value);
-        UA_Nodestore_release(server, (const UA_Node*)type);
+        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)type);
         break;
     case UA_ATTRIBUTEID_VALUERANK:
         CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
@@ -1319,7 +1319,7 @@ copyAttributeIntoNode(UA_Server *server, UA_Session *session,
         GET_NODETYPE
         retval = writeValueRankAttribute(server, session, (UA_VariableNode*)node,
                                          type, *(const UA_Int32*)value);
-        UA_Nodestore_release(server, (const UA_Node*)type);
+        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)type);
         break;
     case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
         CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
@@ -1329,7 +1329,7 @@ copyAttributeIntoNode(UA_Server *server, UA_Session *session,
         retval = writeArrayDimensionsAttribute(server, session, (UA_VariableNode*)node,
                                                type, wvalue->value.value.arrayLength,
                                                (UA_UInt32 *)wvalue->value.value.data);
-        UA_Nodestore_release(server, (const UA_Node*)type);
+        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)type);
         break;
     case UA_ATTRIBUTEID_ACCESSLEVEL:
         CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE);

+ 10 - 19
src/server/ua_services_call.c

@@ -32,8 +32,7 @@ getArgumentsVariableNode(UA_Server *server, const UA_MethodNode *ofMethod,
 
         for(size_t j = 0; j < rk->targetIdsSize; ++j) {
             const UA_Node *refTarget =
-                server->config.nodestore.getNode(server->config.nodestore.context,
-                                                 &rk->targetIds[j].nodeId);
+                UA_Nodestore_getNode(server->nsCtx, &rk->targetIds[j].nodeId);
             if(!refTarget)
                 continue;
             if(refTarget->nodeClass == UA_NODECLASS_VARIABLE &&
@@ -41,8 +40,7 @@ getArgumentsVariableNode(UA_Server *server, const UA_MethodNode *ofMethod,
                UA_String_equal(&withBrowseName, &refTarget->browseName.name)) {
                 return (const UA_VariableNode*)refTarget;
             }
-            server->config.nodestore.releaseNode(server->config.nodestore.context,
-                                                 refTarget);
+            UA_Nodestore_releaseNode(server->nsCtx, refTarget);
         }
     }
     return NULL;
@@ -107,8 +105,7 @@ validMethodArguments(UA_Server *server, UA_Session *session, const UA_MethodNode
                                               inputArgumentResults);
 
     /* Release the input arguments node */
-    server->config.nodestore.releaseNode(server->config.nodestore.context,
-                                         (const UA_Node*)inputArguments);
+    UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)inputArguments);
     return retval;
 }
 
@@ -147,7 +144,7 @@ callWithMethodAndObject(UA_Server *server, UA_Session *session,
         UA_NodeReferenceKind *rk = &object->references[i];
         if(rk->isInverse)
             continue;
-        if(!isNodeInTree(&server->config.nodestore, &rk->referenceTypeId,
+        if(!isNodeInTree(server->nsCtx, &rk->referenceTypeId,
                          &hasComponentNodeId, &hasSubTypeNodeId, 1))
             continue;
         for(size_t j = 0; j < rk->targetIdsSize; ++j) {
@@ -216,8 +213,7 @@ callWithMethodAndObject(UA_Server *server, UA_Session *session,
     result->outputArgumentsSize = outputArgsSize;
 
     /* Release the output arguments node */
-    server->config.nodestore.releaseNode(server->config.nodestore.context,
-                                         (const UA_Node*)outputArguments);
+    UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)outputArguments);
 
     /* Call the method */
     result->statusCode = method->method(server, &session->sessionId, session->sessionHandle,
@@ -233,8 +229,7 @@ Operation_CallMethod(UA_Server *server, UA_Session *session, void *context,
                      const UA_CallMethodRequest *request, UA_CallMethodResult *result) {
     /* Get the method node */
     const UA_MethodNode *method = (const UA_MethodNode*)
-        server->config.nodestore.getNode(server->config.nodestore.context,
-                                         &request->methodId);
+        UA_Nodestore_getNode(server->nsCtx, &request->methodId);
     if(!method) {
         result->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
         return;
@@ -242,12 +237,10 @@ Operation_CallMethod(UA_Server *server, UA_Session *session, void *context,
 
     /* Get the object node */
     const UA_ObjectNode *object = (const UA_ObjectNode*)
-        server->config.nodestore.getNode(server->config.nodestore.context,
-                                         &request->objectId);
+        UA_Nodestore_getNode(server->nsCtx, &request->objectId);
     if(!object) {
         result->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
-        server->config.nodestore.releaseNode(server->config.nodestore.context,
-                                             (const UA_Node*)method);
+        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)method);
         return;
     }
 
@@ -255,10 +248,8 @@ Operation_CallMethod(UA_Server *server, UA_Session *session, void *context,
     callWithMethodAndObject(server, session, request, result, method, object);
 
     /* Release the method and object node */
-    server->config.nodestore.releaseNode(server->config.nodestore.context,
-                                         (const UA_Node*)method);
-    server->config.nodestore.releaseNode(server->config.nodestore.context,
-                                         (const UA_Node*)object);
+    UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)method);
+    UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)object);
 }
 
 void Service_Call(UA_Server *server, UA_Session *session,

+ 50 - 49
src/server/ua_services_nodemanagement.c

@@ -33,11 +33,11 @@
 UA_StatusCode
 UA_Server_getNodeContext(UA_Server *server, UA_NodeId nodeId,
                          void **nodeContext) {
-    const UA_Node *node = UA_Nodestore_get(server, &nodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &nodeId);
     if(!node)
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
     *nodeContext = node->context;
-    UA_Nodestore_release(server, node);
+    UA_Nodestore_releaseNode(server->nsCtx, node);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -94,7 +94,7 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
         return UA_STATUSCODE_GOOD;
 
     /* See if the parent exists */
-    const UA_Node *parent = UA_Nodestore_get(server, parentNodeId);
+    const UA_Node *parent = UA_Nodestore_getNode(server->nsCtx, parentNodeId);
     if(!parent) {
         UA_LOG_NODEID_WRAP(parentNodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                             "AddNodes: Parent node %.*s not found",
@@ -103,11 +103,11 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
     }
 
     UA_NodeClass parentNodeClass = parent->nodeClass;
-    UA_Nodestore_release(server, parent);
+    UA_Nodestore_releaseNode(server->nsCtx, parent);
 
     /* Check the referencetype exists */
     const UA_ReferenceTypeNode *referenceType = (const UA_ReferenceTypeNode*)
-        UA_Nodestore_get(server, referenceTypeId);
+        UA_Nodestore_getNode(server->nsCtx, referenceTypeId);
     if(!referenceType) {
         UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: Reference type %.*s to the parent not found",
@@ -120,12 +120,12 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
         UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                            "AddNodes: Reference type %.*s to the parent is not a ReferenceTypeNode",
                            (int)nodeIdStr.length, nodeIdStr.data));
-        UA_Nodestore_release(server, (const UA_Node*)referenceType);
+        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)referenceType);
         return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
     }
 
     UA_Boolean referenceTypeIsAbstract = referenceType->isAbstract;
-    UA_Nodestore_release(server, (const UA_Node*)referenceType);
+    UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)referenceType);
     /* Check that the reference type is not abstract */
     if(referenceTypeIsAbstract == true) {
         UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
@@ -157,7 +157,7 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
     }
 
     /* Test if the referencetype is hierarchical */
-    if(!isNodeInTree(&server->config.nodestore, referenceTypeId,
+    if(!isNodeInTree(server->nsCtx, referenceTypeId,
                      &hierarchicalReferences, &subtypeId, 1)) {
         UA_LOG_INFO_SESSION(&server->config.logger, session,
                             "AddNodes: Reference type to the parent is not hierarchical");
@@ -321,12 +321,12 @@ useVariableTypeAttributes(UA_Server *server, UA_Session *session,
     /* If the node was modified, update the pointer to the new version */
     if(modified) {
         const UA_VariableNode *updated = (const UA_VariableNode*)
-            UA_Nodestore_get(server, &node->nodeId);
+            UA_Nodestore_getNode(server->nsCtx, &node->nodeId);
 
         if(!updated)
             return UA_STATUSCODE_BADINTERNALERROR;
 
-        UA_Nodestore_release(server, (const UA_Node*)node);
+        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)node);
         *node_ptr = updated;
     }
 
@@ -380,7 +380,7 @@ static UA_Boolean
 isMandatoryChild(UA_Server *server, UA_Session *session,
                  const UA_NodeId *childNodeId) {
     /* Get the child */
-    const UA_Node *child = UA_Nodestore_get(server, childNodeId);
+    const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, childNodeId);
     if(!child)
         return false;
 
@@ -393,13 +393,13 @@ isMandatoryChild(UA_Server *server, UA_Session *session,
             continue;
         for(size_t j = 0; j < refs->targetIdsSize; ++j) {
             if(UA_NodeId_equal(&mandatoryId, &refs->targetIds[j].nodeId)) {
-                UA_Nodestore_release(server, child);
+                UA_Nodestore_releaseNode(server->nsCtx, child);
                 return true;
             }
         }
     }
 
-    UA_Nodestore_release(server, child);
+    UA_Nodestore_releaseNode(server->nsCtx, child);
     return false;
 }
 
@@ -456,7 +456,7 @@ copyChild(UA_Server *server, UA_Session *session, const UA_NodeId *destinationNo
        rd->nodeClass == UA_NODECLASS_OBJECT) {
         /* Make a copy of the node */
         UA_Node *node;
-        retval = UA_Nodestore_getCopy(server, &rd->nodeId.nodeId, &node);
+        retval = UA_Nodestore_getNodeCopy(server->nsCtx, &rd->nodeId.nodeId, &node);
         if(retval != UA_STATUSCODE_GOOD)
             return retval;
 
@@ -478,7 +478,7 @@ copyChild(UA_Server *server, UA_Session *session, const UA_NodeId *destinationNo
 
         /* Add the node to the nodestore */
         UA_NodeId newNodeId;
-        retval = UA_Nodestore_insert(server, node, &newNodeId);
+        retval = UA_Nodestore_insertNode(server->nsCtx, node, &newNodeId);
         if(retval != UA_STATUSCODE_GOOD)
             return retval;
 
@@ -486,7 +486,7 @@ copyChild(UA_Server *server, UA_Session *session, const UA_NodeId *destinationNo
         retval = AddNode_addRefs(server, session, &newNodeId, destinationNodeId,
                                  &rd->referenceTypeId, &rd->typeDefinition.nodeId);
         if(retval != UA_STATUSCODE_GOOD) {
-            UA_Nodestore_remove(server, &newNodeId);
+            UA_Nodestore_removeNode(server->nsCtx, &newNodeId);
             return retval;
         }
 
@@ -539,7 +539,7 @@ addTypeChildren(UA_Server *server, UA_Session *session,
     /* Get the hierarchy of the type and all its supertypes */
     UA_NodeId *hierarchy = NULL;
     size_t hierarchySize = 0;
-    UA_StatusCode retval = getTypeHierarchy(&server->config.nodestore, &type->nodeId,
+    UA_StatusCode retval = getTypeHierarchy(server->nsCtx, &type->nodeId,
                                             &hierarchy, &hierarchySize, false);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
@@ -560,13 +560,14 @@ static UA_StatusCode
 addRef(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
        const UA_NodeId *referenceTypeId, const UA_NodeId *parentNodeId,
        UA_Boolean forward) {
-    UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_AddReferencesItem ref_item;
     UA_AddReferencesItem_init(&ref_item);
     ref_item.sourceNodeId = *nodeId;
     ref_item.referenceTypeId = *referenceTypeId;
     ref_item.isForward = forward;
     ref_item.targetNodeId.nodeId = *parentNodeId;
+
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
     Operation_addReference(server, session, NULL, &ref_item, &retval);
     return retval;
 }
@@ -583,7 +584,7 @@ AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
                 const UA_NodeId *typeDefinitionId) {
     /* Get the node */
     const UA_Node *type = NULL;
-    const UA_Node *node = UA_Nodestore_get(server, nodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId);
     if(!node)
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
 
@@ -594,11 +595,11 @@ AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
        node->nodeClass == UA_NODECLASS_DATATYPE) {
         if(UA_NodeId_equal(referenceTypeId, &UA_NODEID_NULL))
             referenceTypeId = &hasSubtype;
-        const UA_Node *parentNode = UA_Nodestore_get(server, parentNodeId);
+        const UA_Node *parentNode = UA_Nodestore_getNode(server->nsCtx, parentNodeId);
         if(parentNode) {
             if(parentNode->nodeClass == node->nodeClass)
                 typeDefinitionId = parentNodeId;
-            UA_Nodestore_release(server, parentNode);
+            UA_Nodestore_releaseNode(server->nsCtx, parentNode);
         }
     }
 
@@ -632,7 +633,7 @@ AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
      * and type-nodes. See the above checks. */
     if(!UA_NodeId_isNull(typeDefinitionId)) {
         /* Get the type node */
-        type = UA_Nodestore_get(server, typeDefinitionId);
+        type = UA_Nodestore_getNode(server->nsCtx, typeDefinitionId);
         if(!type) {
             UA_LOG_NODEID_WRAP(typeDefinitionId, UA_LOG_INFO_SESSION(&server->config.logger, session,
                                 "AddNodes: Node type %.*s not found",
@@ -685,15 +686,15 @@ AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
                 /* Get subtypes of the parent reference types */
                 UA_NodeId *parentTypeHierachy = NULL;
                 size_t parentTypeHierachySize = 0;
-                getTypesHierarchy(&server->config.nodestore, parentReferences,UA_PARENT_REFERENCES_COUNT,
+                getTypesHierarchy(server->nsCtx, parentReferences,UA_PARENT_REFERENCES_COUNT,
                                   &parentTypeHierachy, &parentTypeHierachySize, true);
                 /* Abstract variable is allowed if parent is a children of a base data variable */
                 const UA_NodeId variableTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
                 /* A variable may be of an object type which again is below BaseObjectType */
                 const UA_NodeId objectTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE);
-                if(!isNodeInTree(&server->config.nodestore, parentNodeId, &variableTypes,
+                if(!isNodeInTree(server->nsCtx, parentNodeId, &variableTypes,
                                  parentTypeHierachy, parentTypeHierachySize) &&
-                   !isNodeInTree(&server->config.nodestore, parentNodeId, &objectTypes,
+                   !isNodeInTree(server->nsCtx, parentNodeId, &objectTypes,
                                  parentTypeHierachy,parentTypeHierachySize)) {
                     UA_Array_delete(parentTypeHierachy, parentTypeHierachySize, &UA_TYPES[UA_TYPES_NODEID]);
                     UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session,
@@ -712,12 +713,12 @@ AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
                 /* Get subtypes of the parent reference types */
                 UA_NodeId *parentTypeHierachy = NULL;
                 size_t parentTypeHierachySize = 0;
-                getTypesHierarchy(&server->config.nodestore, parentReferences,UA_PARENT_REFERENCES_COUNT,
+                getTypesHierarchy(server->nsCtx, parentReferences,UA_PARENT_REFERENCES_COUNT,
                                   &parentTypeHierachy, &parentTypeHierachySize, true);
                 /* Object node created of an abstract ObjectType. Only allowed
                  * if within BaseObjectType folder */
                 const UA_NodeId objectTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE);
-                UA_Boolean isInBaseObjectType = isNodeInTree(&server->config.nodestore, parentNodeId, &objectTypes,
+                UA_Boolean isInBaseObjectType = isNodeInTree(server->nsCtx, parentNodeId, &objectTypes,
                                                              parentTypeHierachy, parentTypeHierachySize);
 
                 UA_Array_delete(parentTypeHierachy, parentTypeHierachySize, &UA_TYPES[UA_TYPES_NODEID]);
@@ -767,9 +768,9 @@ AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
     }
 
  cleanup:
-    UA_Nodestore_release(server, node);
+    UA_Nodestore_releaseNode(server->nsCtx, node);
     if(type)
-        UA_Nodestore_release(server, type);
+        UA_Nodestore_releaseNode(server->nsCtx, type);
     return retval;
 }
 
@@ -800,7 +801,7 @@ AddNode_raw(UA_Server *server, UA_Session *session, void *nodeContext,
     }
 
     /* Create a node */
-    UA_Node *node = UA_Nodestore_new(server, item->nodeClass);
+    UA_Node *node = UA_Nodestore_newNode(server->nsCtx, item->nodeClass);
     if(!node) {
         UA_LOG_INFO_SESSION(&server->config.logger, session,
                             "AddNodes: Node could not create a node "
@@ -824,7 +825,7 @@ AddNode_raw(UA_Server *server, UA_Session *session, void *nodeContext,
         goto create_error;
 
     /* Add the node to the nodestore */
-    retval = UA_Nodestore_insert(server, node, outNewNodeId);
+    retval = UA_Nodestore_insertNode(server->nsCtx, node, outNewNodeId);
     if(retval != UA_STATUSCODE_GOOD)
         UA_LOG_INFO_SESSION(&server->config.logger, session,
                             "AddNodes: Node could not add the new node "
@@ -836,7 +837,7 @@ create_error:
     UA_LOG_INFO_SESSION(&server->config.logger, session,
                         "AddNodes: Node could not create a node "
                         "with error code %s", UA_StatusCode_name(retval));
-    UA_Nodestore_delete(server, node);
+    UA_Nodestore_deleteNode(server->nsCtx, node);
     return retval;
 }
 
@@ -944,11 +945,11 @@ recursiveCallConstructors(UA_Server *server, UA_Session *session,
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     for(size_t i = 0; i < br.referencesSize; ++i) {
         UA_ReferenceDescription *rd = &br.references[i];
-        const UA_Node *target = UA_Nodestore_get(server, &rd->nodeId.nodeId);
+        const UA_Node *target = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId);
         if(!target)
             continue;
         if(target->constructed) {
-            UA_Nodestore_release(server, target);
+            UA_Nodestore_releaseNode(server->nsCtx, target);
             continue;
         }
 
@@ -957,15 +958,15 @@ recursiveCallConstructors(UA_Server *server, UA_Session *session,
            node->nodeClass == UA_NODECLASS_OBJECT) {
             targetType = getNodeType(server, target);
             if(!targetType) {
-                UA_Nodestore_release(server, target);
+                UA_Nodestore_releaseNode(server->nsCtx, target);
                 retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
                 break;
             }
         }
         retval = recursiveCallConstructors(server, session, target, targetType);
-        UA_Nodestore_release(server, target);
+        UA_Nodestore_releaseNode(server->nsCtx, target);
         if(targetType)
-            UA_Nodestore_release(server, targetType);
+            UA_Nodestore_releaseNode(server->nsCtx, targetType);
         if(retval != UA_STATUSCODE_GOOD)
             break;
     }
@@ -1039,7 +1040,7 @@ AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId)
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
 
     /* Get the node */
-    const UA_Node *node = UA_Nodestore_get(server, nodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId);
     if(!node)
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
 
@@ -1078,12 +1079,12 @@ AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId)
 
  cleanup:
     if(type)
-        UA_Nodestore_release(server, type);
+        UA_Nodestore_releaseNode(server->nsCtx, type);
     if(retval != UA_STATUSCODE_GOOD) {
         recursiveDeconstructNode(server, session, node);
         recursiveDeleteNode(server, session, node, true);
     }
-    UA_Nodestore_release(server, node);
+    UA_Nodestore_releaseNode(server->nsCtx, node);
     return retval;
 }
 
@@ -1237,7 +1238,7 @@ recursiveDeconstructNode(UA_Server *server, UA_Session *session,
                                       &session->sessionId, session->sessionHandle,
                                       &type->nodeId, type->context,
                                       &node->nodeId, &context);
-            UA_Nodestore_release(server, type);
+            UA_Nodestore_releaseNode(server->nsCtx, type);
         }
     }
 
@@ -1269,11 +1270,11 @@ recursiveDeconstructNode(UA_Server *server, UA_Session *session,
     /* Deconstruct every child node */
     for(size_t i = 0; i < br.referencesSize; ++i) {
         UA_ReferenceDescription *rd = &br.references[i];
-        const UA_Node *child = UA_Nodestore_get(server, &rd->nodeId.nodeId);
+        const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId);
         if(!child)
             continue;
         recursiveDeconstructNode(server, session, child);
-        UA_Nodestore_release(server, child);
+        UA_Nodestore_releaseNode(server->nsCtx, child);
     }
 
     UA_BrowseResult_deleteMembers(&br);
@@ -1303,10 +1304,10 @@ recursiveDeleteNode(UA_Server *server, UA_Session *session,
         /* Check for self-reference to avoid endless loop */
         if(UA_NodeId_equal(&node->nodeId, &rd->nodeId.nodeId))
             continue;
-        const UA_Node *child = UA_Nodestore_get(server, &rd->nodeId.nodeId);
+        const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId);
         if(child) {
             recursiveDeleteNode(server, session, child, true);
-            UA_Nodestore_release(server, child);
+            UA_Nodestore_releaseNode(server->nsCtx, child);
         }
     }
 
@@ -1315,7 +1316,7 @@ recursiveDeleteNode(UA_Server *server, UA_Session *session,
     if(removeTargetRefs)
         removeIncomingReferences(server, session, node);
 
-    UA_Nodestore_remove(server, &node->nodeId);
+    UA_Nodestore_removeNode(server->nsCtx, &node->nodeId);
 }
 
 static void
@@ -1330,7 +1331,7 @@ deleteNodeOperation(UA_Server *server, UA_Session *session, void *context,
         return;
     }
 
-    const UA_Node *node = UA_Nodestore_get(server, &item->nodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &item->nodeId);
     if(!node) {
         *result = UA_STATUSCODE_BADNODEIDUNKNOWN;
         return;
@@ -1340,7 +1341,7 @@ deleteNodeOperation(UA_Server *server, UA_Session *session, void *context,
         UA_LOG_INFO_SESSION(&server->config.logger, session,
                             "Delete Nodes: Cannot delete a type node "
                             "with active instances or subtypes");
-        UA_Nodestore_release(server, node);
+        UA_Nodestore_releaseNode(server->nsCtx, node);
         *result = UA_STATUSCODE_BADINTERNALERROR;
         return;
     }
@@ -1350,7 +1351,7 @@ deleteNodeOperation(UA_Server *server, UA_Session *session, void *context,
 
     recursiveDeconstructNode(server, session, node);
     recursiveDeleteNode(server, session, node, item->deleteTargetReferences);
-    UA_Nodestore_release(server, node);
+    UA_Nodestore_releaseNode(server->nsCtx, node);
 }
 
 void Service_DeleteNodes(UA_Server *server, UA_Session *session,

+ 2 - 2
src/server/ua_services_subscription.c

@@ -217,12 +217,12 @@ setMonitoredItemSettings(UA_Server *server, UA_MonitoredItem *mon,
     if(mon->attributeId == UA_ATTRIBUTEID_VALUE) {
         mon->monitoredItemType = UA_MONITOREDITEMTYPE_CHANGENOTIFY;
         const UA_VariableNode *vn = (const UA_VariableNode *)
-            UA_Nodestore_get(server, &mon->monitoredNodeId);
+            UA_Nodestore_getNode(server->nsCtx, &mon->monitoredNodeId);
         if(vn) {
             if(vn->nodeClass == UA_NODECLASS_VARIABLE &&
                samplingInterval < vn->minimumSamplingInterval)
                 samplingInterval = vn->minimumSamplingInterval;
-            UA_Nodestore_release(server, (const UA_Node *)vn);
+            UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node *)vn);
         }
     } else if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) {
         /* TODO: events should not need a samplinginterval */

+ 20 - 19
src/server/ua_services_view.c

@@ -46,7 +46,7 @@ fillReferenceDescription(UA_Server *server, const UA_Node *curr,
             const UA_Node *type = getNodeType(server, curr);
             if(type) {
                 retval |= UA_NodeId_copy(&type->nodeId, &descr->typeDefinition.nodeId);
-                UA_Nodestore_release(server, type);
+                UA_Nodestore_releaseNode(server->nsCtx, type);
             }
         }
     }
@@ -69,7 +69,7 @@ relevantReference(UA_Server *server, UA_Boolean includeSubtypes,
         return UA_NodeId_equal(rootRef, testRef);
 
     const UA_NodeId hasSubType = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
-    return isNodeInTree(&server->config.nodestore, testRef, rootRef, &hasSubType, 1);
+    return isNodeInTree(server->nsCtx, testRef, rootRef, &hasSubType, 1);
 }
 
 static UA_Boolean
@@ -140,13 +140,14 @@ browseReferences(UA_Server *server, const UA_Node *node,
         /* Loop over the targets */
         for(; targetIndex < rk->targetIdsSize; ++targetIndex) {
             /* Get the node */
-            const UA_Node *target = UA_Nodestore_get(server, &rk->targetIds[targetIndex].nodeId);
+            const UA_Node *target =
+                UA_Nodestore_getNode(server->nsCtx, &rk->targetIds[targetIndex].nodeId);
             if(!target)
                 continue;
 
             /* Test if the node class matches */
             if(!matchClassMask(target, descr->nodeClassMask)) {
-                UA_Nodestore_release(server, target);
+                UA_Nodestore_releaseNode(server->nsCtx, target);
                 continue;
             }
 
@@ -155,7 +156,7 @@ browseReferences(UA_Server *server, const UA_Node *node,
                 /* There are references we could not return */
                 cp->referenceKindIndex = referenceKindIndex;
                 cp->targetIndex = targetIndex;
-                UA_Nodestore_release(server, target);
+                UA_Nodestore_releaseNode(server->nsCtx, target);
                 return false;
             }
 
@@ -168,7 +169,7 @@ browseReferences(UA_Server *server, const UA_Node *node,
                     UA_realloc(result->references, sizeof(UA_ReferenceDescription) * refs_size);
                 if(!rd) {
                     result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
-                    UA_Nodestore_release(server, target);
+                    UA_Nodestore_releaseNode(server->nsCtx, target);
                     goto error_recovery;
                 }
                 result->references = rd;
@@ -179,7 +180,7 @@ browseReferences(UA_Server *server, const UA_Node *node,
                 fillReferenceDescription(server, target, rk, descr->resultMask,
                                          &result->references[result->referencesSize]);
 
-            UA_Nodestore_release(server, target);
+            UA_Nodestore_releaseNode(server->nsCtx, target);
 
             if(result->statusCode != UA_STATUSCODE_GOOD)
                 goto error_recovery;
@@ -230,14 +231,14 @@ browseWithContinuation(UA_Server *server, UA_Session *session,
 
     /* Is the reference type valid? */
     if(!UA_NodeId_isNull(&descr->referenceTypeId)) {
-        const UA_Node *reftype = UA_Nodestore_get(server, &descr->referenceTypeId);
+        const UA_Node *reftype = UA_Nodestore_getNode(server->nsCtx, &descr->referenceTypeId);
         if(!reftype) {
             result->statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
             return true;
         }
 
         UA_Boolean isRef = (reftype->nodeClass == UA_NODECLASS_REFERENCETYPE);
-        UA_Nodestore_release(server, reftype);
+        UA_Nodestore_releaseNode(server->nsCtx, reftype);
 
         if(!isRef) {
             result->statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
@@ -245,7 +246,7 @@ browseWithContinuation(UA_Server *server, UA_Session *session,
         }
     }
 
-    const UA_Node *node = UA_Nodestore_get(server, &descr->nodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &descr->nodeId);
     if(!node) {
         result->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
         return true;
@@ -253,7 +254,7 @@ browseWithContinuation(UA_Server *server, UA_Session *session,
 
     /* Browse the references */
     UA_Boolean done = browseReferences(server, node, cp, result);
-    UA_Nodestore_release(server, node);
+    UA_Nodestore_releaseNode(server->nsCtx, node);
     return done;
 }
 
@@ -472,11 +473,11 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, UA_UInt32 nodeClas
     /* Return all references? */
     UA_Boolean all_refs = UA_NodeId_isNull(&elem->referenceTypeId);
     if(!all_refs) {
-        const UA_Node *rootRef = UA_Nodestore_get(server, &elem->referenceTypeId);
+        const UA_Node *rootRef = UA_Nodestore_getNode(server->nsCtx, &elem->referenceTypeId);
         if(!rootRef)
             return;
         UA_Boolean match = (rootRef->nodeClass == UA_NODECLASS_REFERENCETYPE);
-        UA_Nodestore_release(server, rootRef);
+        UA_Nodestore_releaseNode(server->nsCtx, rootRef);
         if(!match)
             return;
     }
@@ -484,7 +485,7 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, UA_UInt32 nodeClas
     /* Iterate over all nodes at the current depth-level */
     for(size_t i = 0; i < currentCount; ++i) {
         /* Get the node */
-        const UA_Node *node = UA_Nodestore_get(server, &current[i]);
+        const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &current[i]);
         if(!node) {
             /* If we cannot find the node at depth 0, the starting node does not exist */
             if(elemDepth == 0)
@@ -494,7 +495,7 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, UA_UInt32 nodeClas
 
         /* Test whether the node fits the class mask */
         if(!matchClassMask(node, nodeClassMask)) {
-            UA_Nodestore_release(server, node);
+            UA_Nodestore_releaseNode(server->nsCtx, node);
             continue;
         }
 
@@ -502,7 +503,7 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, UA_UInt32 nodeClas
          * path element */
         if(targetName && (targetName->namespaceIndex != node->browseName.namespaceIndex ||
                           !UA_String_equal(&targetName->name, &node->browseName.name))) {
-            UA_Nodestore_release(server, node);
+            UA_Nodestore_releaseNode(server->nsCtx, node);
             continue;
         }
 
@@ -525,7 +526,7 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, UA_UInt32 nodeClas
                                                   nextCount, elemDepth, rk);
         }
 
-        UA_Nodestore_release(server, node);
+        UA_Nodestore_releaseNode(server->nsCtx, node);
     }
 }
 
@@ -535,7 +536,7 @@ addBrowsePathTargets(UA_Server *server, UA_Session *session, UA_UInt32 nodeClass
                      UA_BrowsePathResult *result, const UA_QualifiedName *targetName,
                      UA_NodeId *current, size_t currentCount) {
     for(size_t i = 0; i < currentCount; i++) {
-        const UA_Node *node = UA_Nodestore_get(server, &current[i]);
+        const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &current[i]);
         if(!node) {
             UA_NodeId_deleteMembers(&current[i]);
             continue;
@@ -550,7 +551,7 @@ addBrowsePathTargets(UA_Server *server, UA_Session *session, UA_UInt32 nodeClass
            !UA_String_equal(&targetName->name, &node->browseName.name))
             skip = true;
 
-        UA_Nodestore_release(server, node);
+        UA_Nodestore_releaseNode(server->nsCtx, node);
 
         if(skip) {
             UA_NodeId_deleteMembers(&current[i]);

+ 4 - 3
src/server/ua_subscription_datachange.c

@@ -204,7 +204,8 @@ detectValueChangeWithFilter(UA_Server *server, UA_MonitoredItem *mon, UA_DataVal
                   UA_BrowsePathResult_deleteMembers(&bpr);
                   return UA_STATUSCODE_GOOD;
             }
-            const UA_VariableNode* node = (const UA_VariableNode*) UA_Nodestore_get(server, &bpr.targets->targetId.nodeId);
+            const UA_VariableNode* node =
+                (const UA_VariableNode*) UA_Nodestore_getNode(server->nsCtx, &bpr.targets->targetId.nodeId);
             UA_Range* euRange = (UA_Range*) node->value.data.value.value.data;
             if(!updateNeededForFilteredPercentValue(&value->value, &mon->lastValue,
                                                     mon->filter.dataChangeFilter.deadbandValue, euRange)) {
@@ -408,7 +409,7 @@ UA_MonitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *monitoredIt
     }
 
     /* Get the node */
-    const UA_Node *node = UA_Nodestore_get(server, &monitoredItem->monitoredNodeId);
+    const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &monitoredItem->monitoredNodeId);
 
     /* Sample the value. The sample can still point into the node. */
     UA_DataValue value;
@@ -439,7 +440,7 @@ UA_MonitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *monitoredIt
     if(!movedValue)
         UA_DataValue_deleteMembers(&value); /* Does nothing for UA_VARIANT_DATA_NODELETE */
     if(node)
-        UA_Nodestore_release(server, node);
+        UA_Nodestore_releaseNode(server->nsCtx, node);
 }
 
 #endif /* UA_ENABLE_SUBSCRIPTIONS */

+ 12 - 10
src/server/ua_subscription_events.c

@@ -79,7 +79,7 @@ UA_Server_createEvent(UA_Server *server, const UA_NodeId eventType, UA_NodeId *o
     /* Make sure the eventType is a subtype of BaseEventType */
     UA_NodeId hasSubtypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
     UA_NodeId baseEventTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEEVENTTYPE);
-    if(!isNodeInTree(&server->config.nodestore, &eventType, &baseEventTypeId, &hasSubtypeId, 1)) {
+    if(!isNodeInTree(server->nsCtx, &eventType, &baseEventTypeId, &hasSubtypeId, 1)) {
         UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_USERLAND,
                      "Event type must be a subtype of BaseEventType!");
         return UA_STATUSCODE_BADINVALIDARGUMENT;
@@ -165,8 +165,7 @@ isValidEvent(UA_Server *server, const UA_NodeId *validEventParent, const UA_Node
     UA_NodeId conditionTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_CONDITIONTYPE);
     UA_NodeId hasSubtypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
     if(UA_NodeId_equal(validEventParent, &conditionTypeId) ||
-       isNodeInTree(&server->config.nodestore, tEventType,
-                     &conditionTypeId, &hasSubtypeId, 1)){
+       isNodeInTree(server->nsCtx, tEventType, &conditionTypeId, &hasSubtypeId, 1)) {
         UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_USERLAND,
                      "Alarms and Conditions are not supported yet!");
         UA_BrowsePathResult_deleteMembers(&bpr);
@@ -176,7 +175,7 @@ isValidEvent(UA_Server *server, const UA_NodeId *validEventParent, const UA_Node
 
     /* check whether Valid Event other than Conditions */
     UA_NodeId baseEventTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEEVENTTYPE);
-    UA_Boolean isSubtypeOfBaseEvent = isNodeInTree(&server->config.nodestore, tEventType,
+    UA_Boolean isSubtypeOfBaseEvent = isNodeInTree(server->nsCtx, tEventType,
                                                    &baseEventTypeId, &hasSubtypeId, 1);
 
     UA_BrowsePathResult_deleteMembers(&bpr);
@@ -375,11 +374,12 @@ getParentsNodeIteratorCallback(UA_NodeId parentId, UA_Boolean isInverse,
         return UA_STATUSCODE_GOOD;
 
     /* Is this a hierarchical reference? */
-    if(!isNodeInTree(&handle->server->config.nodestore, &referenceTypeId,
+    if(!isNodeInTree(handle->server->nsCtx, &referenceTypeId,
                      &hierarchicalReferences, &subtypeId, 1))
         return UA_STATUSCODE_GOOD;
 
-    Events_nodeListElement *entry = (Events_nodeListElement *) UA_malloc(sizeof(Events_nodeListElement));
+    Events_nodeListElement *entry = (Events_nodeListElement *)
+        UA_malloc(sizeof(Events_nodeListElement));
     if(!entry)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
@@ -435,9 +435,10 @@ UA_Server_triggerEvent(UA_Server *server, const UA_NodeId eventNodeId, const UA_
     /* Make sure the origin is in the ObjectsFolder (TODO: or in the ViewsFolder) */
     UA_NodeId *parentTypeHierachy = NULL;
     size_t parentTypeHierachySize = 0;
-    getTypesHierarchy(&server->config.nodestore, parentReferences_events, 2,
+    getTypesHierarchy(server->nsCtx, parentReferences_events, 2,
                       &parentTypeHierachy, &parentTypeHierachySize, true);
-    UA_Boolean isInObjectsFolder = isNodeInTree(&server->config.nodestore, &origin, &objectsFolderId, parentTypeHierachy, parentTypeHierachySize);
+    UA_Boolean isInObjectsFolder = isNodeInTree(server->nsCtx, &origin, &objectsFolderId,
+                                                parentTypeHierachy, parentTypeHierachySize);
     UA_Array_delete(parentTypeHierachy, parentTypeHierachySize, &UA_TYPES[UA_TYPES_NODEID]);
     if (!isInObjectsFolder) {
         UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_USERLAND,
@@ -469,7 +470,8 @@ UA_Server_triggerEvent(UA_Server *server, const UA_NodeId eventNodeId, const UA_
     /* Add the event to each node's monitored items */
     Events_nodeListElement *parentIter, *tmp_parentIter;
     LIST_FOREACH_SAFE(parentIter, &parentHandle.nodes, listEntry, tmp_parentIter) {
-        const UA_ObjectNode *node = (const UA_ObjectNode *) UA_Nodestore_get(server, &parentIter->nodeId);
+        const UA_ObjectNode *node = (const UA_ObjectNode*)
+            UA_Nodestore_getNode(server->nsCtx, &parentIter->nodeId);
         if(node->nodeClass == UA_NODECLASS_OBJECT) {
             for(UA_MonitoredItem *monIter = node->monitoredItemQueue; monIter != NULL; monIter = monIter->next) {
                 retval = UA_Event_addEventToMonitoredItem(server, &eventNodeId, monIter);
@@ -480,7 +482,7 @@ UA_Server_triggerEvent(UA_Server *server, const UA_NodeId eventNodeId, const UA_
                 }
             }
         }
-        UA_Nodestore_release(server, (const UA_Node *) node);
+        UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)node);
 
         LIST_REMOVE(parentIter, listEntry);
         UA_NodeId_deleteMembers(&parentIter->nodeId);

+ 1 - 2
src/server/ua_subscription_monitoreditem.c

@@ -34,8 +34,7 @@ UA_Notification_isOverflowEvent(UA_Server *server, UA_Notification *n) {
     UA_EventFieldList *efl = &n->data.event.fields;
     if(efl->eventFieldsSize == 1 &&
        efl->eventFields[0].type == &UA_TYPES[UA_TYPES_NODEID] &&
-       isNodeInTree(&server->config.nodestore,
-                    (const UA_NodeId *)efl->eventFields[0].data,
+       isNodeInTree(server->nsCtx, (const UA_NodeId *)efl->eventFields[0].data,
                     &overflowEventType, &subtypeId, 1)) {
         return true;
     }

+ 51 - 51
tests/server/check_nodestore.c

@@ -2,9 +2,9 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include <open62541/plugin/nodestore_default.h>
 #include <open62541/types.h>
 #include <open62541/util.h>
+#include <open62541/plugin/nodestore.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -42,15 +42,15 @@ static void checkAllReleased(void *context, const UA_Node* node) {
     ck_assert_int_eq(entry->refCount, 0); /* The count is increased when the visited node is checked out */
 }
 
-UA_Nodestore ns;
+void *nsCtx;
 
 static void setup(void) {
-    UA_Nodestore_default_new(&ns);
+    UA_Nodestore_new(&nsCtx);
 }
 
 static void teardown(void) {
-    ns.iterate(ns.context, NULL, checkAllReleased);
-    ns.deleteNodestore(ns.context);
+    UA_Nodestore_iterate(nsCtx, checkAllReleased, NULL);
+    UA_Nodestore_delete(nsCtx);
 }
 
 static int zeroCnt = 0;
@@ -61,7 +61,7 @@ static void checkZeroVisitor(void *context, const UA_Node* node) {
 }
 
 static UA_Node* createNode(UA_Int16 nsid, UA_Int32 id) {
-    UA_Node *p = ns.newNode(ns.context, UA_NODECLASS_VARIABLE);
+    UA_Node *p = UA_Nodestore_newNode(nsCtx, UA_NODECLASS_VARIABLE);
     p->nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
     p->nodeId.namespaceIndex = nsid;
     p->nodeId.identifier.numeric = id;
@@ -71,91 +71,91 @@ static UA_Node* createNode(UA_Int16 nsid, UA_Int32 id) {
 
 START_TEST(replaceExistingNode) {
     UA_Node* n1 = createNode(0,2253);
-    ns.insertNode(ns.context, n1, NULL);
+    UA_Nodestore_insertNode(nsCtx, n1, NULL);
     UA_NodeId in1 = UA_NODEID_NUMERIC(0, 2253);
     UA_Node* n2;
-    ns.getNodeCopy(ns.context, &in1, &n2);
-    UA_StatusCode retval = ns.replaceNode(ns.context, n2);
+    UA_Nodestore_getNodeCopy(nsCtx, &in1, &n2);
+    UA_StatusCode retval = UA_Nodestore_replaceNode(nsCtx, n2);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 }
 END_TEST
 
 START_TEST(replaceOldNode) {
     UA_Node* n1 = createNode(0,2253);
-    ns.insertNode(ns.context, n1, NULL);
+    UA_Nodestore_insertNode(nsCtx, n1, NULL);
     UA_NodeId in1 = UA_NODEID_NUMERIC(0,2253);
     UA_Node* n2;
     UA_Node* n3;
-    ns.getNodeCopy(ns.context, &in1, &n2);
-    ns.getNodeCopy(ns.context, &in1, &n3);
+    UA_Nodestore_getNodeCopy(nsCtx, &in1, &n2);
+    UA_Nodestore_getNodeCopy(nsCtx, &in1, &n3);
 
     /* shall succeed */
-    UA_StatusCode retval = ns.replaceNode(ns.context, n2);
+    UA_StatusCode retval = UA_Nodestore_replaceNode(nsCtx, n2);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 
     /* shall fail */
-    retval = ns.replaceNode(ns.context, n3);
+    retval = UA_Nodestore_replaceNode(nsCtx, n3);
     ck_assert_int_ne(retval, UA_STATUSCODE_GOOD);
 }
 END_TEST
 
 START_TEST(findNodeInUA_NodeStoreWithSingleEntry) {
     UA_Node* n1 = createNode(0,2253);
-    ns.insertNode(ns.context, n1, NULL);
+    UA_Nodestore_insertNode(nsCtx, n1, NULL);
     UA_NodeId in1 = UA_NODEID_NUMERIC(0,2253);
-    const UA_Node* nr = ns.getNode(ns.context, &in1);
+    const UA_Node* nr = UA_Nodestore_getNode(nsCtx, &in1);
     ck_assert_int_eq((uintptr_t)n1, (uintptr_t)nr);
-    ns.releaseNode(ns.context, nr);
+    UA_Nodestore_releaseNode(nsCtx, nr);
 }
 END_TEST
 
 START_TEST(failToFindNodeInOtherUA_NodeStore) {
     UA_Node* n1 = createNode(0,2255);
-    ns.insertNode(ns.context, n1, NULL);
+    UA_Nodestore_insertNode(nsCtx, n1, NULL);
     UA_NodeId in1 = UA_NODEID_NUMERIC(1, 2255);
-    const UA_Node* nr = ns.getNode(ns.context, &in1);
+    const UA_Node* nr = UA_Nodestore_getNode(nsCtx, &in1);
     ck_assert_int_eq((uintptr_t)nr, 0);
 }
 END_TEST
 
 START_TEST(findNodeInUA_NodeStoreWithSeveralEntries) {
     UA_Node* n1 = createNode(0,2253);
-    ns.insertNode(ns.context, n1, NULL);
+    UA_Nodestore_insertNode(nsCtx, n1, NULL);
     UA_Node* n2 = createNode(0,2255);
-    ns.insertNode(ns.context, n2, NULL);
+    UA_Nodestore_insertNode(nsCtx, n2, NULL);
     UA_Node* n3 = createNode(0,2257);
-    ns.insertNode(ns.context, n3, NULL);
+    UA_Nodestore_insertNode(nsCtx, n3, NULL);
     UA_Node* n4 = createNode(0,2200);
-    ns.insertNode(ns.context, n4, NULL);
+    UA_Nodestore_insertNode(nsCtx, n4, NULL);
     UA_Node* n5 = createNode(0,1);
-    ns.insertNode(ns.context, n5, NULL);
+    UA_Nodestore_insertNode(nsCtx, n5, NULL);
     UA_Node* n6 = createNode(0,12);
-    ns.insertNode(ns.context, n6, NULL);
+    UA_Nodestore_insertNode(nsCtx, n6, NULL);
 
     UA_NodeId in3 = UA_NODEID_NUMERIC(0, 2257);
-    const UA_Node* nr = ns.getNode(ns.context, &in3);
+    const UA_Node* nr = UA_Nodestore_getNode(nsCtx, &in3);
     ck_assert_int_eq((uintptr_t)nr, (uintptr_t)n3);
-    ns.releaseNode(ns.context, nr);
+    UA_Nodestore_releaseNode(nsCtx, nr);
 }
 END_TEST
 
 START_TEST(iterateOverUA_NodeStoreShallNotVisitEmptyNodes) {
     UA_Node* n1 = createNode(0,2253);
-    ns.insertNode(ns.context, n1, NULL);
+    UA_Nodestore_insertNode(nsCtx, n1, NULL);
     UA_Node* n2 = createNode(0,2255);
-    ns.insertNode(ns.context, n2, NULL);
+    UA_Nodestore_insertNode(nsCtx, n2, NULL);
     UA_Node* n3 = createNode(0,2257);
-    ns.insertNode(ns.context, n3, NULL);
+    UA_Nodestore_insertNode(nsCtx, n3, NULL);
     UA_Node* n4 = createNode(0,2200);
-    ns.insertNode(ns.context, n4, NULL);
+    UA_Nodestore_insertNode(nsCtx, n4, NULL);
     UA_Node* n5 = createNode(0,1);
-    ns.insertNode(ns.context, n5, NULL);
+    UA_Nodestore_insertNode(nsCtx, n5, NULL);
     UA_Node* n6 = createNode(0,12);
-    ns.insertNode(ns.context, n6, NULL);
+    UA_Nodestore_insertNode(nsCtx, n6, NULL);
 
     zeroCnt = 0;
     visitCnt = 0;
-    ns.iterate(ns.context, NULL, checkZeroVisitor);
+    UA_Nodestore_iterate(nsCtx, checkZeroVisitor, NULL);
     ck_assert_int_eq(zeroCnt, 0);
     ck_assert_int_eq(visitCnt, 6);
 }
@@ -164,26 +164,26 @@ END_TEST
 START_TEST(findNodeInExpandedNamespace) {
     for(UA_UInt32 i = 0; i < 200; i++) {
         UA_Node* n = createNode(0,i);
-        ns.insertNode(ns.context, n, NULL);
+        UA_Nodestore_insertNode(nsCtx, n, NULL);
     }
     // when
     UA_Node *n2 = createNode(0,25);
-    const UA_Node* nr = ns.getNode(ns.context, &n2->nodeId);
+    const UA_Node* nr = UA_Nodestore_getNode(nsCtx, &n2->nodeId);
     ck_assert_int_eq(nr->nodeId.identifier.numeric, n2->nodeId.identifier.numeric);
-    ns.releaseNode(ns.context, nr);
-    ns.deleteNode(ns.context, n2);
+    UA_Nodestore_releaseNode(nsCtx, nr);
+    UA_Nodestore_deleteNode(nsCtx, n2);
 }
 END_TEST
 
 START_TEST(iterateOverExpandedNamespaceShallNotVisitEmptyNodes) {
     for(UA_UInt32 i = 0; i < 200; i++) {
         UA_Node* n = createNode(0,i+1);
-        ns.insertNode(ns.context, n, NULL);
+        UA_Nodestore_insertNode(nsCtx, n, NULL);
     }
     // when
     zeroCnt = 0;
     visitCnt = 0;
-    ns.iterate(ns.context, NULL, checkZeroVisitor);
+    UA_Nodestore_iterate(nsCtx, checkZeroVisitor, NULL);
     // then
     ck_assert_int_eq(zeroCnt, 0);
     ck_assert_int_eq(visitCnt, 200);
@@ -192,18 +192,18 @@ END_TEST
 
 START_TEST(failToFindNonExistentNodeInUA_NodeStoreWithSeveralEntries) {
     UA_Node* n1 = createNode(0,2253);
-    ns.insertNode(ns.context, n1, NULL);
+    UA_Nodestore_insertNode(nsCtx, n1, NULL);
     UA_Node* n2 = createNode(0,2255);
-    ns.insertNode(ns.context, n2, NULL);
+    UA_Nodestore_insertNode(nsCtx, n2, NULL);
     UA_Node* n3 = createNode(0,2257);
-    ns.insertNode(ns.context, n3, NULL);
+    UA_Nodestore_insertNode(nsCtx, n3, NULL);
     UA_Node* n4 = createNode(0,2200);
-    ns.insertNode(ns.context, n4, NULL);
+    UA_Nodestore_insertNode(nsCtx, n4, NULL);
     UA_Node* n5 = createNode(0,1);
-    ns.insertNode(ns.context, n5, NULL);
+    UA_Nodestore_insertNode(nsCtx, n5, NULL);
 
     UA_NodeId id = UA_NODEID_NUMERIC(0, 12);
-    const UA_Node* nr = ns.getNode(ns.context, &id);
+    const UA_Node* nr = UA_Nodestore_getNode(nsCtx, &id);
     ck_assert_int_eq((uintptr_t)nr, 0);
 }
 END_TEST
@@ -227,8 +227,8 @@ static void *profileGetThread(void *arg) {
     for(UA_Int32 x = 0; x<test->rounds; x++) {
         for(UA_Int32 i=test->min_val; i<max_val; i++) {
             id.identifier.numeric = i+1;
-            const UA_Node *n = ns.getNode(ns.context, &id);
-            ns.releaseNode(ns.context, n);
+            const UA_Node *n = UA_Nodestore_getNode(nsCtx, &id);
+            UA_Nodestore_releaseNode(nsCtx, n);
         }
     }
     return NULL;
@@ -243,7 +243,7 @@ START_TEST(profileGetDelete) {
 
     for(UA_UInt32 i = 0; i < N; i++) {
         UA_Node *n = createNode(0,i+1);
-        ns.insertNode(ns.context, n, NULL);
+        UA_Nodestore_insertNode(nsCtx, n, NULL);
     }
 
 #ifdef UA_ENABLE_MULTITHREADING
@@ -262,8 +262,8 @@ START_TEST(profileGetDelete) {
     UA_NodeId id = UA_NODEID_NULL;
     for(size_t i = 0; i < N; i++) {
         id.identifier.numeric = (UA_UInt32)i+1;
-        const UA_Node *node = ns.getNode(ns.context, &id);
-        ns.releaseNode(ns.context, node);
+        const UA_Node *node = UA_Nodestore_getNode(nsCtx, &id);
+        UA_Nodestore_releaseNode(nsCtx, node);
     }
     end = clock();
     printf("Time for single-threaded %d create/get/delete in a namespace: %fs.\n", N,

+ 2 - 2
tools/nodeset_compiler/backend_open62541.py

@@ -166,7 +166,7 @@ def generateOpen62541Code(nodeset, outfilename, generate_ns0=False, internal_hea
 
 /* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */
 
-# ifndef UA_Nodestore_remove //this definition is needed to hide this code in the amalgamated .c file
+# ifndef UA_INTERNAL //this definition is needed to hide this code in the amalgamated .c file
 
 typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos,
                                                  const UA_Byte **bufEnd);
@@ -188,7 +188,7 @@ UA_calcSizeBinary(void *p, const UA_DataType *type);
 const UA_DataType *
 UA_findDataTypeByBinary(const UA_NodeId *typeId);
 
-# endif // UA_Nodestore_remove
+# endif // UA_INTERNAL
 
 #else // UA_ENABLE_AMALGAMATION
 # include <open62541/server.h>