diff --git a/proto/context.proto b/proto/context.proto
index 27d0cdafd41ac346eddb8a57747318abc07ae25a..685c757937d82cafe662e383d8cf30cbb677930b 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -665,6 +665,8 @@ message AuthenticationResult {
   bool authenticated = 2;
 }
 
+
+
 // ---------------- Experimental ------------------------
 message OpticalConfigId {
   string opticalconfig_uuid = 1;
@@ -685,6 +687,8 @@ message OpticalConfigEvent {
 }
 
 
+
+
 // ---- Optical Link ----
 
 message OpticalEndPointId {
@@ -719,6 +723,29 @@ message OpticalLink {
 }
 
 
+message ChannelId {
+  Uuid channel_uuid = 1;
+}
+
+message OpticalBandId {
+  Uuid opticalband_uuid = 1;
+}
+
+
+message OpticalBand {
+  
+   OpticalBandId opticalband_id = 1 ; 
+   ConnectionId connection_id =2 ; 
+    ChannelId channel_id = 3;
+    ServiceId service_id =4;
+
+}
+
+message OpticalBandList {
+   repeated OpticalBand opticalbands =1 ;
+
+}
+
 
 ////////////////// Config Rule Delete ////////////
 
diff --git a/src/common/tools/descriptor/Loader.py b/src/common/tools/descriptor/Loader.py
index 4a5fc37dbfe216db194bf760b1a8f8f1e6f543d1..3ddc34f8039fc7c9201aa772814b387f9558c494 100644
--- a/src/common/tools/descriptor/Loader.py
+++ b/src/common/tools/descriptor/Loader.py
@@ -509,6 +509,7 @@ class DescriptorLoader:
             self._unload_normal_mode()
 
 def compose_notifications(results : TypeResults) -> TypeNotificationList:
+
     notifications = []
     for entity_name, action_name, num_ok, error_list in results:
         entity_name_singluar,entity_name_plural = ENTITY_TO_TEXT[entity_name]
diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py
index b8eed67aa8ceee4e043aa0c654b6287cb2ebbf10..d3513c36a0f79a82b92669b42eb8fffd53e69c52 100644
--- a/src/context/client/ContextClient.py
+++ b/src/context/client/ContextClient.py
@@ -27,7 +27,8 @@ from common.proto.context_pb2 import (
     OpticalConfig, OpticalConfigId, OpticalConfigList , OpticalLink, OpticalLinkList,
     Service, ServiceConfigRule, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList,
     Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList,
-    Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList,
+    Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList,OpticalBand ,OpticalBandId,
+    OpticalBandList
 )
 from common.proto.context_pb2_grpc import ContextServiceStub
 from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub
@@ -484,6 +485,21 @@ class ContextClient:
         LOGGER.debug('DeleteOpticalChannel result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
     
+    
+    @RETRY_DECORATOR
+    def GetOpticalBand(self, request : Empty) -> OpticalBandList:
+        LOGGER.debug('GetOpticalBand request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetOpticalBand(request)
+        LOGGER.debug('GetOpticalBand result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def SetOpticalBand(self,request : OpticalBand) -> Empty:
+        LOGGER.debug('SetOpticalBand request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.SetOpticalBand(request)
+        LOGGER.debug('SetOpticalBand result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+    
     #--------------------------- Optical Link ------------------------
     def GetOpticalLinkList(self, request: Empty) -> OpticalLinkList:
         LOGGER.debug('ListOpticalLinks request: {:s}'.format(grpc_message_to_json_string(request)))
diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py
index fa6b6a34f1cb3d4be8b61859e98a33b92b884bff..d789b7863a4b4fc0635008a3a5d46eb7f88be03f 100644
--- a/src/context/service/ContextServiceServicerImpl.py
+++ b/src/context/service/ContextServiceServicerImpl.py
@@ -25,7 +25,7 @@ from common.proto.context_pb2 import (
     Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList,
     Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList,
     OpticalConfigList, OpticalConfigId, OpticalConfig, OpticalLink, OpticalLinkList,
-    ServiceConfigRule
+    ServiceConfigRule,OpticalBand,OpticalBandId,OpticalBandList
 )
 from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule
 from common.proto.context_pb2_grpc import ContextServiceServicer
@@ -69,6 +69,10 @@ from .database.OpticalLink import (
     optical_link_delete, optical_link_get, optical_link_list_objs, optical_link_set
 )
 from .database.ConfigRule import delete_config_rule
+from .database.OpticalBand import ( 
+                                   get_optical_band,set_optical_band
+                                   )
+
 LOGGER = logging.getLogger(__name__)
 
 METRICS_POOL = MetricsPool('Context', 'RPC')
@@ -357,6 +361,17 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer
     def DeleteOpticalChannel(self, request : OpticalConfig, context : grpc.ServicerContext) -> Empty:
         delete_opticalchannel(self.db_engine, self.messagebroker, request)
         return Empty()
+    
+    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+    def GetOpticalBand(self, request : Empty, context : grpc.ServicerContext) -> OpticalBandList:
+        result = get_optical_band(self.db_engine)
+        return OpticalBandList(opticalbands=result)
+
+    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
+    def SetOpticalBand(self, request : OpticalBand, context : grpc.ServicerContext) -> Empty:
+        result = set_optical_band(self.db_engine, request)
+        return Empty()
+
 
     #--------------------- Experimental Optical Link -------------------
 
diff --git a/src/context/service/database/OpticalBand.py b/src/context/service/database/OpticalBand.py
new file mode 100644
index 0000000000000000000000000000000000000000..75c4e029c7e9f4405bc9e1d332bbfbb515c3ce91
--- /dev/null
+++ b/src/context/service/database/OpticalBand.py
@@ -0,0 +1,54 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (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 logging
+from sqlalchemy.engine import Engine
+from sqlalchemy.orm import Session, selectinload, sessionmaker
+from sqlalchemy_cockroachdb import run_transaction
+from sqlalchemy.dialects.postgresql import insert
+
+from typing import Dict, List
+from common.proto.context_pb2 import OpticalBand,OpticalBandId,OpticalBandList
+from .models.OpticalConfig.OpticalBandModel import OpticalBandModel
+
+
+LOGGER = logging.getLogger(__name__)
+
+
+
+def get_optical_band(db_engine : Engine):
+    def callback(session:Session):
+        results = session.query(OpticalBandModel).all()
+        
+        return {"opticalbands":[obj.dump_id() for obj in results]}
+    obj = run_transaction(sessionmaker(bind=db_engine), callback)
+    return obj
+
+
+def set_optical_band(db_engine : Engine, ob_data ):
+  
+    def callback(session : Session) -> List[Dict]:
+        if len(ob_data) > 0:
+                stmt = insert(OpticalBandModel).values(ob_data)
+                stmt = stmt.on_conflict_do_update(
+                    index_elements=[OpticalBandModel.ob_uuid],
+                    set_=dict(
+                        connection_uuid = stmt.excluded.connection_uuid
+                    )
+                )
+                stmt = stmt.returning(OpticalBandModel.ob_uuid)
+                ob_id = session.execute(stmt).fetchone()
+                
+    ob_id = run_transaction(sessionmaker(bind=db_engine), callback)
+    return {'ob_id': ob_id}            
diff --git a/src/context/service/database/OpticalConfig.py b/src/context/service/database/OpticalConfig.py
index 2876ff073e155e2cf0573ab0f7daa6812e7d2f8d..583b2d2c9209317dced20f3c5ac08d837a8f7eaa 100644
--- a/src/context/service/database/OpticalConfig.py
+++ b/src/context/service/database/OpticalConfig.py
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json, logging
+import json, logging ,datetime
 from sqlalchemy.dialects.postgresql import insert
 from common.message_broker.MessageBroker import MessageBroker
 from common.DeviceTypes import DeviceTypeEnum
@@ -25,11 +25,12 @@ from .models.OpticalConfig.TransponderModel import  TransponderTypeModel, Optica
 from .models.OpticalConfig.RoadmModel import RoadmTypeModel, ChannelModel, ORInterfaceModel
 from context.service.database.uuids.OpticalConfig import (
     channel_get_uuid , opticalconfig_get_uuid ,transponder_get_uuid,roadm_get_uuid,
-    interface_get_uuid
+    interface_get_uuid , ob_get_uuid
 )
 from .Events import notify_event_opticalconfig
-
+from .OpticalBand import set_optical_band
 LOGGER = logging.getLogger(__name__)
+now = datetime.datetime.utcnow()
 
 def get_opticalconfig(db_engine : Engine):
     def callback(session:Session):
@@ -285,9 +286,11 @@ def update_opticalconfig(db_engine : Engine, request : OpticalConfig):
     channel_namespace = None
     OpticalConfig_data = []
     config_type = None
+    optical_bands = []
     #is_transpondre = False
     opticalconfig_uuid = opticalconfig_get_uuid(device_id)
-
+    is_optical_band=None
+    LOGGER.info(f"update_opticalconfig {request}")
     if request.config :
         config = json.loads(request.config)
 
@@ -357,6 +360,7 @@ def update_opticalconfig(db_engine : Engine, request : OpticalConfig):
                 if channel_namespace is None and  'channel_namespace' in config['new_config']:
                     channel_namespace=config['new_config']['channel_namespace']
                 if 'is_opticalband' in config and not config['is_opticalband']:
+                    is_optical_band=config['is_opticalband']
                     #channels = [channel['name']['index'] for channel in config['channels']]
                     if 'flow_handled' in config  and len(config['flow_handled'])>0 :
                         num = 0    
@@ -380,7 +384,9 @@ def update_opticalconfig(db_engine : Engine, request : OpticalConfig):
                                 "channel_index"       : str(channel_index) if channel_index is not None else None
                             })
                 if 'is_opticalband' in config and config['is_opticalband']:
+                    is_optical_band=config['is_opticalband']
                     #channels = [channel['name']['index'] for channel in config['channels']]
+                    
                     if 'flow_handled' in config and len(config['flow_handled']) > 0:
                         ob_id = config['new_config']['ob_id'] if 'ob_id' in config['new_config'] else None
                         num = 0
@@ -401,6 +407,13 @@ def update_opticalconfig(db_engine : Engine, request : OpticalConfig):
                                 "type"            : 'optical_band',
                                 "channel_index"   : str( channel_index) if channel_index is not None else None
                             })
+                            optical_bands.append ({
+                                 "channel_uuid"    : channel_get_uuid(f'optical_bands_{channel_index}',device_uuid),
+                                 'connection_uuid' : config['connection_uuid'],
+                                 "ob_uuid" : ob_get_uuid (f'ob_{channel_index}' ),
+                                 'created_at':now
+                                 
+                            })
 
                 roadms.append({
                     "roadm_uuid"        : roadm_get_uuid(device_id),
@@ -481,8 +494,10 @@ def update_opticalconfig(db_engine : Engine, request : OpticalConfig):
                 )
                 stmt = stmt.returning(ChannelModel.channel_uuid)
                 opticalChannel_id = session.execute(stmt).fetchone()
-
+               
     opticalconfig_id = run_transaction(sessionmaker(bind=db_engine), callback)
+    if is_optical_band: set_optical_band(db_engine,optical_bands)
+
     return {'opticalconfig_uuid': opticalconfig_id}
 
 def select_opticalconfig(db_engine : Engine, request : OpticalConfigId):
diff --git a/src/context/service/database/models/OpticalConfig/OpticalBandModel.py b/src/context/service/database/models/OpticalConfig/OpticalBandModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..0e3351388d623c96b68f164b2d89a5ea40256b16
--- /dev/null
+++ b/src/context/service/database/models/OpticalConfig/OpticalBandModel.py
@@ -0,0 +1,47 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (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 json, logging, operator
+from sqlalchemy import Column, DateTime, ForeignKey, Integer, CheckConstraint, String
+from sqlalchemy.dialects.postgresql import UUID
+from sqlalchemy.orm import relationship
+from typing import Dict
+from context.service.database.models._Base import _Base
+
+LOGGER = logging.getLogger(__name__)
+
+class OpticalBandModel(_Base):
+    __tablename__ = 'opticalband'
+
+    ob_uuid = Column(UUID(as_uuid=False), primary_key=True)
+    connection_uuid    = Column(ForeignKey('connection.connection_uuid', ondelete='RESTRICT'), nullable=False)
+    channel_uuid    = Column(ForeignKey('channel.channel_uuid', ondelete='RESTRICT'), nullable=False)
+    
+    created_at      = Column(DateTime, nullable=False)
+
+
+    ob_channel    = relationship('ChannelModel') # back_populates='connections'
+    ob_connection   = relationship('ConnectionModel') # lazy='joined', back_populates='connection'
+   
+    def dump_id(self) -> Dict:
+        return {'opticalband_uuid': {'uuid': self.ob_uuid}}
+
+    def dump(self) -> Dict:
+        return {
+            'opticalband_id'          : self.dump_id(),
+            'channel_id'              : self.ob_channel.dump_id(),
+            'connection_id'           : self.ob_connection.dump_id(),
+            'service_id'              : self.ob_connection.connection_service.dump_id()
+        }
+
diff --git a/src/context/service/database/uuids/OpticalConfig.py b/src/context/service/database/uuids/OpticalConfig.py
index a23c1370e2541f8bfc5decf8c746543ec85c1f5e..e11f835975fca86aba9e02eb6bbc15c6598627bb 100644
--- a/src/context/service/database/uuids/OpticalConfig.py
+++ b/src/context/service/database/uuids/OpticalConfig.py
@@ -15,6 +15,7 @@
 from common.method_wrappers.ServiceExceptions import InvalidArgumentsException
 from common.proto.context_pb2 import DeviceId
 from ._Builder import get_uuid_from_string, get_uuid_random
+import logging
 
 def channel_get_uuid(
     channel_name : str , device_id : str, allow_random : bool = False
@@ -73,3 +74,20 @@ def opticalconfig_get_uuid(
     raise InvalidArgumentsException([
         ('DeviceId ', device_id),
     ], extra_details=['device_id is required to produce a OpticalConfig UUID'])
+
+
+def ob_get_uuid(
+    ob_name:str , allow_random : bool = False
+) -> str:
+   
+    if ( ob_name is not None):
+        
+        
+      result = get_uuid_from_string(ob_name)
+      logging.info(f'get_ob_uuid {result}')
+      return result 
+    if allow_random: return get_uuid_random()
+
+    raise InvalidArgumentsException([
+        ('ob_name ', ob_name),
+    ], extra_details=['ob_name is required to produce a Optical band UUID'])
diff --git a/src/device/service/drivers/oc_driver/OCDriver.py b/src/device/service/drivers/oc_driver/OCDriver.py
index bfc84bf1a9b95f8b4f5c1e935b23e5bdde2136d4..5fede091ff6d9f2057d05582a810b5f8e73d60cf 100644
--- a/src/device/service/drivers/oc_driver/OCDriver.py
+++ b/src/device/service/drivers/oc_driver/OCDriver.py
@@ -68,7 +68,7 @@ class NetconfSessionHandler:
         self.__port = int(port)
         self.__username         = settings.get('username')
         self.__password         = settings.get('password')
-        self.__vendor           = settings.get('vendor')
+        self.__vendor           = settings.get('vendor',None)
         self.__version          = settings.get('version', "1")
         self.__key_filename     = settings.get('key_filename')
         self.__hostkey_verify   = settings.get('hostkey_verify', True)
@@ -155,117 +155,121 @@ def edit_config(
     str_method = 'DeleteConfig' if delete else 'SetConfig'
     results = []
 
-    logging.info(f"commmit per rule {commit_per_rule}")
+   
     str_config_messages=[]
-    if str_method == 'SetConfig':
-        if (conditions['edit_type']=='optical-channel'):
-            #transponder
-            str_config_messages =  edit_optical_channel(resources)
-        elif (conditions['edit_type']=='optical-band'):
-            #roadm optical-band
-            str_config_messages = create_optical_band(resources)
-        elif (conditions['edit_type']=='network-media-channel'):
-            commit_per_rule=True
-            #openroadm network media channel
-            str_config_messages = network_media_channel_handler(resources)       
-        else :
-            #roadm media-channel
-            str_config_messages=create_media_channel_v2(resources)
-    #Disabling of the Configuration         
-    else:
-        # Device type is Transponder
-        if (conditions['edit_type'] == "optical-channel"):
-            _,ports,_=seperate_port_config(resources)
-            str_config_messages=change_optical_channel_status(state="DISABLED",ports=ports)
-            
-        #  Device type is Roadm     
-        elif (conditions['edit_type']=='optical-band'):    
-            str_config_messages=delete_optical_band(resources)
-        else :
-            str_config_messages=disable_media_channel(resources)
-
-    for str_config_message in str_config_messages:  
-        # configuration of the received templates 
-        if str_config_message is None: raise UnsupportedResourceKeyException("CONFIG")
-        result= netconf_handler.edit_config(                                                                               # configure the device
-            config=str_config_message, target=target, default_operation=default_operation,
-            test_option=test_option, error_option=error_option, format=format)
-        if commit_per_rule:
-            netconf_handler.commit()                                                                               # configuration commit
-
-        #results[i] = True
-            results.append(result)
-    
-    if netconf_handler.vendor == "CISCO":
-        if "L2VSI" in resources[0][1]:
+    if netconf_handler.vendor is None : 
+        if str_method == 'SetConfig':
+            if (conditions['edit_type']=='optical-channel'):
+                #transponder
+                str_config_messages =  edit_optical_channel(resources)
+            elif (conditions['edit_type']=='optical-band'):
+                #roadm optical-band
+                str_config_messages = create_optical_band(resources)
+            elif (conditions['edit_type']=='network-media-channel'):
+                commit_per_rule=True
+                #openroadm network media channel
+                str_config_messages = network_media_channel_handler(resources)       
+            else :
+                #roadm media-channel
+                str_config_messages=create_media_channel_v2(resources)
+        #Disabling of the Configuration         
+        else:
+            # Device type is Transponder
+            if (conditions['edit_type'] == "optical-channel"):
+                _,ports,_=seperate_port_config(resources)
+                str_config_messages=change_optical_channel_status(state="DISABLED",ports=ports)
+                
+            #  Device type is Roadm     
+            elif (conditions['edit_type']=='optical-band'):    
+                str_config_messages=delete_optical_band(resources)
+            else :
+                str_config_messages=disable_media_channel(resources)
+        
+        logging.info(f"edit_template : {str_config_messages}") 
+                
+        for str_config_message in str_config_messages:  
+            # configuration of the received templates 
+            if str_config_message is None: raise UnsupportedResourceKeyException("CONFIG")
+            result= netconf_handler.edit_config(                                                                               # configure the device
+                config=str_config_message, target=target, default_operation=default_operation,
+                test_option=test_option, error_option=error_option, format=format)
+            if commit_per_rule:
+                netconf_handler.commit()                                                                               # configuration commit
+
+            #results[i] = True
+                results.append(result)
+               
+    else : 
+        if netconf_handler.vendor == "CISCO":
+            if "L2VSI" in resources[0][1]:
+                #Configure by CLI
+                logger.warning("CLI Configuration")
+                cli_compose_config(resources, 
+                                delete=delete, 
+                                host= netconf_handler._NetconfSessionHandler__address, 
+                                user=netconf_handler._NetconfSessionHandler__username, 
+                                passw=netconf_handler._NetconfSessionHandler__password)        
+                for i,resource in enumerate(resources):
+                    results.append(True)
+            else: 
+                logger.warning("CLI Configuration CISCO INTERFACE")
+                cisco_interface(resources, 
+                                delete=delete,
+                                host= netconf_handler._NetconfSessionHandler__address
+                                , user=netconf_handler._NetconfSessionHandler__username,
+                                passw=netconf_handler._NetconfSessionHandler__password)        
+                for i,resource in enumerate(resources):
+                    results.append(True)
+        elif netconf_handler.vendor == "UFISPACE": 
             #Configure by CLI
-            logger.warning("CLI Configuration")
-            cli_compose_config(resources, 
-                               delete=delete, 
-                               host= netconf_handler._NetconfSessionHandler__address, 
-                               user=netconf_handler._NetconfSessionHandler__username, 
-                               passw=netconf_handler._NetconfSessionHandler__password)        
+            logger.warning("CLI Configuration: {:s}".format(resources))
+            ufi_interface(resources, 
+                        delete=delete, 
+                        host= netconf_handler._NetconfSessionHandler__address,
+                        user=netconf_handler._NetconfSessionHandler__username,
+                        passw=netconf_handler._NetconfSessionHandler__password)        
             for i,resource in enumerate(resources):
                 results.append(True)
-        else: 
-            logger.warning("CLI Configuration CISCO INTERFACE")
-            cisco_interface(resources, 
-                            delete=delete,
-                            host= netconf_handler._NetconfSessionHandler__address
-                            , user=netconf_handler._NetconfSessionHandler__username,
-                            passw=netconf_handler._NetconfSessionHandler__password)        
+        else:
             for i,resource in enumerate(resources):
-                results.append(True)
-    elif netconf_handler.vendor == "UFISPACE": 
-        #Configure by CLI
-        logger.warning("CLI Configuration: {:s}".format(resources))
-        ufi_interface(resources, 
-                      delete=delete, 
-                      host= netconf_handler._NetconfSessionHandler__address,
-                      user=netconf_handler._NetconfSessionHandler__username,
-                      passw=netconf_handler._NetconfSessionHandler__password)        
-        for i,resource in enumerate(resources):
-            results.append(True)
-    else:
-        for i,resource in enumerate(resources):
-            str_resource_name = 'resources[#{:d}]'.format(i)
-            try:
-                logger.debug('[{:s}] resource = {:s}'.format(str_method, str(resource)))
-                chk_type(str_resource_name, resource, (list, tuple))
-                chk_length(str_resource_name, resource, min_length=2, max_length=2)
-                resource_key,resource_value = resource
-                chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
-                str_config_messages = compose_config(                                                                          # get template for configuration
-                    resource_key, resource_value, delete=delete, vendor=netconf_handler.vendor, message_renderer=netconf_handler.message_renderer)
-                for str_config_message in str_config_messages:                                                                 # configuration of the received templates 
-                    if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
-                    logger.debug('[{:s}] str_config_message[{:d}] = {:s}'.format(
-                    str_method, len(str_config_message), str(str_config_message)))
-                    netconf_handler.edit_config(                                                                               # configure the device
-                        config=str_config_message, target=target, default_operation=default_operation,
-                        test_option=test_option, error_option=error_option, format=format)
-                    if commit_per_rule:
-                        netconf_handler.commit()                                                                               # configuration commit
-                    if 'table_connections' in resource_key:
-                        time.sleep(5) # CPU usage might exceed critical level after route redistribution, BGP daemon needs time to reload
-                
-                #results[i] = True
-                results.append(True)
-            except Exception as e: # pylint: disable=broad-except
-                str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
-                msg = '[{:s}] Exception {:s} {:s}: {:s}'
-                logger.exception(msg.format(str_method, str_operation, str_resource_name, str(resource)))
-                #results[i] = e # if validation fails, store the exception
-                results.append(e)
-
-        if not commit_per_rule:
-            try:
-                netconf_handler.commit()
-            except Exception as e: # pylint: disable=broad-except
-                msg = '[{:s}] Exception committing: {:s}'
-                str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
-                logger.exception(msg.format(str_method, str_operation, str(resources)))
-                results = [e for _ in resources] # if commit fails, set exception in each resource
+                str_resource_name = 'resources[#{:d}]'.format(i)
+                try:
+                    logger.debug('[{:s}] resource = {:s}'.format(str_method, str(resource)))
+                    chk_type(str_resource_name, resource, (list, tuple))
+                    chk_length(str_resource_name, resource, min_length=2, max_length=2)
+                    resource_key,resource_value = resource
+                    chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
+                    str_config_messages = compose_config(                                                                          # get template for configuration
+                        resource_key, resource_value, delete=delete, vendor=netconf_handler.vendor, message_renderer=netconf_handler.message_renderer)
+                    for str_config_message in str_config_messages:                                                                 # configuration of the received templates 
+                        if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
+                        logger.debug('[{:s}] str_config_message[{:d}] = {:s}'.format(
+                        str_method, len(str_config_message), str(str_config_message)))
+                        netconf_handler.edit_config(                                                                               # configure the device
+                            config=str_config_message, target=target, default_operation=default_operation,
+                            test_option=test_option, error_option=error_option, format=format)
+                        if commit_per_rule:
+                            netconf_handler.commit()                                                                               # configuration commit
+                        if 'table_connections' in resource_key:
+                            time.sleep(5) # CPU usage might exceed critical level after route redistribution, BGP daemon needs time to reload
+                    
+                    #results[i] = True
+                    results.append(True)
+                except Exception as e: # pylint: disable=broad-except
+                    str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
+                    msg = '[{:s}] Exception {:s} {:s}: {:s}'
+                    logger.exception(msg.format(str_method, str_operation, str_resource_name, str(resource)))
+                    #results[i] = e # if validation fails, store the exception
+                    results.append(e)
+
+            if not commit_per_rule:
+                try:
+                    netconf_handler.commit()
+                except Exception as e: # pylint: disable=broad-except
+                    msg = '[{:s}] Exception committing: {:s}'
+                    str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
+                    logger.exception(msg.format(str_method, str_operation, str(resources)))
+                    results = [e for _ in resources] # if commit fails, set exception in each resource
 
     return results         
 
diff --git a/src/device/service/drivers/oc_driver/templates/VPN/roadms.py b/src/device/service/drivers/oc_driver/templates/VPN/roadms.py
index e5362f48243dbca9bb2b439855e2d8ed84f14eee..f3befa00137f6fc846ccabfe380ae41dcf22d5c7 100644
--- a/src/device/service/drivers/oc_driver/templates/VPN/roadms.py
+++ b/src/device/service/drivers/oc_driver/templates/VPN/roadms.py
@@ -156,7 +156,7 @@ def create_media_channel_v2 (resources):
                                         if resource['resource_key'] == "index":
                                             with tag('index'):text(str(int(index)+n))
                                         elif resource['resource_key']== 'optical-band-parent'    :
-                                            with tag('optical-band-parent',xmlns=optical_band_namespaces):text(int(resource['value'])+int(n))
+                                            with tag('optical-band-parent',xmlns=optical_band_namespaces):text(int(resource['value']))
                                         elif resource['resource_key']== 'admin-state'    :
                                             with tag('admin-status'):text(resource['value'])
                                         else:
diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py
index 9120d475b8b2bb88bfcf7d7da3cadba2bf9931e4..ba43bdbc8635959d843f164ce02c6509001b2baf 100644
--- a/src/service/service/ServiceServiceServicerImpl.py
+++ b/src/service/service/ServiceServiceServicerImpl.py
@@ -312,7 +312,7 @@ class ServiceServiceServicerImpl(ServiceServiceServicer):
                     devices, _service, reply_json, context_uuid_x, topology_uuid_x, optical_band_txt
                 )
 
-                tasks_scheduler.compose_from_pathcompreply(
+                tasks_scheduler.compose_from_opticalcontroller_reply(
                     optical_reply, is_delete=False)
         else:
             if len(service_with_uuids.service_endpoint_ids) >= num_expected_endpoints:
diff --git a/src/service/service/service_handler_api/_ServiceHandler.py b/src/service/service/service_handler_api/_ServiceHandler.py
index 9e90ade1da362b0d4f5bb043541bf96cd26a985d..f8ef8d55188b9f7f9ae87b36444e6f23caad31d3 100644
--- a/src/service/service/service_handler_api/_ServiceHandler.py
+++ b/src/service/service/service_handler_api/_ServiceHandler.py
@@ -150,3 +150,25 @@ class _ServiceHandler:
                     the processing must be returned.
         """
         raise NotImplementedError()
+    
+    
+    def SetOpticalConfig (
+        self, endpoints : List[Tuple[str, str, Optional[str]]],
+        connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]: 
+        
+          """ Create/Update Optical configuration related to optical service.
+            Parameters:
+                endpoints: List[Tuple[str, str, Optional[str]]]
+                    List of tuples, each containing a device_uuid,
+                    endpoint_uuid and, optionally, the topology_uuid
+                    of the endpoint to be added.
+                connection_uuid : Optional[str]
+                    If specified, is the UUID of the connection this endpoint is associated to.
+            Returns:
+                results: List[Union[bool, Exception]]
+                    List of results for configurations changes requested. 
+                    Return values must be in the same order as the requested
+                    configurtations.   
+        """
+        
diff --git a/src/service/service/service_handlers/oc/OCServiceHandler.py b/src/service/service/service_handlers/oc/OCServiceHandler.py
index 49212d1aa5e82097627709dc77fe6d99914b6d98..1f2211e094f980ecf14bb65fbc576aa131020a21 100644
--- a/src/service/service/service_handlers/oc/OCServiceHandler.py
+++ b/src/service/service/service_handlers/oc/OCServiceHandler.py
@@ -48,26 +48,7 @@ class OCServiceHandler(_ServiceHandler):
    
         chk_type('endpoints', endpoints, list)
         if len(endpoints) == 0: return []
-        is_opticalband =False
-        #service_uuid = self.__service.service_id.service_uuid.uuid
-        settings=None
-       
-        if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)):
-            is_opticalband=True
-            settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid))
-        else:
-            settings = self.__settings_handler.get('/settings')
-       
-        bidir = settings.value.get("bidir")
-        LOGGER.debug(f"Bidir bvalue is: {bidir}")
-        # settings = self.__settings_handler.get('/settings')
-
-        #flow is the new variable that stores input-output relationship
-        flows = convert_endpoints_to_flows(endpoints)
-        LOGGER.info(f"endpoints {endpoints} is_opticalband {is_opticalband} ")
-        #flows = endpoints_to_flows(endpoints, bidir, is_opticalband)
-        #handled_flows=handle_flows_names(flows=flows,task_executor=self.__task_executor)
-
+    
         results = []
         for endpoint in endpoints:
             try:
@@ -91,16 +72,50 @@ class OCServiceHandler(_ServiceHandler):
                 LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint)))
                 results.append(e)
 
-        LOGGER.info(f"flows {flows} ")
-        LOGGER.info(f"settings {settings} ")
+
+        return results
+    
+    
+    @metered_subclass_method(METRICS_POOL)
+    def SetOpticalConfig(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
+        
+        LOGGER.info(f"endpoints {endpoints}  ")
+   
+        chk_type('endpoints', endpoints, list)
+        if len(endpoints) == 0: return []
+        is_opticalband =False
+        #service_uuid = self.__service.service_id.service_uuid.uuid
+        settings=None
+       
+        if self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid)):
+            is_opticalband=True
+            settings = self.__settings_handler.get('/settings-ob_{}'.format(connection_uuid))
+        else:
+            settings = self.__settings_handler.get('/settings')
+       
+        bidir = settings.value.get("bidir")
+        LOGGER.debug(f"Bidir bvalue is: {bidir}")
+        # settings = self.__settings_handler.get('/settings')
+
+        #flow is the new variable that stores input-output relationship
+        flows = convert_endpoints_to_flows(endpoints)
+        LOGGER.info(f"endpoints {endpoints} is_opticalband {is_opticalband} ")
+        #flows = endpoints_to_flows(endpoints, bidir, is_opticalband)
+        #handled_flows=handle_flows_names(flows=flows,task_executor=self.__task_executor)
+
+        results = []
+        
         
         #new cycle for setting optical devices
         for device_uuid, dev_flows in flows.items():
             try:
                 device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
                 LOGGER.info(f"device {device_obj.name} ")
-                if settings:
-                    self.__task_executor.configure_optical_device(device_obj, settings, dev_flows, is_opticalband)
+                if settings is not None:
+                    self.__task_executor.configure_optical_device(device_obj, settings, dev_flows
+                                                                  , is_opticalband ,connection_uuid)
                 results.append(True)
             except Exception as e: # pylint: disable=broad-except
                 LOGGER.exception('Unable to configure Device({:s})'.format(str(device_uuid)))
@@ -108,6 +123,7 @@ class OCServiceHandler(_ServiceHandler):
 
         return results
 
+
     @metered_subclass_method(METRICS_POOL)
     def DeleteEndpoint(
         self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
diff --git a/src/service/service/task_scheduler/TaskExecutor.py b/src/service/service/task_scheduler/TaskExecutor.py
index 6fb1eca3497fef311605e2cd202ca74bd9cb730f..5391eca4883771fde998c838bc5f698b43ef0bfe 100644
--- a/src/service/service/task_scheduler/TaskExecutor.py
+++ b/src/service/service/task_scheduler/TaskExecutor.py
@@ -127,7 +127,8 @@ class TaskExecutor:
     
     # New function Andrea for Optical Devices
     def configure_optical_device(
-        self, device : Device, settings : str, flows : list, is_opticalband : bool
+        self, device : Device, settings : str, flows : list, is_opticalband : bool,
+        connection_uuid:str
     ):
         device_key = get_device_key(device.device_id)
         optical_config_id = OpticalConfigId()
@@ -142,6 +143,7 @@ class TaskExecutor:
             result = self._context_client.SelectOpticalConfig(optical_config_id)
 
             new_config = json.loads(result.config)
+            if is_opticalband : new_config['connection_uuid']=connection_uuid
             if 'type' in new_config:
                 config_type=new_config['type']
             if config_type == 'optical-transponder':
@@ -292,6 +294,12 @@ class TaskExecutor:
                 device_type = DeviceTypeEnum._value2member_map_[controller.device_type]
                 devices.setdefault(device_type, dict())[controller.device_id.device_uuid.uuid] = controller
         return devices
+    
+    
+    def set_optical_band(self, connection : ConnectionId,device:DeviceId) -> None:
+        device_key = get_device_key(device.device_id)
+        self._device_client.ConfigureDevice(device)
+        self._store_grpc_object(CacheableObjectType.DEVICE, device_key, device)
 
     # ----- Service-related methods ------------------------------------------------------------------------------------
 
diff --git a/src/service/service/task_scheduler/TaskScheduler.py b/src/service/service/task_scheduler/TaskScheduler.py
index e849e855f9d91c2dc51a99237bcfa389dc0b414d..9017149d653a6508d3f3dfeeb61955249bf14ab4 100644
--- a/src/service/service/task_scheduler/TaskScheduler.py
+++ b/src/service/service/task_scheduler/TaskScheduler.py
@@ -23,7 +23,9 @@ from context.client.ContextClient import ContextClient
 from service.service.tools.ObjectKeys import get_connection_key, get_service_key
 from .tasks._Task import _Task
 from .tasks.Task_ConnectionConfigure import Task_ConnectionConfigure
+from .tasks.Task_OpticalConnectionConfigure import Task_OpticalConnectionConfigure
 from .tasks.Task_OpticalConnectionDeconfigure import Task_OpticalConnectionDeconfigure
+
 from .tasks.Task_OpticalServiceDelete import Task_OpticalServiceDelete
 from .tasks.Task_ConnectionDeconfigure import Task_ConnectionDeconfigure
 from .tasks.Task_ServiceDelete import Task_ServiceDelete
@@ -85,6 +87,19 @@ class TasksScheduler:
         # deleting a service requires the service is in removing state
         self._dag.add(service_delete_key, service_removing_key)
         return service_removing_key, service_delete_key
+    
+    
+    def _optical_service_create(self, service_id : ServiceId , has_media_channel : bool
+                                , has_optical_band = True) -> Tuple[str, str]:
+        service_planned_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_PLANNED))
+
+        service_active_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_ACTIVE))
+
+        # activating a service requires the service is in planning state
+        self._dag.add(service_active_key, service_planned_key)
+        return service_planned_key, service_active_key
 
     def _optical_service_remove(
         self, service_id : ServiceId, has_media_channel : bool, has_optical_band = True
@@ -135,6 +150,29 @@ class TasksScheduler:
         self._dag.add(service_delete_key, connection_deconfigure_key)
 
         return connection_deconfigure_key
+    
+    
+    def _optical_connection_configure(self, connection_id : ConnectionId
+                                      , service_id : ServiceId ,
+                                      has_media_channel : bool, has_optical_band = True) -> str:
+        optical_connection_configure_key = self._add_task_if_not_exists(Task_OpticalConnectionConfigure(
+            self._executor, connection_id))
+        
+        
+        # the connection configuration depends on its connection's service being in planning state
+        service_planned_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_PLANNED))
+        self._dag.add(optical_connection_configure_key, service_planned_key)
+        
+      
+
+        # the connection's service depends on the connection configuration to transition to active state
+        service_active_key = self._add_task_if_not_exists(Task_ServiceSetStatus(
+            self._executor, service_id, ServiceStatusEnum.SERVICESTATUS_ACTIVE))
+        self._dag.add(service_active_key, optical_connection_configure_key)
+        
+       
+        return optical_connection_configure_key
 
     def _optical_connection_deconfigure(
         self, connection_id : ConnectionId, service_id : ServiceId,
@@ -218,10 +256,57 @@ class TasksScheduler:
             else :
                 has_optical_band = True
         return (has_media_channel, has_optical_band)
-
-    def compose_from_optical_service(
-        self, service : Service, params : dict, is_delete : bool = False
+    
+    
+    
+    def compose_from_opticalcontroller_reply(
+        self, pathcomp_reply : PathCompReply, is_delete : bool = False
     ) -> None:
+        t0 = time.time()
+        include_service = self._optical_service_remove if is_delete else self._optical_service_create
+        include_connection = self._optical_connection_deconfigure if is_delete else self._optical_connection_configure
+
+        #pending_items_to_explore.put(service)
+        has_media_channel = None
+        has_optical_band = None
+   
+        for service in pathcomp_reply.services:
+
+                connections = self._context_client.ListConnections(service.service_id)
+                has_media_channel, has_optical_band = self.check_service_for_media_channel(
+                    connections=connections, item=service.service_id
+                )
+
+                
+                include_service(service.service_id , has_media_channel=has_media_channel, has_optical_band=has_optical_band)
+                self._add_service_to_executor_cache(service)
+                
+                for connection in connections.connections:
+                    self._add_connection_to_executor_cache(connection)
+                   
+               
+
+        for connection in pathcomp_reply.connections:
+               
+                connection_key = include_connection(
+                    connection.connection_id, connection.service_id, has_media_channel=has_media_channel,
+                    has_optical_band=has_optical_band
+                ) 
+                self._add_connection_to_executor_cache(connection)
+
+                self._executor.get_service(connection.service_id)
+                for sub_service_id in connection.sub_service_ids:
+                    _,service_key_done = include_service(
+                        sub_service_id, has_media_channel=has_media_channel,
+                        has_optical_band=has_optical_band
+                    )
+                    self._executor.get_service(sub_service_id)
+                    self._dag.add(connection_key, service_key_done)
+
+        t1 = time.time()
+        LOGGER.debug('[compose_from_service] elapsed_time: {:f} sec'.format(t1-t0))
+
+    def compose_from_optical_service(self, service : Service, params:dict, is_delete : bool = False) -> None:
         t0 = time.time()
         include_service = self._optical_service_remove if is_delete else self._service_create
         include_connection = self._optical_connection_deconfigure if is_delete else self._connection_configure
@@ -230,103 +315,125 @@ class TasksScheduler:
         explored_items = set()
         pending_items_to_explore = queue.Queue()
         pending_items_to_explore.put(service)
-        has_media_channel = None
-        has_optical_band = None
-        reply = None
-        code = 0
-        reply_not_allowed = "DELETE_NOT_ALLOWED"
+        has_media_channel=None
+        has_optical_band=None
+        reply=None
+        code=0
+        reply_not_allowed="DELETE_NOT_ALLOWED"
         while not pending_items_to_explore.empty():
             try:
                 item = pending_items_to_explore.get(block=False)
+
             except queue.Empty:
                 break
-
+        
             if isinstance(item, Service):
+          
                 str_item_key = grpc_message_to_json_string(item.service_id)
                 if str_item_key in explored_items: continue
                 connections = self._context_client.ListConnections(item.service_id)
-                has_media_channel, has_optical_band = self.check_service_for_media_channel(
-                    connections=connections, item=item.service_id
-                )
-
+                has_media_channel,has_optical_band=self.check_service_for_media_channel(connections=connections,item=item.service_id)
+               
                 if len(service.service_config.config_rules) > 0:
-                    reply, code = delete_lightpath(
-                        params['src'], params ['dst'], params['bitrate'], params['ob_id'],
-                        delete_band=not has_media_channel, flow_id= params['flow_id']
-                    )
-
-                if code == 400 and reply_not_allowed in reply:
+                
+                   
+                    reply,code = delete_lightpath(
+                                              params['src']
+                                             ,params ['dst']
+                                             , params['bitrate']
+                                             , params['ob_id']
+                                             ,delete_band=not has_media_channel
+                                             , flow_id= params['flow_id']
+                                             )
+              
+               
+                if code == 400 and reply_not_allowed in reply :
                    MSG = 'Deleteion for the service is not Allowed , Served Lightpaths is not empty'
                    raise Exception(MSG)
 
-                include_service(
-                    item.service_id, has_media_channel=has_media_channel, has_optical_band=has_optical_band
-                )
+                include_service(item.service_id,has_media_channel=has_media_channel,has_optical_band=has_optical_band)
                 self._add_service_to_executor_cache(item)
-
+               
+          
                 for connection in connections.connections:
-                    self._add_connection_to_executor_cache(connection)
-                    pending_items_to_explore.put(connection)
+                        self._add_connection_to_executor_cache(connection)
+                        pending_items_to_explore.put(connection)
                 explored_items.add(str_item_key)
+        
 
             elif isinstance(item, ServiceId):
-                if code == 400 and reply_not_allowed in reply: break
+              
+                if code == 400 and reply_not_allowed in reply:break
+                
                 str_item_key = grpc_message_to_json_string(item)
                 if str_item_key in explored_items: continue
                 connections = self._context_client.ListConnections(item)
-                has_media_channel, has_optical_band = self.check_service_for_media_channel(
-                    connections=connections, item=item
-                )
-                include_service(
-                    item, has_media_channel=has_media_channel, has_optical_band=has_optical_band
-                )
-                self._executor.get_service(item)
+                has_media_channel,has_optical_band=self.check_service_for_media_channel(connections=connections,item=item)
 
+            
+                include_service(item,has_media_channel=has_media_channel,has_optical_band=has_optical_band)
+               
+                
+                self._executor.get_service(item)
+               
                 for connection in connections.connections:
+                  
                     self._add_connection_to_executor_cache(connection)
                     pending_items_to_explore.put(connection)
+                  
+                            
+
+          
                 explored_items.add(str_item_key)
 
             elif isinstance(item, Connection):
+              
+                
                 if code == 400 and reply_not_allowed in reply:break
+         
                 str_item_key = grpc_message_to_json_string(item.connection_id)
                 if str_item_key in explored_items: continue
-                connection_key = include_connection(
-                    item.connection_id, item.service_id, has_media_channel=has_media_channel,
-                    has_optical_band=has_optical_band
-                ) 
+                
+                   
+                connection_key = include_connection(item.connection_id, item.service_id,has_media_channel=has_media_channel,has_optical_band=has_optical_band) 
                 self._add_connection_to_executor_cache(connection)
-
+                
                 if include_service_config is not None : 
-                    connections_list = ConnectionList()  
-                    connections_list.connections.append(item)
-                    is_media_channel, _ = self.check_service_for_media_channel(
-                        connections=connections_list, item=service
-                    )
-                    if has_optical_band and is_media_channel:
-                        include_service_config(
-                            item.connection_id, item.service_id
-                        )
+                   connections_list = ConnectionList()  
+                   connections_list.connections.append(item)
+                   
+                   is_media_channel,_=self.check_service_for_media_channel(connections=connections_list,item=service)
+                   
+                   if has_optical_band and is_media_channel:
+                        include_service_config(item.connection_id
+                                                , item.service_id
+                             
+                                                )
+                
+
                 self._executor.get_service(item.service_id)
                 pending_items_to_explore.put(item.service_id)
-
+              
+           
                 for sub_service_id in item.sub_service_ids:
-                    _,service_key_done = include_service(
-                        sub_service_id, has_media_channel=has_media_channel,
-                        has_optical_band=has_optical_band
-                    )
+                    _,service_key_done = include_service(sub_service_id,has_media_channel=has_media_channel,has_optical_band=has_optical_band)
                     self._executor.get_service(sub_service_id)
                     self._dag.add(service_key_done, connection_key)
                     pending_items_to_explore.put(sub_service_id)
+                    
+
 
                 explored_items.add(str_item_key)
+            
+                     
             else:
                 MSG = 'Unsupported item {:s}({:s})'
                 raise Exception(MSG.format(type(item).__name__, grpc_message_to_json_string(item)))
-
+      
         t1 = time.time()
         LOGGER.debug('[compose_from_service] elapsed_time: {:f} sec'.format(t1-t0))
 
+
     def compose_from_service(self, service : Service, is_delete : bool = False) -> None:
         t0 = time.time()
         include_service = self._service_remove if is_delete else self._service_create
diff --git a/src/service/service/task_scheduler/tasks/Task_OpticalConnectionConfigure.py b/src/service/service/task_scheduler/tasks/Task_OpticalConnectionConfigure.py
new file mode 100644
index 0000000000000000000000000000000000000000..1665c41b18dba0a7c09ae124092e018afb4c6fb2
--- /dev/null
+++ b/src/service/service/task_scheduler/tasks/Task_OpticalConnectionConfigure.py
@@ -0,0 +1,88 @@
+# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (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.
+
+from typing import TYPE_CHECKING, Dict, Tuple
+from common.DeviceTypes import DeviceTypeEnum
+from common.method_wrappers.ServiceExceptions import OperationFailedException
+from common.proto.context_pb2 import ConnectionId, Device
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from service.service.service_handler_api.Tools import check_errors_setendpoint
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+from service.service.tools.EndpointIdFormatters import endpointids_to_raw
+from service.service.tools.ObjectKeys import get_connection_key
+from ._Task import _Task
+
+if TYPE_CHECKING:
+    from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+
+KEY_TEMPLATE = 'optical_Connection ({connection_id:s}):configure'
+
+class Task_OpticalConnectionConfigure(_Task):
+    def __init__(self, task_executor : TaskExecutor, connection_id : ConnectionId) -> None:
+        super().__init__(task_executor)
+        self._connection_id = connection_id
+
+    @property
+    def connection_id(self) -> ConnectionId: return self._connection_id
+
+    @staticmethod
+    def build_key(connection_id : ConnectionId) -> str: # pylint: disable=arguments-differ
+        str_connection_id = get_connection_key(connection_id)
+        return KEY_TEMPLATE.format(connection_id=str_connection_id)
+
+    @property
+    def key(self) -> str: return self.build_key(self._connection_id)
+
+    def execute(self) -> None:
+        connection = self._task_executor.get_connection(self._connection_id)
+        service = self._task_executor.get_service(connection.service_id)
+
+        service_handler_settings = {}
+        service_handlers : Dict[DeviceTypeEnum, Tuple['_ServiceHandler', Dict[str, Device]]] = \
+            self._task_executor.get_service_handlers(connection, service, **service_handler_settings)
+
+        connection_uuid = connection.connection_id.connection_uuid.uuid
+        endpointids_to_set = endpointids_to_raw(connection.path_hops_endpoint_ids)
+
+        errors = list()
+        for _, (service_handler, connection_devices) in service_handlers.items():
+            _endpointids_to_set = [
+                (device_uuid, endpoint_uuid, topology_uuid)
+                for device_uuid, endpoint_uuid, topology_uuid in endpointids_to_set
+                if device_uuid in connection_devices
+            ]
+            results_setendpoint = service_handler.SetEndpoint(
+                _endpointids_to_set, connection_uuid=connection_uuid
+            )
+            errors.extend(check_errors_setendpoint(endpointids_to_set, results_setendpoint))
+
+        if len(errors) > 0:
+            MSG = 'SetEndpoint for Connection({:s}) from Service({:s})'
+            str_connection = grpc_message_to_json_string(connection)
+            str_service = grpc_message_to_json_string(service)
+            raise OperationFailedException(MSG.format(str_connection, str_service), extra_details=errors)
+
+        self._task_executor.set_connection(connection)
+        
+        results_setendOpticalConfigs = service_handler.SetOpticalConfig(
+                _endpointids_to_set, connection_uuid=connection_uuid
+            )
+        errors.extend(check_errors_setendpoint(endpointids_to_set, results_setendOpticalConfigs))
+
+        if len(errors) > 0:
+            MSG = 'SetOpticalConfigs for Optical Connection({:s}) from Optical Service({:s})'
+            str_connection = grpc_message_to_json_string(connection)
+            str_service = grpc_message_to_json_string(service)
+            raise OperationFailedException(MSG.format(str_connection, str_service), extra_details=errors)
+        
diff --git a/src/service/service/tools/OpticalTools.py b/src/service/service/tools/OpticalTools.py
index b7df3dd1428718f1d8141c557fddf8e572312afc..774f4f6713ea131fb124782e782b336a6842025d 100644
--- a/src/service/service/tools/OpticalTools.py
+++ b/src/service/service/tools/OpticalTools.py
@@ -26,7 +26,10 @@ from common.Settings import (
     find_environment_variables, get_env_var_name
 )
 from service.service.tools.replies import (
-    reply_uni_txt, optical_band_uni_txt, reply_bid_txt, optical_band_bid_txt
+    reply_uni_txt
+    , optical_band_uni_txt
+    , reply_bid_txt
+    , optical_band_bid_txt
 )
 
 log = logging.getLogger(__name__)
diff --git a/src/webui/requirements.in b/src/webui/requirements.in
index f5bbee5bc954aa82392d86d653fda57725cda40b..e80851b4a2a89898cdfef36c292e23b62b9f1514 100644
--- a/src/webui/requirements.in
+++ b/src/webui/requirements.in
@@ -18,3 +18,4 @@ flask-healthz<2
 flask-unittest==0.1.3
 lorem-text==2.1
 werkzeug==2.3.7
+requests==2.27.1
diff --git a/src/webui/service/__main__.py b/src/webui/service/__main__.py
index e604b0d9030c436bd07c02d792b22d5be0bd0701..44a8f2e015ac516484722acd1326a586c125bd54 100644
--- a/src/webui/service/__main__.py
+++ b/src/webui/service/__main__.py
@@ -17,7 +17,8 @@ from prometheus_client import start_http_server
 from common.Constants import ServiceNameEnum
 from common.Settings import (
     ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
-    get_service_baseurl_http, get_service_port_http, get_setting, wait_for_environment_variables)
+    get_service_baseurl_http, get_service_port_http, get_setting, wait_for_environment_variables
+    )
 from webui.service import create_app
 from webui.Config import MAX_CONTENT_LENGTH, HOST, SECRET_KEY, DEBUG
 
@@ -41,6 +42,8 @@ def main():
         get_env_var_name(ServiceNameEnum.DEVICE,  ENVVAR_SUFIX_SERVICE_PORT_GRPC),
         get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_HOST     ),
         get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
+         get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.OPTICALCONTROLLER, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
     ])
 
     logger.info('Starting...')
@@ -60,7 +63,9 @@ def main():
         'SECRET_KEY': SECRET_KEY,
         'MAX_CONTENT_LENGTH': MAX_CONTENT_LENGTH,
         'SESSION_COOKIE_NAME': create_unique_session_cookie_name(),
+        'WTF_CSRF_ENABLED':False
     }, web_app_root=web_app_root)
+    #app = create_app(use_config=None, web_app_root=web_app_root)
     app.run(host=host, port=service_port, debug=debug)
     
     logger.info(f'Bye ')
diff --git a/src/webui/service/main/routes.py b/src/webui/service/main/routes.py
index 2e23c28a67956f6a274a8f9c61df1ce2a7deb6ed..c3e4fe1a3ed6b47622733f8541f065c268fce547 100644
--- a/src/webui/service/main/routes.py
+++ b/src/webui/service/main/routes.py
@@ -57,7 +57,7 @@ def home():
     device_client.connect()
     context_topology_form = ContextTopologyForm()
     context_topology_form.context_topology.choices.append(('', 'Select...'))
-
+    logging.info(f"CSRF Token in Session:  {session}")
     contexts : ContextList = context_client.ListContexts(Empty())
     for context_ in contexts.contexts:
         #context_uuid : str = context_.context_id.context_uuid.uuid
@@ -74,6 +74,8 @@ def home():
             context_topology_form.context_topology.choices.append(context_topology_entry)
 
     if context_topology_form.validate_on_submit():
+        logging.info(f"CSRF Token from Form: {request.form.get('csrf_token')}")
+        logging.info(f"CSRF Token in Session:  {session.get('csrf_token')}")
         context_topology_uuid = context_topology_form.context_topology.data
         if len(context_topology_uuid) > 0:
             b64_values = context_topology_uuid.split(',')
@@ -117,7 +119,8 @@ def home():
     finally:
         context_client.close()
         device_client.close()
-
+        
+    LOGGER.info(f"erorr {context_topology_form.errors.items()}")
     return render_template(
         'main/home.html', context_topology_form=context_topology_form, descriptor_form=descriptor_form)
 
diff --git a/src/webui/service/optical_link/routes.py b/src/webui/service/optical_link/routes.py
index 764d4c266948998b7389f276126f384bff7e7ba8..87ca15de1c0bfc1228bc6efdab361ac9a56e1b5d 100644
--- a/src/webui/service/optical_link/routes.py
+++ b/src/webui/service/optical_link/routes.py
@@ -18,6 +18,27 @@ from common.proto.context_pb2 import Empty, OpticalLink, LinkId, OpticalLinkList
 from common.tools.context_queries.EndPoint import get_endpoint_names
 from common.tools.context_queries.Topology import get_topology
 from context.client.ContextClient import ContextClient
+import functools ,requests ,logging
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_BASEURL_HTTP, ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC,
+    find_environment_variables, get_env_var_name
+)
+get_optical_controller_setting = functools.partial(get_env_var_name, ServiceNameEnum.OPTICALCONTROLLER)
+VAR_NAME_OPTICAL_CTRL_HOST         = get_optical_controller_setting(ENVVAR_SUFIX_SERVICE_HOST)
+VAR_NAME_OPTICAL_CTRL_PORT         = get_optical_controller_setting(ENVVAR_SUFIX_SERVICE_PORT_GRPC)
+VAR_NAME_OPTICAL_CTRL_BASEURL_HTTP = get_optical_controller_setting(ENVVAR_SUFIX_SERVICE_BASEURL_HTTP)
+VAR_NAME_OPTICAL_CTRL_SCHEMA       = get_optical_controller_setting('SCHEMA')
+
+settings = find_environment_variables([
+        VAR_NAME_OPTICAL_CTRL_BASEURL_HTTP,
+        VAR_NAME_OPTICAL_CTRL_SCHEMA,
+        VAR_NAME_OPTICAL_CTRL_HOST,
+        VAR_NAME_OPTICAL_CTRL_PORT,
+    ])
+
+host = settings.get(VAR_NAME_OPTICAL_CTRL_HOST)
+port = settings.get(VAR_NAME_OPTICAL_CTRL_PORT, 80)
 
 optical_link = Blueprint('optical_link', __name__, url_prefix='/optical_link')
 context_client = ContextClient()
@@ -106,3 +127,74 @@ def delete_all():
     except Exception as e:
         flash(f"Problem in delete all optical link  => {e}",'danger')
     return redirect(url_for('optical_link.home'))
+
+
+@optical_link.route('getopticallinks', methods=(['GET']))
+def get_optical_links (): 
+    
+
+    urlx = "http://{:s}:{:s}/OpticalTFS/GetLinks".format(host,port)
+   
+    headers = {"Content-Type": "application/json"}
+    optical_links =[]
+    try: 
+        r = requests.get(urlx, headers=headers)
+        reply = r.json()
+        if (reply and 'optical_links' in reply): optical_links = reply["optical_links"]
+        
+        logging.info(f"reply {optical_links}")
+    except Exception as e : 
+        logging.info(f"error {e}")
+    finally:
+         
+       return render_template(
+        'opticalconfig/opticallinks.html', optical_links=optical_links
+    )
+       
+
+
+
+@optical_link.route('getopticalbands', methods=(['GET']))
+def get_optical_bands(): 
+    
+
+    urlx = "http://{:s}:{:s}/OpticalTFS/GetOpticalBands".format(host,port)
+   
+    headers = {"Content-Type": "application/json"}
+    optical_bands ={}
+    try: 
+        r = requests.get(urlx, headers=headers)
+        reply = r.json()
+        if (reply):optical_bands=reply
+        
+        logging.info(f"optical bands {reply}")
+    except Exception as e : 
+        logging.info(f"error {e}")
+    finally:
+         
+       return render_template(
+        'opticalconfig/opticalbands.html',optical_bands=optical_bands
+    )       
+ 
+@optical_link.route('getlightpath', methods=(['GET']))
+def get_lightpath(): 
+    
+
+    urlx = "http://{:s}:{:s}/OpticalTFS/GetLightpaths".format(host,port)
+   
+    headers = {"Content-Type": "application/json"}
+    light_paths ={}
+    try: 
+        r = requests.get(urlx, headers=headers)
+        reply = r.json()
+        if (reply):light_paths=reply
+       
+        
+        logging.info(f"lightpaths {reply}")
+    except Exception as e : 
+        logging.info(f"error {e}")
+    finally:
+         
+       return render_template(
+        'opticalconfig/lightpaths.html',light_paths=light_paths
+    )           
\ No newline at end of file
diff --git a/src/webui/service/templates/base_optical/home.html b/src/webui/service/templates/base_optical/home.html
index c087af016dd18410958edfde9f0b452bf9f0bd83..490d40ffe00ed3cb1670fda30adf1390011d5af9 100644
--- a/src/webui/service/templates/base_optical/home.html
+++ b/src/webui/service/templates/base_optical/home.html
@@ -27,10 +27,22 @@
             </a>
           </div>
           <div class="col">
-            <a href="{{ url_for('optical_link.home') }}" class="btn btn-primary" style="margin-bottom: 10px;">
+            <a href="{{ url_for('optical_link.get_optical_links') }}" class="btn btn-primary" style="margin-bottom: 10px;">
               
                   Optical Links
             </a>
           </div>
+          <div class="col">
+            <a href="{{ url_for('optical_link.get_optical_bands') }}" class="btn btn-primary" style="margin-bottom: 10px;">
+              
+                  Optical Bands
+            </a>
+          </div>
+          <div class="col">
+            <a href="{{ url_for('optical_link.get_lightpath') }}" class="btn btn-primary" style="margin-bottom: 10px;">
+              
+                  Light Paths
+            </a>
+          </div>
        </div>
    {% endblock %}
diff --git a/src/webui/service/templates/optical_link/detail.html b/src/webui/service/templates/optical_link/detail.html
index 2f7cd2326589dbcc93c8d4d232257d5267363b87..3bcb1a34b7ddac0a95feed5f08d1e0bd5e4c9827 100644
--- a/src/webui/service/templates/optical_link/detail.html
+++ b/src/webui/service/templates/optical_link/detail.html
@@ -17,7 +17,6 @@
 {% extends 'base.html' %}
 
 {% block content %}
-<h1>Link {{ link.name }} ({{ link.link_id.link_uuid.uuid }})</h1>
 <div class="row mb-3">
     <div class="col-sm-3">
         <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('optical_link.home') }}'">
@@ -25,29 +24,26 @@
             Back to link list
         </button>
     </div>
-    <div class="col-sm-3">
-        <!-- <button type="button" class="btn btn-danger"><i class="bi bi-x-square"></i>Delete link</button> -->
-        <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
-            <i class="bi bi-x-square"></i>
-            Delete link
-        </button>
-    </div>
+   
 </div>
+{% for link in optical_links %}
+<h1>Link : {{ link.name }} </h1>
+
 
 <br>
 <div class="row mb-3">
     <div class="col-sm-4">
         <b>UUID: </b>{{ link.link_id.link_uuid.uuid }}<br>
-        <b>Name: </b>{{ link.name }}<br>
+    
     </div>
     <div class="col-sm-8">
         <table class="table table-striped table-hover">
             <thead>
                 <tr>
                     <th scope="col">Endpoint UUID</th>
-                    <th scope="col">Name</th>
-                    <th scope="col">Device</th>
-                    <th scope="col">Endpoint Type</th>
+                  
+                    <th scope="col">Device UUID </th>
+                  
                 </tr>
             </thead>
             <tbody>
@@ -56,21 +52,12 @@
                     <td>
                         {{ endpoint.endpoint_uuid.uuid }}
                     </td>
+                   
                     <td>
-                        {{ endpoints_data.get(endpoint.endpoint_uuid.uuid, (endpoint.endpoint_uuid.uuid, ''))[0] }}
-                    </td>
-                    <td>
-                        <a href="{{ url_for('device.detail', device_uuid=endpoint.device_id.device_uuid.uuid) }}">
-                            {{ device_names.get(endpoint.device_id.device_uuid.uuid, endpoint.device_id.device_uuid.uuid) }}
-                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
-                                    <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
-                                    <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
-                            </svg>
-                        </a>
-                    </td>
-                    <td>
-                        {{ endpoints_data.get(endpoint.endpoint_uuid.uuid, ('', '-'))[1] }}
+                        {{endpoint.device_id.device_uuid.uuid}}
+                        
                     </td>
+         
                 </tr>
                 {% endfor %}
             </tbody>
@@ -89,28 +76,20 @@
         </tr>
     </thead>
     <tbody>
-        {% for field_descriptor, field_value in link.optical_details.ListFields() %}
-            {% if  field_descriptor.name != "c_slots" and  field_descriptor.name != "s_slots" and  field_descriptor.name != "l_slots" %}
+        {% for field_descriptor, field_value in link.optical_details.items() %}
+          
             <tr>
+               
                 <td>
-                    {{ field_descriptor.name }}
+                    {{ field_descriptor }}
                 </td>
                 <td>
                     {{ field_value }}
                 </td>
             </tr>
-            {%endif%}
+            
         {% endfor %}
-        {%if c_slots %}
-        <tr>
-            <td>
-                c_slots
-            </td>
-            <td>
-                {{ c_slots }}
-            </td>
-        </tr>
-        {%endif%}
+       
         {%if l_slots %}
         <tr>
             <td>
@@ -133,26 +112,9 @@
         {%endif%}
     </tbody>
 </table>
+
+{% endfor %}
 <!-- Modal -->
-<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
-    aria-labelledby="staticBackdropLabel" aria-hidden="true">
-    <div class="modal-dialog">
-        <div class="modal-content">
-            <div class="modal-header">
-                <h5 class="modal-title" id="staticBackdropLabel">Delete link?</h5>
-                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-            </div>
-            <div class="modal-body">
-                Are you sure you want to delete the link "{{ link.link_id.link_uuid.uuid }}"?
-            </div>
-            <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
-                <a type="button" class="btn btn-danger"
-                    href="{{ url_for('optical_link.delete', link_uuid=link.link_id.link_uuid.uuid) }}"><i
-                        class="bi bi-exclamation-diamond"></i>Yes</a>
-            </div>
-        </div>
-    </div>
-</div>
+
 
 {% endblock %}
diff --git a/src/webui/service/templates/opticalconfig/lightpaths.html b/src/webui/service/templates/opticalconfig/lightpaths.html
new file mode 100644
index 0000000000000000000000000000000000000000..5ae6734615b9a743e656380b4815c0f718420f7d
--- /dev/null
+++ b/src/webui/service/templates/opticalconfig/lightpaths.html
@@ -0,0 +1,73 @@
+<!--
+    Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (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.
+   -->
+
+{% extends 'base.html' %}
+
+{% block content %}
+<div class="row mb-3">
+    <div class="col-sm-3">
+        <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('optical_link.home') }}'">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Back to link list
+        </button>
+    </div>
+   
+</div>
+
+<h1>Light Paths </h1>
+{% for field_descriptor, field_value in light_paths.items() %}
+
+
+<div class="row mt-3">
+    <div class="col-sm-3">
+    </div>
+
+</div>        
+
+<b>Name : {{field_descriptor}}</b>
+
+<table class="table table-striped table-hover">
+    <thead>
+        <tr>
+            <th scope="col">Key</th>
+            <th scope="col">Value</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for k, v in field_value.items() %}
+          
+            <tr>
+               
+                <td>
+                    {{ k }}
+                </td>
+                <td>
+                    {{ v }}
+                </td>
+            </tr>
+            
+        {% endfor %}
+      
+      
+    </tbody>
+</table>
+
+{% endfor %}
+<!-- Modal -->
+<!-- Modal -->
+
+
+{% endblock %}
diff --git a/src/webui/service/templates/opticalconfig/opticalbands.html b/src/webui/service/templates/opticalconfig/opticalbands.html
new file mode 100644
index 0000000000000000000000000000000000000000..94e4ec559f090a3d4caf49d9aaeae653528e264c
--- /dev/null
+++ b/src/webui/service/templates/opticalconfig/opticalbands.html
@@ -0,0 +1,74 @@
+<!--
+    Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (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.
+   -->
+
+{% extends 'base.html' %}
+
+{% block content %}
+<div class="row mb-3">
+    <div class="col-sm-3">
+        <button type="button" class="btn btn-success" onclick="window.location.href='/base_optical'">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Back to link list
+        </button>
+    </div>
+   
+</div>
+
+<h1>Optical Bands </h1>
+{% for field_descriptor, field_value in optical_bands.items() %}
+
+
+<div class="row mt-3">
+    <div class="col-sm-3">
+    </div>
+
+</div>  
+
+
+<b>Name :  {{field_descriptor}}</b>
+
+<table class="table table-striped table-hover">
+    <thead>
+        <tr>
+            <th scope="col">Key</th>
+            <th scope="col">Value</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for k, v in field_value.items() %}
+          
+            <tr>
+               
+                <td>
+                    {{ k }}
+                </td>
+                <td>
+                    {{ v }}
+                </td>
+            </tr>
+            
+        {% endfor %}
+      
+      
+    </tbody>
+</table>
+
+{% endfor %}
+<!-- Modal -->
+
+
+{% endblock %}
+
diff --git a/src/webui/service/templates/opticalconfig/opticallinks.html b/src/webui/service/templates/opticalconfig/opticallinks.html
new file mode 100644
index 0000000000000000000000000000000000000000..3bcb1a34b7ddac0a95feed5f08d1e0bd5e4c9827
--- /dev/null
+++ b/src/webui/service/templates/opticalconfig/opticallinks.html
@@ -0,0 +1,120 @@
+<!--
+    Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (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.
+   -->
+
+{% extends 'base.html' %}
+
+{% block content %}
+<div class="row mb-3">
+    <div class="col-sm-3">
+        <button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('optical_link.home') }}'">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Back to link list
+        </button>
+    </div>
+   
+</div>
+{% for link in optical_links %}
+<h1>Link : {{ link.name }} </h1>
+
+
+<br>
+<div class="row mb-3">
+    <div class="col-sm-4">
+        <b>UUID: </b>{{ link.link_id.link_uuid.uuid }}<br>
+    
+    </div>
+    <div class="col-sm-8">
+        <table class="table table-striped table-hover">
+            <thead>
+                <tr>
+                    <th scope="col">Endpoint UUID</th>
+                  
+                    <th scope="col">Device UUID </th>
+                  
+                </tr>
+            </thead>
+            <tbody>
+                {% for endpoint in link.link_endpoint_ids %}
+                <tr>
+                    <td>
+                        {{ endpoint.endpoint_uuid.uuid }}
+                    </td>
+                   
+                    <td>
+                        {{endpoint.device_id.device_uuid.uuid}}
+                        
+                    </td>
+         
+                </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+</div>
+
+
+
+<b>Optical Link Detail:</b>
+<table class="table table-striped table-hover">
+    <thead>
+        <tr>
+            <th scope="col">Key</th>
+            <th scope="col">Value</th>
+        </tr>
+    </thead>
+    <tbody>
+        {% for field_descriptor, field_value in link.optical_details.items() %}
+          
+            <tr>
+               
+                <td>
+                    {{ field_descriptor }}
+                </td>
+                <td>
+                    {{ field_value }}
+                </td>
+            </tr>
+            
+        {% endfor %}
+       
+        {%if l_slots %}
+        <tr>
+            <td>
+                l_slots
+            </td>
+            <td>
+                {{ l_slots }}
+            </td>
+        </tr>
+        {%endif%}
+        {%if s_slots %}
+        <tr>
+            <td>
+                s_slots
+            </td>
+            <td>
+                {{ s_slots }}
+            </td>
+        </tr>
+        {%endif%}
+    </tbody>
+</table>
+
+{% endfor %}
+<!-- Modal -->
+
+
+{% endblock %}