diff --git a/src/webui/service/main/DescriptorTools.py b/src/webui/service/main/DescriptorTools.py
new file mode 100644
index 0000000000000000000000000000000000000000..31bb793d82be604a96a4d67f9fd40a6b4cbc1579
--- /dev/null
+++ b/src/webui/service/main/DescriptorTools.py
@@ -0,0 +1,75 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy
+from typing import Dict, List, Optional, Tuple
+
+def get_descriptors_add_contexts(contexts : List[Dict]) -> List[Dict]:
+    contexts_add = copy.deepcopy(contexts)
+    for context in contexts_add:
+        context['topology_ids'] = []
+        context['service_ids'] = []
+    return contexts_add
+
+def get_descriptors_add_topologies(topologies : List[Dict]) -> List[Dict]:
+    topologies_add = copy.deepcopy(topologies)
+    for topology in topologies_add:
+        topology['device_ids'] = []
+        topology['link_ids'] = []
+    return topologies_add
+
+def get_descriptors_add_services(services : List[Dict]) -> List[Dict]:
+    services_add = []
+    for service in services:
+        service_copy = copy.deepcopy(service)
+        service_copy['service_endpoint_ids'] = []
+        service_copy['service_constraints'] = []
+        service_copy['service_config'] = {'config_rules': []}
+        services_add.append(service_copy)
+    return services_add
+
+def get_descriptors_add_slices(slices : List[Dict]) -> List[Dict]:
+    slices_add = []
+    for slice in slices:
+        slice_copy = copy.deepcopy(slice)
+        slice_copy['slice_endpoint_ids'] = []
+        slice_copy['slice_constraints'] = []
+        slice_copy['slice_config'] = {'config_rules': []}
+        slices_add.append(slice_copy)
+    return slices_add
+
+def split_devices_by_rules(devices : List[Dict]) -> Tuple[List[Dict], List[Dict]]:
+    devices_add = []
+    devices_config = []
+    for device in devices:
+        connect_rules = []
+        config_rules = []
+        for config_rule in device.get('device_config', {}).get('config_rules', []):
+            custom_resource_key : Optional[str] = config_rule.get('custom', {}).get('resource_key')
+            if custom_resource_key is not None and custom_resource_key.startswith('_connect/'):
+                connect_rules.append(config_rule)
+            else:
+                config_rules.append(config_rule)
+
+        if len(connect_rules) > 0:
+            device_add = copy.deepcopy(device)
+            device_add['device_endpoints'] = []
+            device_add['device_config'] = {'config_rules': connect_rules}
+            devices_add.append(device_add)
+
+        if len(config_rules) > 0:
+            device['device_config'] = {'config_rules': config_rules}
+            devices_config.append(device)
+
+    return devices_add, devices_config
diff --git a/src/webui/service/main/routes.py b/src/webui/service/main/routes.py
index d115444487c7356a541f3c567e5dea183da73ade..80dfb30c2bdd8d75937611bf0dfbd8e3426e4847 100644
--- a/src/webui/service/main/routes.py
+++ b/src/webui/service/main/routes.py
@@ -12,8 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import copy, json, logging
-from typing import Optional
+import json, logging
 from flask import jsonify, redirect, render_template, Blueprint, flash, session, url_for, request
 from common.proto.context_pb2 import Connection, Context, Device, Empty, Link, Service, Slice, Topology, ContextIdList
 from common.tools.grpc.Tools import grpc_message_to_json_string
@@ -21,6 +20,9 @@ from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
 from service.client.ServiceClient import ServiceClient
 from slice.client.SliceClient import SliceClient
+from webui.service.main.DescriptorTools import (
+    get_descriptors_add_contexts, get_descriptors_add_services, get_descriptors_add_slices,
+    get_descriptors_add_topologies, split_devices_by_rules)
 from webui.service.main.forms import ContextForm, DescriptorForm
 
 main = Blueprint('main', __name__)
@@ -82,94 +84,54 @@ def process_descriptors(descriptors):
     slices      = descriptors.get('slices'     , [])
     connections = descriptors.get('connections', [])
 
+    # Context and Topology require to create the entity first, and add devices, links, services, slices, etc. in a
+    # second stage.
+    contexts_add = get_descriptors_add_contexts(contexts)
+    topologies_add = get_descriptors_add_topologies(topologies)
+
     if dummy_mode:
         # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks.
         context_client.connect()
-
-        contexts_add = copy.deepcopy(contexts)
-        for context in contexts_add:
-            context['topology_ids'] = []
-            context['service_ids'] = []
-
-        topologies_add = copy.deepcopy(topologies)
-        for topology in topologies_add:
-            topology['device_ids'] = []
-            topology['link_ids'] = []
-
         process_descriptor('context',    'add',    context_client.SetContext,    Context,    contexts_add  )
         process_descriptor('topology',   'add',    context_client.SetTopology,   Topology,   topologies_add)
         process_descriptor('device',     'add',    context_client.SetDevice,     Device,     devices       )
         process_descriptor('link',       'add',    context_client.SetLink,       Link,       links         )
         process_descriptor('service',    'add',    context_client.SetService,    Service,    services      )
-        process_descriptor('context',    'update', context_client.SetContext,    Context,    contexts      )
-        process_descriptor('topology',   'update', context_client.SetTopology,   Topology,   topologies    )
         process_descriptor('slice',      'add',    context_client.SetSlice,      Slice,      slices        )
         process_descriptor('connection', 'add',    context_client.SetConnection, Connection, connections   )
+        process_descriptor('context',    'update', context_client.SetContext,    Context,    contexts      )
+        process_descriptor('topology',   'update', context_client.SetTopology,   Topology,   topologies    )
         context_client.close()
-        return
+    else:
+        # Normal mode: follows the automated workflows in the different components
+        assert len(connections) == 0, 'in normal mode, connections should not be set'
 
-    # Normal mode: follows the automated workflows in the different components
-
-    # in normal mode, connections should not be set
-    assert len(connections) == 0
-
-    devices_add = []
-    devices_config = []
-    for device in devices:
-        connect_rules = []
-        config_rules = []
-        for config_rule in device.get('device_config', {}).get('config_rules', []):
-            custom_resource_key : Optional[str] = config_rule.get('custom', {}).get('resource_key')
-            if custom_resource_key is not None and custom_resource_key.startswith('_connect/'):
-                connect_rules.append(config_rule)
-            else:
-                config_rules.append(config_rule)
-
-        if len(connect_rules) > 0:
-            device_add = copy.deepcopy(device)
-            device_add['device_endpoints'] = []
-            device_add['device_config'] = {'config_rules': connect_rules}
-            devices_add.append(device_add)
-
-        if len(config_rules) > 0:
-            device['device_config'] = {'config_rules': config_rules}
-            devices_config.append(device)
-
-    services_add = []
-    for service in services:
-        service_copy = copy.deepcopy(service)
-        service_copy['service_endpoint_ids'] = []
-        service_copy['service_constraints'] = []
-        service_copy['service_config'] = {'config_rules': []}
-        services_add.append(service_copy)
-
-    slices_add = []
-    for slice in slices:
-        slice_copy = copy.deepcopy(slice)
-        slice_copy['slice_endpoint_ids'] = []
-        slice_copy['slice_constraints'] = []
-        slice_copy['slice_config'] = {'config_rules': []}
-        slices_add.append(slice_copy)
+        # Device, Service and Slice require to first create the entity and the configure it
+        devices_add, devices_config = split_devices_by_rules(devices)
+        services_add = get_descriptors_add_services(services)
+        slices_add = get_descriptors_add_slices(slices)
 
-    context_client.connect()
-    device_client.connect()
-    service_client.connect()
-    slice_client.connect()
-
-    process_descriptor('context',  'add',    context_client.SetContext,      Context,  contexts      )
-    process_descriptor('topology', 'add',    context_client.SetTopology,     Topology, topologies    )
-    process_descriptor('device',   'add',    device_client .AddDevice,       Device,   devices_add   )
-    process_descriptor('device',   'config', device_client .ConfigureDevice, Device,   devices_config)
-    process_descriptor('link',     'add',    context_client.SetLink,         Link,     links         )
-    process_descriptor('service',  'add',    service_client.CreateService,   Service,  services_add  )
-    process_descriptor('service',  'update', service_client.UpdateService,   Service,  services      )
-    process_descriptor('slice',    'add',    slice_client  .CreateSlice,     Slice,    slices_add    )
-    process_descriptor('slice',    'update', slice_client  .UpdateSlice,     Slice,    slices        )
-
-    slice_client.close()
-    service_client.close()
-    device_client.close()
-    context_client.close()
+        context_client.connect()
+        device_client.connect()
+        service_client.connect()
+        slice_client.connect()
+
+        process_descriptor('context',    'add',    context_client.SetContext,      Context,    contexts_add  )
+        process_descriptor('topology',   'add',    context_client.SetTopology,     Topology,   topologies_add)
+        process_descriptor('device',     'add',    device_client .AddDevice,       Device,     devices_add   )
+        process_descriptor('device',     'config', device_client .ConfigureDevice, Device,     devices_config)
+        process_descriptor('link',       'add',    context_client.SetLink,         Link,       links         )
+        process_descriptor('service',    'add',    service_client.CreateService,   Service,    services_add  )
+        process_descriptor('service',    'update', service_client.UpdateService,   Service,    services      )
+        process_descriptor('slice',      'add',    slice_client  .CreateSlice,     Slice,      slices_add    )
+        process_descriptor('slice',      'update', slice_client  .UpdateSlice,     Slice,      slices        )
+        process_descriptor('context',    'update', context_client.SetContext,      Context,    contexts      )
+        process_descriptor('topology',   'update', context_client.SetTopology,     Topology,   topologies    )
+
+        slice_client.close()
+        service_client.close()
+        device_client.close()
+        context_client.close()
 
 @main.route('/', methods=['GET', 'POST'])
 def home():