From 440a4d7e7e85bd32fc8d115d76a581a349f46be5 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@h-da.de>
Date: Tue, 18 Feb 2025 16:35:40 +0100
Subject: [PATCH 1/7] Update init for assignForwardingHandler

---
 .../kms/assignForwardingHandler.go            | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/goKMS/gnmiHandlers/kms/assignForwardingHandler.go b/goKMS/gnmiHandlers/kms/assignForwardingHandler.go
index bc4daeda..35c4da1b 100644
--- a/goKMS/gnmiHandlers/kms/assignForwardingHandler.go
+++ b/goKMS/gnmiHandlers/kms/assignForwardingHandler.go
@@ -36,6 +36,28 @@ func (yh *AssignForwardingHandler) Init(config *handler.Config, publishToSubsFun
 	yh.Config = config
 	yh.PublishToSubs = publishToSubsFunc
 
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	newConfig.GetOrCreateAssignForwarding()
+
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return err
+	}
+
+	yh.Config.Data = newConfig
+
 	return nil
 }
 
-- 
GitLab


From 4a59230a45060d474bc7ba6647c47aa4118168b7 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@h-da.de>
Date: Tue, 18 Feb 2025 18:34:04 +0100
Subject: [PATCH 2/7] Key store updates through EventBus

---
 goKMS/gnmiHandlers/kms/keyStoreHandler.go | 56 +++++++++++++++++------
 goKMS/kms/event/bus.go                    | 22 +++++++--
 goKMS/kms/event/event.go                  | 21 +++++++++
 goKMS/kms/store/kms-keystore.go           | 20 ++++++++
 4 files changed, 103 insertions(+), 16 deletions(-)

diff --git a/goKMS/gnmiHandlers/kms/keyStoreHandler.go b/goKMS/gnmiHandlers/kms/keyStoreHandler.go
index ddff4a7c..11e1d66f 100644
--- a/goKMS/gnmiHandlers/kms/keyStoreHandler.go
+++ b/goKMS/gnmiHandlers/kms/keyStoreHandler.go
@@ -2,10 +2,10 @@ package kmsHandler
 
 import (
 	"fmt"
-	"time"
 
 	"code.fbi.h-da.de/danet/gnmi-target/handler"
 	"code.fbi.h-da.de/danet/quant/goKMS/kms"
+	"code.fbi.h-da.de/danet/quant/goKMS/kms/event"
 	gnmitargetygot "code.fbi.h-da.de/danet/quant/goKMS/model"
 	"github.com/openconfig/gnmi/proto/gnmi"
 	"github.com/openconfig/ygot/ygot"
@@ -15,6 +15,7 @@ import (
 type KeyStoreHandler struct {
 	handler.DefaultPathHandler
 	kms                     *kms.KMS
+	events                  <-chan event.Event
 	maxKeyFillLevelsDefined map[string]uint64
 }
 
@@ -35,20 +36,49 @@ func (yh *KeyStoreHandler) Init(config *handler.Config, publishToSubsFunc func([
 	yh.Config = config
 	yh.PublishToSubs = publishToSubsFunc
 
+	var err error
+	yh.events, err = event.NewEventBus().Subscribe(event.KEY_STORE)
+	if err != nil {
+		return err
+	}
+
+	yh.Config.Lock()
+	defer yh.Config.Unlock()
+
+	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
+	if err != nil {
+		return err
+	}
+
+	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
+	if !ok {
+		return fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
+	}
+
+	newConfig.GetOrCreateKeyStores()
+
+	//validate struct
+	if err := newConfig.Validate(); err != nil {
+		return err
+	}
+
+	yh.Config.Data = newConfig
+
 	// Start the go routine that takes care of any update from the kms
 	go func() {
-		ticker := time.NewTicker(15 * time.Second)
-		defer ticker.Stop()
-
-		// TODO: add context/channel to stop
-		for range ticker.C {
-			diff, err := yh.updateOrCreateKeyStores(yh.kms)
-			if err != nil {
-				log.Errorf("Error within key stores subscription goroutine; %v", err)
-				break
-			}
-			if err := yh.PublishToSubs(diff); err != nil {
-				log.Errorf("Error within key stores subscription goroutine; %v", err)
+		for {
+			select {
+			case <-yh.events:
+				log.Println("Update for key stores.")
+
+				diff, err := yh.updateOrCreateKeyStores(yh.kms)
+				if err != nil {
+					log.Errorf("Error within key stores subscription goroutine; %v", err)
+					break
+				}
+				if err := yh.PublishToSubs(diff); err != nil {
+					log.Errorf("Error within key stores subscription goroutine; %v", err)
+				}
 			}
 		}
 	}()
diff --git a/goKMS/kms/event/bus.go b/goKMS/kms/event/bus.go
index 301b883b..947c3aac 100644
--- a/goKMS/kms/event/bus.go
+++ b/goKMS/kms/event/bus.go
@@ -1,15 +1,31 @@
 package event
 
-import "fmt"
+import (
+	"fmt"
+	"sync"
+)
+
+var eventBusLock = &sync.Mutex{}
+var eventBus *EventBus
 
 type EventBus struct {
 	subscribers map[Topic]map[chan<- Event]struct{}
 }
 
 func NewEventBus() *EventBus {
-	return &EventBus{
-		subscribers: make(map[Topic]map[chan<- Event]struct{}),
+	if eventBus == nil {
+		// lock access to eventBus
+		eventBusLock.Lock()
+		defer eventBusLock.Unlock()
+		// check if eventBus is still nil
+		if eventBus == nil {
+			fmt.Println("Initializing KMS EventBus.")
+			eventBus = &EventBus{
+				subscribers: make(map[Topic]map[chan<- Event]struct{}),
+			}
+		}
 	}
+	return eventBus
 }
 
 func (b *EventBus) Subscribe(topic Topic) (<-chan Event, error) {
diff --git a/goKMS/kms/event/event.go b/goKMS/kms/event/event.go
index b99faee9..c0a32e84 100644
--- a/goKMS/kms/event/event.go
+++ b/goKMS/kms/event/event.go
@@ -9,6 +9,7 @@ const (
 	ROUTE
 	QUANTUM_MODULE
 	CREATE_ROUTE
+	KEY_STORE
 )
 
 // Event ...
@@ -86,3 +87,23 @@ func (e *RouteEvent) Topic() Topic {
 func (e *RouteEvent) Time() time.Time {
 	return e.Timestamp
 }
+
+type KeyStoreEvent struct {
+	EventTopic Topic
+	Timestamp  time.Time
+}
+
+func NewKeyStoreEvent() *RouteEvent {
+	return &RouteEvent{
+		EventTopic: ROUTE,
+		Timestamp:  time.Now(),
+	}
+}
+
+func (e *KeyStoreEvent) Topic() Topic {
+	return e.EventTopic
+}
+
+func (e *KeyStoreEvent) Time() time.Time {
+	return e.Timestamp
+}
diff --git a/goKMS/kms/store/kms-keystore.go b/goKMS/kms/store/kms-keystore.go
index ef1a5212..73a06671 100644
--- a/goKMS/kms/store/kms-keystore.go
+++ b/goKMS/kms/store/kms-keystore.go
@@ -4,8 +4,10 @@ import (
 	"encoding/base64"
 	"fmt"
 	"sync"
+	"time"
 
 	etsi14 "code.fbi.h-da.de/danet/quant/etsi014/go/rest/etsi/client"
+	"code.fbi.h-da.de/danet/quant/goKMS/kms/event"
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 )
@@ -30,6 +32,7 @@ type KmsKeyStore struct {
 	keyStoreMutex sync.Mutex
 	keyStore      map[uuid.UUID]*KmsKSElement
 	KeySingleSize uint // the size of a single key, given as unit of bits
+	eventBus      *event.EventBus
 }
 
 func NewKmsKeyStore(desiredkeySingleSizeLength uint) *KmsKeyStore {
@@ -37,6 +40,7 @@ func NewKmsKeyStore(desiredkeySingleSizeLength uint) *KmsKeyStore {
 		// NOTE: could be useful to use something like a ordered map here
 		keyStore:      make(map[uuid.UUID]*KmsKSElement),
 		KeySingleSize: desiredkeySingleSizeLength,
+		eventBus:      event.NewEventBus(),
 	}
 }
 
@@ -63,6 +67,14 @@ func (ks *KmsKeyStore) AddKey(keyId uuid.UUID, keyToadd []byte) error {
 	}
 	// ok to add
 	ks.keyStore[newKeyElement.KeyID] = newKeyElement
+
+	// publish to eventBus
+	go func() {
+		err := ks.eventBus.Publish(&event.KeyStoreEvent{EventTopic: event.KEY_STORE, Timestamp: time.Now()})
+		if err != nil {
+			fmt.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+		}
+	}()
 	return nil
 }
 
@@ -100,6 +112,14 @@ func (ks *KmsKeyStore) DeleteKey(keyId uuid.UUID) {
 	ks.keyStoreMutex.Lock()
 	defer ks.keyStoreMutex.Unlock()
 	delete(ks.keyStore, keyId)
+
+	// publish to eventBus
+	go func() {
+		err := ks.eventBus.Publish(&event.KeyStoreEvent{EventTopic: event.KEY_STORE, Timestamp: time.Now()})
+		if err != nil {
+			fmt.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+		}
+	}()
 }
 
 func (ks *KmsKeyStore) Reset() {
-- 
GitLab


From 234258be71e36652a424895b8130ea3d50422c55 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@h-da.de>
Date: Tue, 18 Feb 2025 18:50:09 +0100
Subject: [PATCH 3/7] Fix wrongly returned Event for NewKeyStoreEvent

---
 goKMS/kms/event/event.go        | 6 +++---
 goKMS/kms/store/kms-keystore.go | 5 ++---
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/goKMS/kms/event/event.go b/goKMS/kms/event/event.go
index c0a32e84..2e89cf2b 100644
--- a/goKMS/kms/event/event.go
+++ b/goKMS/kms/event/event.go
@@ -93,9 +93,9 @@ type KeyStoreEvent struct {
 	Timestamp  time.Time
 }
 
-func NewKeyStoreEvent() *RouteEvent {
-	return &RouteEvent{
-		EventTopic: ROUTE,
+func NewKeyStoreEvent() *KeyStoreEvent {
+	return &KeyStoreEvent{
+		EventTopic: KEY_STORE,
 		Timestamp:  time.Now(),
 	}
 }
diff --git a/goKMS/kms/store/kms-keystore.go b/goKMS/kms/store/kms-keystore.go
index 73a06671..683c5634 100644
--- a/goKMS/kms/store/kms-keystore.go
+++ b/goKMS/kms/store/kms-keystore.go
@@ -4,7 +4,6 @@ import (
 	"encoding/base64"
 	"fmt"
 	"sync"
-	"time"
 
 	etsi14 "code.fbi.h-da.de/danet/quant/etsi014/go/rest/etsi/client"
 	"code.fbi.h-da.de/danet/quant/goKMS/kms/event"
@@ -70,7 +69,7 @@ func (ks *KmsKeyStore) AddKey(keyId uuid.UUID, keyToadd []byte) error {
 
 	// publish to eventBus
 	go func() {
-		err := ks.eventBus.Publish(&event.KeyStoreEvent{EventTopic: event.KEY_STORE, Timestamp: time.Now()})
+		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
 		if err != nil {
 			fmt.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
 		}
@@ -115,7 +114,7 @@ func (ks *KmsKeyStore) DeleteKey(keyId uuid.UUID) {
 
 	// publish to eventBus
 	go func() {
-		err := ks.eventBus.Publish(&event.KeyStoreEvent{EventTopic: event.KEY_STORE, Timestamp: time.Now()})
+		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
 		if err != nil {
 			fmt.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
 		}
-- 
GitLab


From d1604e5f3596c4d6851ec539a3fca47a811ca1f0 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@h-da.de>
Date: Wed, 19 Feb 2025 14:15:54 +0100
Subject: [PATCH 4/7] Keystore extended with AddKeys method

---
 docker-compose.yml                        | 259 +++++++++++-----------
 goKMS/gnmiHandlers/kms/keyStoreHandler.go |  28 +--
 goKMS/kms/kmsintercom.go                  |   8 +-
 goKMS/kms/peers/danetQuantummodule.go     |   6 +-
 goKMS/kms/quipsec.go                      |  10 +-
 goKMS/kms/store/kms-keystore.go           |  40 +++-
 6 files changed, 183 insertions(+), 168 deletions(-)

diff --git a/docker-compose.yml b/docker-compose.yml
index 32355fb8..d1ca2a18 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,128 +1,133 @@
 services:
-  kms01:
-    image: gokms
-    command: ["--log", "debug", "--kms_config", "/tmp/kms/config/kms01.yaml"]
-    volumes:
-        - ./config/goKMS/example01.yaml:/tmp/kms/config/kms01.yaml
-        - ./artifacts/ssl:/ssl
-    ports:
-        - "127.0.0.1:4401:1337"
-        - "127.0.0.1:9696:9696"
-
-  kms02:
-    image: gokms
-    command: ["--log", "debug", "--kms_config", "/tmp/kms/config/kms02.yaml"]
-    volumes:
-        - ./config/goKMS/example02.yaml:/tmp/kms/config/kms02.yaml
-        - ./artifacts/ssl:/ssl
-    ports:
-        - "127.0.0.1:4402:1337"
-
-  kms03:
-    image: gokms
-    command: ["--log", "debug", "--kms_config", "/tmp/kms/config/kms03.yaml"]
-    volumes:
-        - ./config/goKMS/example03.yaml:/tmp/kms/config/kms03.yaml
-        - ./artifacts/ssl:/ssl
-    ports:
-        - "127.0.0.1:4403:1337"
-
-  kms04:
-    image: gokms
-    command: ["--log", "debug", "--kms_config", "/tmp/kms/config/kms04.yaml"]
-    volumes:
-        - ./config/goKMS/example04.yaml:/tmp/kms/config/kms04.yaml
-        - ./artifacts/ssl:/ssl
-    ports:
-        - "127.0.0.1:4404:1337"
-        - "127.0.0.1:9697:9696"
-
-  qlayer01:
-    image: quantumlayer
-    command: ["--config", "/tmp/quantumlayer/config/quantumlayer01.yaml"]
-    volumes:
-        - ./config/quantumlayer/example01.yaml:/tmp/quantumlayer/config/quantumlayer01.yaml
-
-  qlayer02:
-    image: quantumlayer
-    command: ["--config", "/tmp/quantumlayer/config/quantumlayer02.yaml"]
-    volumes:
-        - ./config/quantumlayer/example02.yaml:/tmp/quantumlayer/config/quantumlayer02.yaml
-
-  qlayer03:
-    image: quantumlayer
-    command: ["--config", "/tmp/quantumlayer/config/quantumlayer03.yaml"]
-    volumes:
-        - ./config/quantumlayer/example03.yaml:/tmp/quantumlayer/config/quantumlayer03.yaml
-
-  qlayer04:
-    image: quantumlayer
-    command: ["--config", "/tmp/quantumlayer/config/quantumlayer04.yaml"]
-    volumes:
-        - ./config/quantumlayer/example04.yaml:/tmp/quantumlayer/config/quantumlayer04.yaml
-
-  qlayer05:
-    image: quantumlayer
-    command: ["--config", "/tmp/quantumlayer/config/quantumlayer05.yaml"]
-    volumes:
-        - ./config/quantumlayer/example05.yaml:/tmp/quantumlayer/config/quantumlayer05.yaml
-
-  qlayer06:
-    image: quantumlayer
-    command: ["--config", "/tmp/quantumlayer/config/quantumlayer06.yaml"]
-    volumes:
-        - ./config/quantumlayer/example06.yaml:/tmp/quantumlayer/config/quantumlayer06.yaml
-
-  qlayer07:
-    image: quantumlayer
-    command: ["--config", "/tmp/quantumlayer/config/quantumlayer07.yaml"]
-    volumes:
-        - ./config/quantumlayer/example07.yaml:/tmp/quantumlayer/config/quantumlayer07.yaml
-
-  qlayer08:
-    image: quantumlayer
-    command: ["--config", "/tmp/quantumlayer/config/quantumlayer08.yaml"]
-    volumes:
-        - ./config/quantumlayer/example08.yaml:/tmp/quantumlayer/config/quantumlayer08.yaml
-
-  akms-receiver01:
-    image: akms-simulator
-
-  akms-receiver02:
-    image: akms-simulator
-
-  qkdn-controller:
-    image: registry.code.fbi.h-da.de/demoquandt/qkdn-controller:qkdn-main
-    volumes:
-      - ./config/controller/qkdn-gosdn.toml:/app/configs/qkdn-gosdn.toml
-      - ./config/controller/gNMISubscriptions.txt:/app/configs/gNMISubscriptions.txt
-    command: --config ./configs/qkdn-gosdn.toml
-    ports:
-      - "127.0.0.1:55055:55055"
-    environment:
-      GOSDN_ADMIN_PASSWORD: TestPassword
-
-  gosdnc:
-    image: registry.code.fbi.h-da.de/demoquandt/qkdn-controller/gosdnc:qkdn-main
-    volumes:
-      - ./config/controller/add_devices.sh:/scripts/add_devices.sh
-    entrypoint: ["/scripts/add_devices.sh"]
-
-  plugin-registry:
-    image: registry.code.fbi.h-da.de/demoquandt/qkdn-controller/plugin-registry:qkdn-main
-
-  mongo:
-    image: mongo:7
-    environment:
-      MONGO_INITDB_ROOT_USERNAME: root
-      MONGO_INITDB_ROOT_PASSWORD: example
-
-  rabbitmq:
-    image: rabbitmq:3-management
-
-  routing-app:
-    image: registry.code.fbi.h-da.de/demoquandt/qkdn-controller/routing-app:qkdn-main
-    entrypoint: ["./start_ra_sleep.sh"]
-    volumes:
-      - ./config/controller/start_ra_sleep.sh:/app/start_ra_sleep.sh
-      - ./config/controller/routing-config.yaml:/new/routing-config.yaml
+    kms01:
+        image: gokms
+        command:
+            ["--log", "debug", "--kms_config", "/tmp/kms/config/kms01.yaml"]
+        volumes:
+            - ./config/goKMS/example01.yaml:/tmp/kms/config/kms01.yaml
+            - ./artifacts/ssl:/ssl
+        ports:
+            - "127.0.0.1:7030:7030"
+            - "127.0.0.1:4401:1337"
+            - "127.0.0.1:9696:9696"
+
+    kms02:
+        image: gokms
+        command:
+            ["--log", "debug", "--kms_config", "/tmp/kms/config/kms02.yaml"]
+        volumes:
+            - ./config/goKMS/example02.yaml:/tmp/kms/config/kms02.yaml
+            - ./artifacts/ssl:/ssl
+        ports:
+            - "127.0.0.1:4402:1337"
+
+    kms03:
+        image: gokms
+        command:
+            ["--log", "debug", "--kms_config", "/tmp/kms/config/kms03.yaml"]
+        volumes:
+            - ./config/goKMS/example03.yaml:/tmp/kms/config/kms03.yaml
+            - ./artifacts/ssl:/ssl
+        ports:
+            - "127.0.0.1:4403:1337"
+
+    kms04:
+        image: gokms
+        command:
+            ["--log", "debug", "--kms_config", "/tmp/kms/config/kms04.yaml"]
+        volumes:
+            - ./config/goKMS/example04.yaml:/tmp/kms/config/kms04.yaml
+            - ./artifacts/ssl:/ssl
+        ports:
+            - "127.0.0.1:4404:1337"
+            - "127.0.0.1:9697:9696"
+
+    qlayer01:
+        image: quantumlayer
+        command: ["--config", "/tmp/quantumlayer/config/quantumlayer01.yaml"]
+        volumes:
+            - ./config/quantumlayer/example01.yaml:/tmp/quantumlayer/config/quantumlayer01.yaml
+
+    qlayer02:
+        image: quantumlayer
+        command: ["--config", "/tmp/quantumlayer/config/quantumlayer02.yaml"]
+        volumes:
+            - ./config/quantumlayer/example02.yaml:/tmp/quantumlayer/config/quantumlayer02.yaml
+
+    qlayer03:
+        image: quantumlayer
+        command: ["--config", "/tmp/quantumlayer/config/quantumlayer03.yaml"]
+        volumes:
+            - ./config/quantumlayer/example03.yaml:/tmp/quantumlayer/config/quantumlayer03.yaml
+
+    qlayer04:
+        image: quantumlayer
+        command: ["--config", "/tmp/quantumlayer/config/quantumlayer04.yaml"]
+        volumes:
+            - ./config/quantumlayer/example04.yaml:/tmp/quantumlayer/config/quantumlayer04.yaml
+
+    qlayer05:
+        image: quantumlayer
+        command: ["--config", "/tmp/quantumlayer/config/quantumlayer05.yaml"]
+        volumes:
+            - ./config/quantumlayer/example05.yaml:/tmp/quantumlayer/config/quantumlayer05.yaml
+
+    qlayer06:
+        image: quantumlayer
+        command: ["--config", "/tmp/quantumlayer/config/quantumlayer06.yaml"]
+        volumes:
+            - ./config/quantumlayer/example06.yaml:/tmp/quantumlayer/config/quantumlayer06.yaml
+
+    qlayer07:
+        image: quantumlayer
+        command: ["--config", "/tmp/quantumlayer/config/quantumlayer07.yaml"]
+        volumes:
+            - ./config/quantumlayer/example07.yaml:/tmp/quantumlayer/config/quantumlayer07.yaml
+
+    qlayer08:
+        image: quantumlayer
+        command: ["--config", "/tmp/quantumlayer/config/quantumlayer08.yaml"]
+        volumes:
+            - ./config/quantumlayer/example08.yaml:/tmp/quantumlayer/config/quantumlayer08.yaml
+
+    akms-receiver01:
+        image: akms-simulator
+
+    akms-receiver02:
+        image: akms-simulator
+
+    qkdn-controller:
+        image: registry.code.fbi.h-da.de/demoquandt/qkdn-controller:qkdn-main
+        volumes:
+            - ./config/controller/qkdn-gosdn.toml:/app/configs/qkdn-gosdn.toml
+            - ./config/controller/gNMISubscriptions.txt:/app/configs/gNMISubscriptions.txt
+        command: --config ./configs/qkdn-gosdn.toml
+        ports:
+            - "127.0.0.1:55055:55055"
+        environment:
+            GOSDN_ADMIN_PASSWORD: TestPassword
+
+    gosdnc:
+        image: registry.code.fbi.h-da.de/demoquandt/qkdn-controller/gosdnc:qkdn-main
+        volumes:
+            - ./config/controller/add_devices.sh:/scripts/add_devices.sh
+        entrypoint: ["/scripts/add_devices.sh"]
+
+    plugin-registry:
+        image: registry.code.fbi.h-da.de/demoquandt/qkdn-controller/plugin-registry:qkdn-main
+
+    mongo:
+        image: mongo:7
+        environment:
+            MONGO_INITDB_ROOT_USERNAME: root
+            MONGO_INITDB_ROOT_PASSWORD: example
+
+    rabbitmq:
+        image: rabbitmq:3-management
+
+    routing-app:
+        image: registry.code.fbi.h-da.de/demoquandt/qkdn-controller/routing-app:qkdn-main
+        entrypoint: ["./start_ra_sleep.sh"]
+        volumes:
+            - ./config/controller/start_ra_sleep.sh:/app/start_ra_sleep.sh
+            - ./config/controller/routing-config.yaml:/new/routing-config.yaml
diff --git a/goKMS/gnmiHandlers/kms/keyStoreHandler.go b/goKMS/gnmiHandlers/kms/keyStoreHandler.go
index 11e1d66f..8697fb06 100644
--- a/goKMS/gnmiHandlers/kms/keyStoreHandler.go
+++ b/goKMS/gnmiHandlers/kms/keyStoreHandler.go
@@ -42,27 +42,7 @@ func (yh *KeyStoreHandler) Init(config *handler.Config, publishToSubsFunc func([
 		return err
 	}
 
-	yh.Config.Lock()
-	defer yh.Config.Unlock()
-
-	copyCurrentConfig, err := ygot.DeepCopy(yh.Config.Data)
-	if err != nil {
-		return err
-	}
-
-	newConfig, ok := copyCurrentConfig.(*gnmitargetygot.Gnmitarget)
-	if !ok {
-		return fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.OpenconfigInterfaces_Interfaces)(nil), copyCurrentConfig)
-	}
-
-	newConfig.GetOrCreateKeyStores()
-
-	//validate struct
-	if err := newConfig.Validate(); err != nil {
-		return err
-	}
-
-	yh.Config.Data = newConfig
+	yh.updateOrCreateKeyStores()
 
 	// Start the go routine that takes care of any update from the kms
 	go func() {
@@ -71,7 +51,7 @@ func (yh *KeyStoreHandler) Init(config *handler.Config, publishToSubsFunc func([
 			case <-yh.events:
 				log.Println("Update for key stores.")
 
-				diff, err := yh.updateOrCreateKeyStores(yh.kms)
+				diff, err := yh.updateOrCreateKeyStores()
 				if err != nil {
 					log.Errorf("Error within key stores subscription goroutine; %v", err)
 					break
@@ -90,7 +70,7 @@ func (yh *KeyStoreHandler) Update(c ygot.ValidatedGoStruct, jobs []*gnmi.Update)
 	return nil
 }
 
-func (yh *KeyStoreHandler) updateOrCreateKeyStores(kms *kms.KMS) ([]*gnmi.Notification, error) {
+func (yh *KeyStoreHandler) updateOrCreateKeyStores() ([]*gnmi.Notification, error) {
 	yh.Config.Lock()
 	defer yh.Config.Unlock()
 
@@ -104,7 +84,7 @@ func (yh *KeyStoreHandler) updateOrCreateKeyStores(kms *kms.KMS) ([]*gnmi.Notifi
 		return nil, fmt.Errorf("Wrong type, exptected: %T, got: %T", (*gnmitargetygot.Temp_KeyStores)(nil), copyCurrentConfig)
 	}
 
-	kmsPeers := kms.PeersDeepCopy()
+	kmsPeers := yh.kms.PeersDeepCopy()
 
 	confKeyStores := newConfig.GetOrCreateKeyStores()
 
diff --git a/goKMS/kms/kmsintercom.go b/goKMS/kms/kmsintercom.go
index 09c6bff8..344d20c8 100644
--- a/goKMS/kms/kmsintercom.go
+++ b/goKMS/kms/kmsintercom.go
@@ -128,7 +128,7 @@ func (s *kmsTalkerServer) SyncQkdBulk(ctx context.Context, in *pb.SyncQkdBulkReq
 		}
 	}
 
-	return nil, status.Errorf(codes.Unimplemented, "method SyncQkdBulk not implemented")
+	return nil, status.Errorf(codes.Internal, "Could not find a RawBulkKey that matches the provided IDs: %v", in.BulkId)
 }
 
 func (s *kmsTalkerServer) SyncKeyIdsForBulk(ctx context.Context, in *pb.SyncKeyIdsForBulkRequest) (*pb.SyncKeyIdsForBulkResponse, error) {
@@ -155,10 +155,8 @@ func (s *kmsTalkerServer) SyncKeyIdsForBulk(ctx context.Context, in *pb.SyncKeyI
 		return nil, status.Errorf(codes.Internal, "%v", err)
 	}
 
-	for keyId, key := range keyData {
-		if err := eqm.KeyStore().AddKey(keyId, key); err != nil {
-			log.Error(err)
-		}
+	if err := eqm.KeyStore().AddKeys(keyData); err != nil {
+		log.Error(err)
 	}
 
 	delete(eqm.RawBulkKeys, in.GetBulkId())
diff --git a/goKMS/kms/peers/danetQuantummodule.go b/goKMS/kms/peers/danetQuantummodule.go
index fd967f6b..b237a379 100644
--- a/goKMS/kms/peers/danetQuantummodule.go
+++ b/goKMS/kms/peers/danetQuantummodule.go
@@ -123,10 +123,8 @@ func (qm *DanetQuantumModule) Sync() error {
 		return err
 	}
 
-	for keyId, key := range keyData {
-		if err := qm.keyStore.AddKey(keyId, key); err != nil {
-			log.Error(err)
-		}
+	if err := qm.keyStore.AddKeys(keyData); err != nil {
+		log.Error(err)
 	}
 
 	qm.RawBulkKeysMutex.Lock()
diff --git a/goKMS/kms/quipsec.go b/goKMS/kms/quipsec.go
index da6c9c4e..4eb66b66 100644
--- a/goKMS/kms/quipsec.go
+++ b/goKMS/kms/quipsec.go
@@ -48,17 +48,23 @@ func (qs *quipSecServer) PushKeys(ctx context.Context, req *pb.PushKeysRequest)
 		return nil, status.Errorf(codes.Internal, "could not get bulkkeyid")
 	}
 
-	eqm.RawBulkKeysMutex.Lock()
-	defer eqm.RawBulkKeysMutex.Unlock()
 	if !eqm.IsActive() {
 		logrus.Debugf("Quantum module: %s is not active and denied incoming bulk keys", eqm.ID())
 		return nil, status.Errorf(codes.Aborted, "Currently no new bulk keys are accepted")
 	}
+	eqm.RawBulkKeysMutex.Lock()
 	eqm.RawBulkKeys[bulkKeyId] = &quantumlayer.QuantumLayerBulkKey{
 		BulkKeyId:     bulkKeyId,
 		BulkKeyLength: int(req.GetKeyBulk().GetKeyLength()),
 		BulkKey:       req.GetKeyBulk().Keys,
 	}
+	eqm.RawBulkKeysMutex.Unlock()
+
+	if eqm.KeyStore().Length() == 0 {
+		if err := eqm.Sync(); err != nil {
+			logrus.Error("Syncing key stores after a bulk key push failed; err: ", err)
+		}
+	}
 
 	logrus.Debugf("%s received a new bulk from: %s with id: %s and a length of: %d", qs.KMS.kmsName, qm.Address(), req.GetKeyBulk().GetKeyId(), req.GetKeyBulk().GetKeyLength())
 	return &pb.PushKeysResponse{Timestamp: time.Now().Unix()}, nil
diff --git a/goKMS/kms/store/kms-keystore.go b/goKMS/kms/store/kms-keystore.go
index 683c5634..297f1af5 100644
--- a/goKMS/kms/store/kms-keystore.go
+++ b/goKMS/kms/store/kms-keystore.go
@@ -50,7 +50,7 @@ func (ks *KmsKeyStore) Length() int {
 	return len(ks.keyStore)
 }
 
-func (ks *KmsKeyStore) AddKey(keyId uuid.UUID, keyToadd []byte) error {
+func (ks *KmsKeyStore) AddKey(keyId uuid.UUID, keyToAdd []byte) error {
 	ks.keyStoreMutex.Lock()
 	defer ks.keyStoreMutex.Unlock()
 
@@ -61,7 +61,7 @@ func (ks *KmsKeyStore) AddKey(keyId uuid.UUID, keyToadd []byte) error {
 
 	newKeyElement := &KmsKSElement{
 		KeyID:  keyId,
-		Key:    keyToadd,
+		Key:    keyToAdd,
 		Status: AVAILABLE,
 	}
 	// ok to add
@@ -77,6 +77,32 @@ func (ks *KmsKeyStore) AddKey(keyId uuid.UUID, keyToadd []byte) error {
 	return nil
 }
 
+func (ks *KmsKeyStore) AddKeys(keys map[uuid.UUID][]byte) error {
+	ks.keyStoreMutex.Lock()
+	defer ks.keyStoreMutex.Unlock()
+
+	// INFO: could be useful to also check for collisions
+
+	for keyId, keyToAdd := range keys {
+		newKeyElement := &KmsKSElement{
+			KeyID:  keyId,
+			Key:    keyToAdd,
+			Status: AVAILABLE,
+		}
+		// ok to add
+		ks.keyStore[newKeyElement.KeyID] = newKeyElement
+	}
+
+	// publish to eventBus
+	go func() {
+		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
+		if err != nil {
+			fmt.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+		}
+	}()
+	return nil
+}
+
 func (ks *KmsKeyStore) GetKey() (*KmsKSElement, error) {
 	ks.keyStoreMutex.Lock()
 	defer ks.keyStoreMutex.Unlock()
@@ -128,6 +154,7 @@ func (ks *KmsKeyStore) Reset() {
 }
 
 func AddETSIKeysToKeystore(keyStore *KmsKeyStore, keyContainer []etsi14.KeyContainerKeysInner) error {
+	keysToAdd := make(map[uuid.UUID][]byte)
 	for _, keyItem := range keyContainer {
 		// decode base64 encoded key string
 		key, err := base64.StdEncoding.DecodeString(keyItem.GetKey())
@@ -138,10 +165,11 @@ func AddETSIKeysToKeystore(keyStore *KmsKeyStore, keyContainer []etsi14.KeyConta
 		if err != nil {
 			return err
 		}
-		// add to keystore
-		if err := keyStore.AddKey(keyId, key); err != nil {
-			log.Error(err)
-		}
+		keysToAdd[keyId] = key
+	}
+	// add to keystore
+	if err := keyStore.AddKeys(keysToAdd); err != nil {
+		log.Error(err)
 	}
 	log.Debugf("Current key store length: %d", keyStore.Length())
 	return nil
-- 
GitLab


From f4bb08761807987f28c0c910f07354705fce779b Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@h-da.de>
Date: Wed, 19 Feb 2025 15:26:07 +0100
Subject: [PATCH 5/7] Linter pleasing

---
 goKMS/gnmiHandlers/kms/keyStoreHandler.go | 4 +++-
 goKMS/kms/store/kms-keystore.go           | 6 +++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/goKMS/gnmiHandlers/kms/keyStoreHandler.go b/goKMS/gnmiHandlers/kms/keyStoreHandler.go
index 8697fb06..b9be8da7 100644
--- a/goKMS/gnmiHandlers/kms/keyStoreHandler.go
+++ b/goKMS/gnmiHandlers/kms/keyStoreHandler.go
@@ -42,7 +42,9 @@ func (yh *KeyStoreHandler) Init(config *handler.Config, publishToSubsFunc func([
 		return err
 	}
 
-	yh.updateOrCreateKeyStores()
+	if _, err := yh.updateOrCreateKeyStores(); err != nil {
+		return err
+	}
 
 	// Start the go routine that takes care of any update from the kms
 	go func() {
diff --git a/goKMS/kms/store/kms-keystore.go b/goKMS/kms/store/kms-keystore.go
index 297f1af5..6a95b9e1 100644
--- a/goKMS/kms/store/kms-keystore.go
+++ b/goKMS/kms/store/kms-keystore.go
@@ -71,7 +71,7 @@ func (ks *KmsKeyStore) AddKey(keyId uuid.UUID, keyToAdd []byte) error {
 	go func() {
 		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
 		if err != nil {
-			fmt.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+			log.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
 		}
 	}()
 	return nil
@@ -97,7 +97,7 @@ func (ks *KmsKeyStore) AddKeys(keys map[uuid.UUID][]byte) error {
 	go func() {
 		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
 		if err != nil {
-			fmt.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+			log.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
 		}
 	}()
 	return nil
@@ -142,7 +142,7 @@ func (ks *KmsKeyStore) DeleteKey(keyId uuid.UUID) {
 	go func() {
 		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
 		if err != nil {
-			fmt.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+			log.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
 		}
 	}()
 }
-- 
GitLab


From 6630b437bbc47f447065bf07e43ed425fb351383 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@h-da.de>
Date: Wed, 19 Feb 2025 15:29:14 +0100
Subject: [PATCH 6/7] Linter pleasing

---
 goKMS/kms/store/kms-keystore.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/goKMS/kms/store/kms-keystore.go b/goKMS/kms/store/kms-keystore.go
index 6a95b9e1..1132e247 100644
--- a/goKMS/kms/store/kms-keystore.go
+++ b/goKMS/kms/store/kms-keystore.go
@@ -71,7 +71,7 @@ func (ks *KmsKeyStore) AddKey(keyId uuid.UUID, keyToAdd []byte) error {
 	go func() {
 		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
 		if err != nil {
-			log.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+			log.Errorf("Publishing a key store update through the eventBus failed, err: %s", err)
 		}
 	}()
 	return nil
@@ -97,7 +97,7 @@ func (ks *KmsKeyStore) AddKeys(keys map[uuid.UUID][]byte) error {
 	go func() {
 		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
 		if err != nil {
-			log.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+			log.Errorf("Publishing a key store update through the eventBus failed, err: %s", err)
 		}
 	}()
 	return nil
@@ -142,7 +142,7 @@ func (ks *KmsKeyStore) DeleteKey(keyId uuid.UUID) {
 	go func() {
 		err := ks.eventBus.Publish(event.NewKeyStoreEvent())
 		if err != nil {
-			log.Errorf("Publishing a key store update through the eventBus failed, err: %w", err)
+			log.Errorf("Publishing a key store update through the eventBus failed, err: %s", err)
 		}
 	}()
 }
-- 
GitLab


From 33ec4ac2382105da5b178a093d4a003c13b03fb9 Mon Sep 17 00:00:00 2001
From: Malte Bauch <malte.bauch@h-da.de>
Date: Wed, 19 Feb 2025 15:33:19 +0100
Subject: [PATCH 7/7] Bump glog to v1.2.4

---
 go.mod |  2 +-
 go.sum | 94 ++++++++++------------------------------------------------
 2 files changed, 17 insertions(+), 79 deletions(-)

diff --git a/go.mod b/go.mod
index e70ca39c..a42ecce2 100644
--- a/go.mod
+++ b/go.mod
@@ -27,7 +27,7 @@ require (
 	buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240221180331-f05a6f4403ce.1 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/go-ole/go-ole v1.3.0 // indirect
-	github.com/golang/glog v1.2.2 // indirect
+	github.com/golang/glog v1.2.4 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/google/go-cmp v0.6.0 // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
diff --git a/go.sum b/go.sum
index 3257a676..a179c122 100644
--- a/go.sum
+++ b/go.sum
@@ -27,12 +27,16 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
 github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
 github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY=
-github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
+github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=
+github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -64,8 +68,6 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
 github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
 github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
 github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -109,8 +111,6 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
@@ -120,6 +120,16 @@ github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDgu
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
 github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
+go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
+go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
+go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
+go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
+go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
+go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
+go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
+go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
+go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -143,12 +153,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
-golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
-golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
-golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
-golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
-golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
 golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
 golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -170,16 +174,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
-golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
-golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
-golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
-golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
-golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
 golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -188,10 +182,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
-golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
-golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
-golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
 golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -213,40 +203,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/genproto v0.0.0-20210811021853-ddbe55d93216/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
-google.golang.org/genproto/googleapis/api v0.0.0-20240820151423-278611b39280 h1:YDFM9oOjiFhaMAVgbDxfxW+66nRrsvzQzJ51wp3OxC0=
-google.golang.org/genproto/googleapis/api v0.0.0-20240820151423-278611b39280/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
-google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0=
-google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
-google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
-google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
 google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ=
 google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3 h1:9Xyg6I9IWQZhRVfCWjKK+l6kI0jHcPesVlMnT//aHNo=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a h1:hqK4+jJZXCU4pW7jsAdGOVFIfLHQeV7LaizZKnZ84HI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240725223205-93522f1f2a9f h1:RARaIm8pxYuxyNPbBQf5igT7XdOyCNtat1qAT2ZxjU4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240725223205-93522f1f2a9f/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c h1:Kqjm4WpoWvwhMPcrAczoTyMySQmYa9Wy2iL6Con4zn8=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -257,22 +215,6 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
 google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
-google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
-google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
-google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
-google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM=
-google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
-google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
-google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
-google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
-google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
-google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
-google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
-google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
-google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
-google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
-google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
 google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
 google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
@@ -290,10 +232,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
-google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
-google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
 google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
 google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-- 
GitLab