diff --git a/src/device/service/drivers/ietf_actn/ComposerOsuTunnel.py b/src/device/service/drivers/ietf_actn/ComposerOsuTunnel.py
deleted file mode 100644
index ad369482e67d56a8cccf64db15e16f1be0effa4c..0000000000000000000000000000000000000000
--- a/src/device/service/drivers/ietf_actn/ComposerOsuTunnel.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
-#
-# 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 enum
-from typing import Dict
-
-OSU_TUNNEL_URL = '/restconf/data/ietf-te:tunnel'
-
-class EndpointProtectionRoleEnum(enum.Enum):
-    WORK = 'work'
-
-class LspProtectionTypeEnum(enum.Enum):
-    UNPROTECTED = 'ietf-te-types:lsp-protection-unprotected'
-
-class LspRestorationTypeEnum(enum.Enum):
-    NOT_APPLICABLE = 'ietf-te-types:lsp-restoration-not-applicable'
-
-class TunnelAdminStateEnum(enum.Enum):
-    UP = 'ietf-te-types:tunnel-admin-state-up'
-
-class OduTypeEnum(enum.Enum):
-    OSUFLEX = 'osuflex'
-
-def compose_osu_tunnel_endpoint(
-    node_id : str, tp_id : str, ttp_channel_name : str,
-    protection_role : EndpointProtectionRoleEnum = EndpointProtectionRoleEnum.WORK
-) -> Dict:
-    return {
-        'node-id': node_id, 'tp-id': tp_id, 'ttp-channel-name': ttp_channel_name,
-        'protection-role': protection_role.value
-    }
-
-def compose_osu_tunnel_te_bandwidth_odu(odu_type : OduTypeEnum, number : int) -> Dict:
-    return {'layer': 'odu', 'odu-type': odu_type.value, 'number': number}
-
-def compose_osu_tunnel_protection(
-    type_ : LspProtectionTypeEnum = LspProtectionTypeEnum.UNPROTECTED, reversion_disable : bool = True
-) -> Dict:
-    return {'protection-type': type_.value, 'protection-reversion-disable': reversion_disable}
-
-def compose_osu_tunnel_restoration(
-    type_ : LspRestorationTypeEnum = LspRestorationTypeEnum.NOT_APPLICABLE, restoration_lock : bool = False
-) -> Dict:
-    return {'restoration-type': type_.value, 'restoration-lock': restoration_lock}
-
-def compose_osu_tunnel(
-    name : str,
-    src_node_id : str, src_tp_id : str, src_ttp_channel_name : str,
-    dst_node_id : str, dst_tp_id : str, dst_ttp_channel_name : str,
-    odu_type : OduTypeEnum, osuflex_number : int,
-    delay : int, bidirectional : bool = True,
-    admin_state : TunnelAdminStateEnum = TunnelAdminStateEnum.UP
-) -> Dict:
-    return {'ietf-te:tunnel': [{
-        'name': name.lower(),
-        'title': name.upper(),
-        'admin-state': admin_state.value,
-        'delay': delay,
-        'te-bandwidth': compose_osu_tunnel_te_bandwidth_odu(odu_type, osuflex_number),
-        'bidirectional': bidirectional,
-        'source-endpoints': {'source-endpoint': [
-            compose_osu_tunnel_endpoint(src_node_id, src_tp_id, src_ttp_channel_name),
-        ]},
-        'destination-endpoints': {'destination-endpoint': [
-            compose_osu_tunnel_endpoint(dst_node_id, dst_tp_id, dst_ttp_channel_name),
-        ]},
-        'restoration': compose_osu_tunnel_restoration(),
-        'protection': compose_osu_tunnel_protection(),
-    }]}
diff --git a/src/device/service/drivers/ietf_actn/Tools.py b/src/device/service/drivers/ietf_actn/Tools.py
index 1b89315b1820b77f36e45938c6a7c77d01e2b5f7..ef60446e7c2fc81b5b258fa646230f8062442e23 100644
--- a/src/device/service/drivers/ietf_actn/Tools.py
+++ b/src/device/service/drivers/ietf_actn/Tools.py
@@ -140,40 +140,7 @@ def create_resource(
 
     url = '{:s}/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context'.format(base_url)
     headers = {'content-type': 'application/json'}
-    data = {
-        'tapi-connectivity:connectivity-service': [
-            {
-                'uuid': uuid,
-                'connectivity-constraint': {
-                    'requested-capacity': {
-                        'total-size': {
-                            'value': capacity_value,
-                            'unit': capacity_unit
-                        }
-                    },
-                    'connectivity-direction': direction
-                },
-                'end-point': [
-                    {
-                        'service-interface-point': {
-                            'service-interface-point-uuid': input_sip
-                        },
-                        'layer-protocol-name': layer_protocol_name,
-                        'layer-protocol-qualifier': layer_protocol_qualifier,
-                        'local-id': input_sip
-                    },
-                    {
-                        'service-interface-point': {
-                            'service-interface-point-uuid': output_sip
-                        },
-                        'layer-protocol-name': layer_protocol_name,
-                        'layer-protocol-qualifier': layer_protocol_qualifier,
-                        'local-id': output_sip
-                    }
-                ]
-            }
-        ]
-    }
+    data = compose_...
     results = []
     try:
         LOGGER.info('Connectivity service {:s}: {:s}'.format(str(uuid), str(data)))
@@ -194,9 +161,9 @@ def delete_resource(
     base_url : str, resource_key : str, resource_value : Dict,
     auth : Optional[HTTPBasicAuth] = None, timeout : Optional[int] = None
 ):
-    uuid = find_key(resource, 'uuid')
+    uuid = find_key(resource_value, 'uuid')
 
-    url = '{:s}/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service={:s}'
+    url = '{:s}/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service={:s}'
     url = url.format(base_url, uuid)
     results = []
     try:
diff --git a/src/device/service/drivers/ietf_actn/examples/eth_svc_1.json b/src/device/service/drivers/ietf_actn/examples/eth_svc_1.json
new file mode 100644
index 0000000000000000000000000000000000000000..840092429c28c42077d502ebb3860e4c99113e72
--- /dev/null
+++ b/src/device/service/drivers/ietf_actn/examples/eth_svc_1.json
@@ -0,0 +1,91 @@
+{
+    "ietf-eth-tran-service:etht-svc": {
+        "etht-svc-instances": [
+            {
+                "etht-svc-name": "etht_service_1",
+                "etht-svc-title": "ETHT_SVC_1",
+                "etht-svc-type": "op-mp2mp-svc?",
+                "source-endpoints": {
+                    "source-endpoint": [
+                        {
+                            "node-id": "10.0.10.1",
+                            "tp-id": "200",
+                            "protection-role": "work?",
+                            "layer-specific": {
+                                "access-type": "port"
+                            },
+                            "is-extendable": false,
+                            "is-terminal": true,
+                            "static-route-list": [
+                                {
+                                    "destination": "128.32.10.5",
+                                    "destination-mask": 24,
+                                    "next-hop": "128.32.33.5"
+                                },
+                                {
+                                    "destination": "128.32.20.5",
+                                    "destination-mask": 24,
+                                    "next-hop": "128.32.33.5"
+                                }
+                            ],
+                            "outer-tag": {
+                                "tag-type": "ietf-eth-tran-types:classify-c-vlan",
+                                "vlan-value": 21
+                            },
+                            "service-classification-type": "ietf-eth-tran-type:vlan-classification",
+                            "ingress-egress-bandwidth-profile" : {
+                                "bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
+                                "CIR": 10000000,
+                                "EIR": 10000000
+                            }
+                        }
+                    ]
+                },
+                "destination-endpoints": {
+                    "destination-endpoint": [
+                        {
+                            "node-id": "10.0.30.1",
+                            "tp-id": "200",
+                            "protection-role": "work?",
+                            "layer-specific": {
+                                "access-type": "port"
+                            },
+                            "is-extendable": false,
+                            "is-terminal": true,
+                            "static-route-list": [
+                                {
+                                    "destination": "172.1.101.22",
+                                    "destination-mask": 24,
+                                    "next-hop": "172.10.33.5"
+                                }
+                            ],
+                            "outer-tag": {
+                                "tag-type": "ietf-eth-tran-types:classify-c-vlan",
+                                "vlan-value": 101
+                            },
+                            "service-classification-type": "ietf-eth-tran-type:vlan-classification",
+                            "ingress-egress-bandwidth-profile" : {
+                                "bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
+                                "CIR": 10000000,
+                                "EIR": 10000000
+                            }
+                        }
+                    ]
+                },
+                "svc-tunnel": [
+                    {
+                        "tunnel-name": "osu_tunnel_1"
+                    }
+                ],
+                "optimizations": {
+                    "optimization-metric": [
+                        {
+                            "metric-role": "work?",
+                            "metric-type": "ietf-te-types:path-metric-te"
+                        }
+                    ]
+                }
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/src/device/service/drivers/ietf_actn/examples/eth_svc_2.json b/src/device/service/drivers/ietf_actn/examples/eth_svc_2.json
new file mode 100644
index 0000000000000000000000000000000000000000..74ca61d0399e4a2912ac280afc2eef9a50a235cf
--- /dev/null
+++ b/src/device/service/drivers/ietf_actn/examples/eth_svc_2.json
@@ -0,0 +1,91 @@
+{
+    "ietf-eth-tran-service:etht-svc": {
+        "etht-svc-instances": [
+            {
+                "etht-svc-name": "etht_service_2",
+                "etht-svc-title": "ETHT_SVC_2",
+                "etht-svc-type": "op-p2mp-svc?",
+                "source-endpoints": {
+                    "source-endpoint": [
+                        {
+                            "node-id": "10.0.10.1",
+                            "tp-id": "200",
+                            "protection-role": "work?",
+                            "layer-specific": {
+                                "access-type": "port"
+                            },
+                            "is-extendable": false,
+                            "is-terminal": true,
+                            "static-route-list": [
+                                {
+                                    "destination": "128.32.10.5",
+                                    "destination-mask": 24,
+                                    "next-hop": "128.32.33.5"
+                                },
+                                {
+                                    "destination": "128.32.20.5",
+                                    "destination-mask": 24,
+                                    "next-hop": "128.32.33.5"
+                                }
+                            ],
+                            "outer-tag": {
+                                "tag-type": "ietf-eth-tran-types:classify-c-vlan",
+                                "vlan-value": 31
+                            },
+                            "service-classification-type": "ietf-eth-tran-type:vlan-classification",
+                            "ingress-egress-bandwidth-profile" : {
+                                "bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
+                                "CIR": 10000000,
+                                "EIR": 10000000
+                            }
+                        }
+                    ]
+                },
+                "destination-endpoints": {
+                    "destination-endpoint": [
+                        {
+                            "node-id": "10.0.30.1",
+                            "tp-id": "200",
+                            "protection-role": "work?",
+                            "layer-specific": {
+                                "access-type": "port"
+                            },
+                            "is-extendable": false,
+                            "is-terminal": true,
+                            "static-route-list": [
+                                {
+                                    "destination": "172.1.101.22",
+                                    "destination-mask": 24,
+                                    "next-hop": "172.10.33.5"
+                                }
+                            ],
+                            "outer-tag": {
+                                "tag-type": "ietf-eth-tran-types:classify-c-vlan",
+                                "vlan-value": 201
+                            },
+                            "service-classification-type": "ietf-eth-tran-type:vlan-classification",
+                            "ingress-egress-bandwidth-profile" : {
+                                "bandwidth-profile-type": "ietf-eth-tran-types:mef-10-bwp",
+                                "CIR": 10000000,
+                                "EIR": 10000000
+                            }
+                        }
+                    ]
+                },
+                "svc-tunnel": [
+                    {
+                        "tunnel-name": "osu_tunnel_2"
+                    }
+                ],
+                "optimizations": {
+                    "optimization-metric": [
+                        {
+                            "metric-role": "work?",
+                            "metric-type": "ietf-te-types:path-metric-te"
+                        }
+                    ]
+                }
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/src/device/service/drivers/ietf_actn/examples/osu_tunnel_1.json b/src/device/service/drivers/ietf_actn/examples/osu_tunnel_1.json
new file mode 100644
index 0000000000000000000000000000000000000000..728450b92883ed13916847577bbd0948607ff943
--- /dev/null
+++ b/src/device/service/drivers/ietf_actn/examples/osu_tunnel_1.json
@@ -0,0 +1,44 @@
+{
+    "ietf-te:tunnel": [
+        {
+            "name": "osu_tunnel_1",
+            "title": "OSU_TUNNEL_1",
+            "admin-state": "ietf-te-types:tunnel-admin-state-up",
+            "delay": 20,
+            "te-bandwidth": {
+                "layer": "odu",
+                "odu-type": "osuflex",
+                "number": 1
+            },
+            "bidirectional": true,
+            "destination-endpoints": {
+                "destination-endpoint": [
+                    {
+                        "node-id": "10.0.30.1",
+                        "tp-id": "200",
+                        "ttp-channel-name": "och:1-odu2:1-oduflex:3-osuflex:1?",
+                        "protection-role": "work"
+                    }
+                ]
+            },
+            "source-endpoints": {
+                "source-endpoint": [
+                    {
+                        "node-id": "10.0.10.1",
+                        "tp-id": "200",
+                        "ttp-channel-name": "och:1-odu2:1-oduflex:1-osuflex:2?",
+                        "protection-role": "work"
+                    }
+                ]
+            },
+            "restoration": {
+                "restoration-type": "ietf-te-types:lsp-restoration-not-applicable",
+                "restoration-lock": false
+            },
+            "protection": {
+                "protection-type": "ietf-te-types:lsp-protection-unprotected",
+                "protection-reversion-disable": true
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/device/service/drivers/ietf_actn/examples/osu_tunnel_2.json b/src/device/service/drivers/ietf_actn/examples/osu_tunnel_2.json
new file mode 100644
index 0000000000000000000000000000000000000000..4e6966b8f53ab9ef87f930e2c7f6d9db88365ff9
--- /dev/null
+++ b/src/device/service/drivers/ietf_actn/examples/osu_tunnel_2.json
@@ -0,0 +1,44 @@
+{
+    "ietf-te:tunnel": [
+        {
+            "name": "osu_tunnel_2",
+            "title": "OSU_TUNNEL_2",
+            "admin-state": "ietf-te-types:tunnel-admin-state-up",
+            "delay": 20,
+            "te-bandwidth": {
+                "layer": "odu",
+                "odu-type": "osuflex",
+                "number": 1
+            },
+            "bidirectional": true,
+            "destination-endpoints": {
+                "destination-endpoint": [
+                    {
+                        "node-id": "10.0.30.1",
+                        "tp-id": "200",
+                        "ttp-channel-name": "och:1-odu2:1-oduflex:3-osuflex:1?",
+                        "protection-role": "work"
+                    }
+                ]
+            },
+            "source-endpoints": {
+                "source-endpoint": [
+                    {
+                        "node-id": "10.0.10.1",
+                        "tp-id": "200",
+                        "ttp-channel-name": "och:1-odu2:1-oduflex:1-osuflex:2?",
+                        "protection-role": "work"
+                    }
+                ]
+            },
+            "restoration": {
+                "restoration-type": "ietf-te-types:lsp-restoration-not-applicable",
+                "restoration-lock": false
+            },
+            "protection": {
+                "protection-type": "ietf-te-types:lsp-protection-unprotected",
+                "protection-reversion-disable": true
+            }
+        }
+    ]
+}
\ No newline at end of file
diff --git a/src/device/service/drivers/ietf_actn/handlers/EthService.py b/src/device/service/drivers/ietf_actn/handlers/EthService.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d923b16cd7bcc9c0cb1c01e38c66336a1c78cd1
--- /dev/null
+++ b/src/device/service/drivers/ietf_actn/handlers/EthService.py
@@ -0,0 +1,106 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# 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 enum
+from typing import Dict, List, Tuple
+
+OSU_TUNNEL_URL = '/restconf/data/ietf-te:tunnel'
+
+class BandwidthProfileTypeEnum(enum.Enum):
+    MEF_10_BWP = 'ietf-eth-tran-types:mef-10-bwp'
+
+class EndpointLayerSpecificAccessTypeEnum(enum.Enum):
+    PORT = 'port'
+
+class EndpointProtectionRoleEnum(enum.Enum):
+    WORK = 'work'
+
+class OptimizationMetricRole(enum.Enum):
+    WORK = 'work'
+
+class OptimizationMetricType(enum.Enum):
+    PATH_METRIC_TE = 'ietf-te-types:path-metric-te'
+
+class OuterTagTypeEnum(enum.Enum):
+    CLASSIFY_C_VLAN = 'ietf-eth-tran-types:classify-c-vlan'
+
+class ServiceClassificationTypeEnum(enum.Enum):
+    VLAN_CLASSIFICATION = 'ietf-eth-tran-type:vlan-classification'
+
+class ServiceTypeEnum(enum.Enum):
+    MP2MP = 'op-mp2mp-svc'
+    P2MP  = 'op-p2mp-svc'
+
+def compose_outer_tag(tag_type : OuterTagTypeEnum, vlan_value : int) -> Dict:
+    return {'tag-type': tag_type.value, 'vlan-value': vlan_value}
+
+def compose_ingress_egress_bandwidth_profile() -> Dict:
+    return {
+        'bandwidth-profile-type': BandwidthProfileTypeEnum.MEF_10_BWP.value,
+        'CIR': 10_000_000,
+        'EIR': 10_000_000,
+    }
+
+def compose_layer_specific_access_type() -> Dict:
+    return {'access-type': EndpointLayerSpecificAccessTypeEnum.PORT.value}
+
+def compose_static_route(prefix : str, mask : int, next_hop : str) -> Dict:
+    return {'destination': prefix, 'destination-mask': mask, 'next-hop': next_hop}
+
+def compose_static_route_list(static_routes : List[Tuple[str, int, str]]) -> List[Dict]:
+    return [
+        compose_static_route(prefix, mask, next_hop)
+        for prefix, mask, next_hop in static_routes
+    ]
+
+def compose_etht_service_endpoint(
+    node_id : str, tp_id : str, vlan_value : int, static_routes : List[Tuple[str, int, str]] = list()
+) -> Dict:
+    return {
+        'node-id'           : node_id,
+        'tp-id'             : tp_id,
+        'protection-role'   : EndpointProtectionRoleEnum.WORK.value,
+        'layer-specific'    : compose_layer_specific_access_type,
+        'is-extendable'     : False,
+        'is-terminal'       : True,
+        'static-route-list' : compose_static_route_list(static_routes),
+        'outer-tag'         : compose_outer_tag(OuterTagTypeEnum.CLASSIFY_C_VLAN, vlan_value),
+        'service-classification-type'     : ServiceClassificationTypeEnum.VLAN_CLASSIFICATION.value,
+        'ingress-egress-bandwidth-profile': compose_ingress_egress_bandwidth_profile(),
+    }
+
+def compose_optimizations() -> Dict:
+    return {'optimization-metric': [{
+        'metric-role': OptimizationMetricRole.WORK.value,
+        'metric-type': OptimizationMetricType.PATH_METRIC_TE.value,
+    }]}
+
+def compose_etht_service(
+    name : str, service_type : ServiceTypeEnum, osu_tunnel_name : str,
+    src_node_id : str, src_tp_id : str, src_vlan_tag : int, dst_node_id : str, dst_tp_id : str, dst_vlan_tag : int,
+    src_static_routes : List[Tuple[str, int, str]] = list(), dst_static_routes : List[Tuple[str, int, str]] = list()
+) -> Dict:
+    return {'ietf-eth-tran-service:etht-svc': {'etht-svc-instances': [{
+        'etht-svc-name' : name.lower(),
+        'etht-svc-title': name.upper(),
+        'etht-svc-type' : service_type.value,
+        'source-endpoints': {'source-endpoint': [
+            compose_etht_service_endpoint(src_node_id, src_tp_id, src_vlan_tag, src_static_routes),
+        ]},
+        'destination-endpoints': {'destination-endpoint': [
+            compose_etht_service_endpoint(dst_node_id, dst_tp_id, dst_vlan_tag, dst_static_routes),
+        ]},
+        'svc-tunnel': [{'tunnel-name': osu_tunnel_name}],
+        'optimizations': compose_optimizations(),
+    }]}}
diff --git a/src/device/service/drivers/ietf_actn/handlers/OsuTunnel.py b/src/device/service/drivers/ietf_actn/handlers/OsuTunnel.py
new file mode 100644
index 0000000000000000000000000000000000000000..a15f73eab7e550d3ba43447ba260cee19daf7fff
--- /dev/null
+++ b/src/device/service/drivers/ietf_actn/handlers/OsuTunnel.py
@@ -0,0 +1,236 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# 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 enum, json, logging, operator, requests
+from requests.auth import HTTPBasicAuth
+from typing import Dict, List, Optional
+from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_SERVICES
+from .Tools import HTTP_OK_CODES
+
+LOGGER = logging.getLogger(__name__)
+
+BASE_URL_OSU_TUNNEL = '{:s}/ietf-te:tunnel'
+
+class EndpointProtectionRoleEnum(enum.Enum):
+    WORK = 'work'
+
+class LspProtectionTypeEnum(enum.Enum):
+    UNPROTECTED = 'ietf-te-types:lsp-protection-unprotected'
+
+class LspRestorationTypeEnum(enum.Enum):
+    NOT_APPLICABLE = 'ietf-te-types:lsp-restoration-not-applicable'
+
+class TunnelAdminStateEnum(enum.Enum):
+    UP = 'ietf-te-types:tunnel-admin-state-up'
+
+class OduTypeEnum(enum.Enum):
+    OSUFLEX = 'osuflex'
+
+def compose_osu_tunnel_endpoint(
+    node_id : str, tp_id : str, ttp_channel_name : str,
+    protection_role : EndpointProtectionRoleEnum = EndpointProtectionRoleEnum.WORK
+) -> Dict:
+    return {
+        'node-id': node_id, 'tp-id': tp_id, 'ttp-channel-name': ttp_channel_name,
+        'protection-role': protection_role.value
+    }
+
+def compose_osu_tunnel_te_bandwidth_odu(odu_type : OduTypeEnum, number : int) -> Dict:
+    return {'layer': 'odu', 'odu-type': odu_type.value, 'number': number}
+
+def compose_osu_tunnel_protection(
+    type_ : LspProtectionTypeEnum = LspProtectionTypeEnum.UNPROTECTED, reversion_disable : bool = True
+) -> Dict:
+    return {'protection-type': type_.value, 'protection-reversion-disable': reversion_disable}
+
+def compose_osu_tunnel_restoration(
+    type_ : LspRestorationTypeEnum = LspRestorationTypeEnum.NOT_APPLICABLE, restoration_lock : bool = False
+) -> Dict:
+    return {'restoration-type': type_.value, 'restoration-lock': restoration_lock}
+
+def compose_osu_tunnel(
+    name : str,
+    src_node_id : str, src_tp_id : str, src_ttp_channel_name : str,
+    dst_node_id : str, dst_tp_id : str, dst_ttp_channel_name : str,
+    odu_type : OduTypeEnum, osuflex_number : int,
+    delay : int, bidirectional : bool = True,
+    admin_state : TunnelAdminStateEnum = TunnelAdminStateEnum.UP
+) -> Dict:
+    return {'ietf-te:tunnel': [{
+        'name': name.lower(),
+        'title': name.upper(),
+        'admin-state': admin_state.value,
+        'delay': delay,
+        'te-bandwidth': compose_osu_tunnel_te_bandwidth_odu(odu_type, osuflex_number),
+        'bidirectional': bidirectional,
+        'source-endpoints': {'source-endpoint': [
+            compose_osu_tunnel_endpoint(src_node_id, src_tp_id, src_ttp_channel_name),
+        ]},
+        'destination-endpoints': {'destination-endpoint': [
+            compose_osu_tunnel_endpoint(dst_node_id, dst_tp_id, dst_ttp_channel_name),
+        ]},
+        'restoration': compose_osu_tunnel_restoration(),
+        'protection': compose_osu_tunnel_protection(),
+    }]}
+
+class OsuTunnel:
+    def __init__(self, base_url : str, auth : Optional[HTTPBasicAuth] = None, timeout : Optional[int] = None) -> None:
+        self._base_url = base_url
+        self._auth     = auth
+        self._timeout  = timeout
+
+    def get(self, resource_key : str) -> None:
+        url = '{:s}/restconf/data/tapi-common:context'.format(base_url)
+        result = []
+        try:
+            response = requests.get(url, timeout=timeout, verify=False, auth=auth)
+        except requests.exceptions.Timeout:
+            LOGGER.exception('Timeout connecting {:s}'.format(url))
+            return result
+        except Exception as e:  # pylint: disable=broad-except
+            LOGGER.exception('Exception retrieving {:s}'.format(resource_key))
+            result.append((resource_key, e))
+            return result
+
+        try:
+            context = json.loads(response.content)
+        except Exception as e:  # pylint: disable=broad-except
+            LOGGER.warning('Unable to decode reply: {:s}'.format(str(response.content)))
+            result.append((resource_key, e))
+            return result
+
+        if resource_key == RESOURCE_ENDPOINTS:
+            if 'tapi-common:context' in context:
+                context = context['tapi-common:context']
+            elif 'context' in context:
+                context = context['context']
+
+            for sip in context['service-interface-point']:
+                layer_protocol_name = sip.get('layer-protocol-name', '?')
+                supportable_spectrum = sip.get('tapi-photonic-media:media-channel-service-interface-point-spec', {})
+                supportable_spectrum = supportable_spectrum.get('mc-pool', {})
+                supportable_spectrum = supportable_spectrum.get('supportable-spectrum', [])
+                supportable_spectrum = supportable_spectrum[0] if len(supportable_spectrum) == 1 else {}
+                grid_type = supportable_spectrum.get('frequency-constraint', {}).get('grid-type')
+                granularity = supportable_spectrum.get('frequency-constraint', {}).get('adjustment-granularity')
+                direction = sip.get('direction', '?')
+
+                endpoint_type = [layer_protocol_name, grid_type, granularity, direction]
+                str_endpoint_type = ':'.join(filter(lambda i: operator.is_not(i, None), endpoint_type))
+                sip_uuid = sip['uuid']
+
+                sip_names = sip.get('name', [])
+                sip_name = next(iter([
+                    sip_name['value']
+                    for sip_name in sip_names
+                    if sip_name['value-name'] == 'local-name'
+                ]), sip_uuid)
+
+                endpoint_url = '/endpoints/endpoint[{:s}]'.format(sip_uuid)
+                endpoint_data = {'uuid': sip_uuid, 'name': sip_name, 'type': str_endpoint_type}
+                result.append((endpoint_url, endpoint_data))
+
+        elif resource_key == RESOURCE_SERVICES:
+            if 'tapi-common:context' in context:
+                context = context['tapi-common:context']
+            elif 'context' in context:
+                context = context['context']
+
+            if 'tapi-connectivity:connectivity-context' in context:
+                context = context['tapi-connectivity:connectivity-context']
+            elif 'connectivity-context' in context:
+                context = context['connectivity-context']
+
+            for conn_svc in context['connectivity-service']:
+                service_uuid = conn_svc['uuid']
+                constraints = conn_svc.get('connectivity-constraint', {})
+                total_req_cap = constraints.get('requested-capacity', {}).get('total-size', {})
+
+                service_url = '/services/service[{:s}]'.format(service_uuid)
+                service_data = {
+                    'uuid': service_uuid,
+                    'direction': constraints.get('connectivity-direction', 'UNIDIRECTIONAL'),
+                    'capacity_unit': total_req_cap.get('unit', '<UNDEFINED>'),
+                    'capacity_value': total_req_cap.get('value', '<UNDEFINED>'),
+                }
+
+                for i,endpoint in enumerate(conn_svc.get('end-point', [])):
+                    layer_protocol_name = endpoint.get('layer-protocol-name')
+                    if layer_protocol_name is not None:
+                        service_data['layer_protocol_name'] = layer_protocol_name
+
+                    layer_protocol_qualifier = endpoint.get('layer-protocol-qualifier')
+                    if layer_protocol_qualifier is not None:
+                        service_data['layer_protocol_qualifier'] = layer_protocol_qualifier
+
+                    sip = endpoint['service-interface-point']['service-interface-point-uuid']
+                    service_data['input_sip' if i == 0 else 'output_sip'] = sip
+
+                result.append((service_url, service_data))
+
+        return result
+
+    def update(self, resource_value : Dict) -> None:
+        name                 = resource_value['name'                ]
+        src_node_id          = resource_value['src_node_id'         ]
+        src_tp_id            = resource_value['src_tp_id'           ]
+        src_ttp_channel_name = resource_value['src_ttp_channel_name']
+        dst_node_id          = resource_value['dst_node_id'         ]
+        dst_tp_id            = resource_value['dst_tp_id'           ]
+        dst_ttp_channel_name = resource_value['dst_ttp_channel_name']
+        odu_type             = resource_value.get('odu_type',       OduTypeEnum.OSUFLEX.value)
+        osuflex_number       = resource_value.get('osuflex_number', 1                        )
+        delay                = resource_value.get('delay',          20                       )
+        bidirectional        = resource_value.get('bidirectional',  True                     )
+
+        odu_type = OduTypeEnum._value2member_map_[odu_type]
+
+        headers = {'content-type': 'application/json'}
+        data = compose_osu_tunnel(
+            name, src_node_id, src_tp_id, src_ttp_channel_name, dst_node_id, dst_tp_id, dst_ttp_channel_name,
+            odu_type, osuflex_number, delay, bidirectional=bidirectional
+        )
+
+        results = []
+        try:
+            LOGGER.info('OSU Tunnel {:s}: {:s}'.format(str(name), str(data)))
+            response = requests.post(
+                self._base_url, data=json.dumps(data), timeout=self._timeout,
+                headers=headers, verify=False, auth=self._auth
+            )
+            LOGGER.info('Response: {:s}'.format(str(response)))
+        except Exception as e:  # pylint: disable=broad-except
+            LOGGER.exception('Exception creating OsuTunnel(name={:s}, data={:s})'.format(str(name), str(data)))
+            results.append(e)
+        else:
+            if response.status_code not in HTTP_OK_CODES:
+                msg = 'Could not create OsuTunnel(name={:s}, data={:s}). status_code={:s} reply={:s}'
+                LOGGER.error(msg.format(str(name), str(data), str(response.status_code), str(response)))
+            results.append(response.status_code in HTTP_OK_CODES)
+        return results
+
+    def delete(self, osu_tunnel_name : str) -> List[]:
+        url = '{:s}[name={:s}]'.format(self._base_url, osu_tunnel_name)
+        results = []
+        try:
+            response = requests.delete(url=url, timeout=self._timeout, verify=False, auth=self._auth)
+        except Exception as e:  # pylint: disable=broad-except
+            LOGGER.exception('Exception deleting OsuTunnel(name={:s})'.format(str(osu_tunnel_name)))
+            results.append(e)
+        else:
+            if response.status_code not in HTTP_OK_CODES:
+                msg = 'Could not delete OsuTunnel(name={:s}). status_code={:s} reply={:s}'
+                LOGGER.error(msg.format(str(osu_tunnel_name), str(response.status_code), str(response)))
+            results.append(response.status_code in HTTP_OK_CODES)
+        return results
diff --git a/src/device/service/drivers/ietf_actn/handlers/Tools.py b/src/device/service/drivers/ietf_actn/handlers/Tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..c14c65afab4001fa5c3935d1a7ef4893d43342bc
--- /dev/null
+++ b/src/device/service/drivers/ietf_actn/handlers/Tools.py
@@ -0,0 +1,20 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# 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.
+
+HTTP_OK_CODES = {
+    200,    # OK
+    201,    # Created
+    202,    # Accepted
+    204,    # No Content
+}
diff --git a/src/device/service/drivers/ietf_actn/ComposerEthService.py b/src/device/service/drivers/ietf_actn/handlers/__init__.py
similarity index 99%
rename from src/device/service/drivers/ietf_actn/ComposerEthService.py
rename to src/device/service/drivers/ietf_actn/handlers/__init__.py
index 1549d9811aa5d1c193a44ad45d0d7773236c0612..38d04994fb0fa1951fb465bc127eb72659dc2eaf 100644
--- a/src/device/service/drivers/ietf_actn/ComposerEthService.py
+++ b/src/device/service/drivers/ietf_actn/handlers/__init__.py
@@ -11,4 +11,3 @@
 # 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.
-