diff --git a/goKMS/gnmiHandlers/kms/keyStoreHandler.go b/goKMS/gnmiHandlers/kms/keyStoreHandler.go index ddff4a7cc9d73a62a5adeec5a7228b7a4f04739e..11e1d66fc6f7f7e00640b2f06d184127f198662d 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 301b883b09fa8d71d10cfae043415fc5adad0e80..947c3aac882fb79a7a070647b9028d275808b2ca 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 b99faee99ccabaf0ca246dff53294935ce7961ac..c0a32e8418e44bf11431e72606aad8649af6e130 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 ef1a5212aa1933dc2ca104d64b72412bfb879c94..73a06671498ab6e2a8900d1bf1b2c0117f554972 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() {