Skip to content
Snippets Groups Projects
Commit 4409bde0 authored by Fabian Seidl's avatar Fabian Seidl
Browse files

Merge branch 'develop' into...

Merge branch 'develop' into 248-error-handling-in-event-publishing-via-entity-services-could-be-improved
parents 915a11ed 6fa76388
No related branches found
No related tags found
1 merge request!370Resolve "Error handling in event publishing via entity services could be improved"
Pipeline #117035 passed
This commit is part of merge request !370. Comments created here will be created in the context of that merge request.
...@@ -9,6 +9,7 @@ workflow: ...@@ -9,6 +9,7 @@ workflow:
- if: $CI_PIPELINE_SOURCE == 'push' - if: $CI_PIPELINE_SOURCE == 'push'
stages: stages:
- tools
- build - build
- test - test
- analyze - analyze
...@@ -25,3 +26,4 @@ include: ...@@ -25,3 +26,4 @@ include:
- local: "/.gitlab/ci/.integration-test-containerlab.yml" - local: "/.gitlab/ci/.integration-test-containerlab.yml"
- local: "/.gitlab/ci/.integration-test.yml" - local: "/.gitlab/ci/.integration-test.yml"
- local: "/.gitlab/ci/.uml-autogen-ci.yml" - local: "/.gitlab/ci/.uml-autogen-ci.yml"
- local: "/.gitlab/ci/.renovate.yml"
renovate:
stage: tools
image: renovate/renovate:32.127.0-slim@sha256:30824333e0978851f96ac8e58e7afa39aaf996de243f8bfcb1d7d6906b46488d
variables:
LOG_LEVEL: debug
only:
- schedules
script:
- renovate $RENOVATE_EXTRA_FLAGS
config.js 0 → 100644
Object.assign(process.env, {
GIT_AUTHOR_NAME: 'Renovate Bot',
GIT_AUTHOR_EMAIL: 'renovate@danet.fbi.h-da.de',
GIT_COMMITTER_NAME: 'Renovate Bot',
GIT_COMMITTER_EMAIL: 'renovate@danet.fbi.h-da.de',
});
module.exports = {
endpoint: process.env.CI_API_V4_URL,
hostRules: [
{
baseUrl: 'https://registry.code.fbi.h-da.de',
username: '@project_10161_bot',
password: process.env.GITLAB_REGISTRY_TOKEN,
},
],
platform: 'gitlab',
username: '@project_10161_bot',
gitAuthor: 'Renovate Bot <renovate@danet.fbi.h-da.de>',
autodiscover: true,
prConcurrentLimit: 10,
commitMessagePrefix: '[renovate]',
labels: ['renovate']
};
...@@ -128,7 +128,7 @@ func initialize() error { ...@@ -128,7 +128,7 @@ func initialize() error {
} }
c.networkElementWatcher = nucleus.NewNetworkElementWatcher(c.pndStore) c.networkElementWatcher = nucleus.NewNetworkElementWatcher(c.pndStore)
c.networkElementWatcher.SubToDevices(config.GetGnmiSubscriptionPaths(), nil) c.networkElementWatcher.SubToNetworkElements(config.GetGnmiSubscriptionPaths(), nil)
err = ensureDefaultRoleExists() err = ensureDefaultRoleExists()
if err != nil { if err != nil {
......
...@@ -35,7 +35,7 @@ func (e *AlreadyExistsError) Error() string { ...@@ -35,7 +35,7 @@ func (e *AlreadyExistsError) Error() string {
// InvalidUUIDError implements the Error interface and is called if a UUID is not valid. // InvalidUUIDError implements the Error interface and is called if a UUID is not valid.
type InvalidUUIDError struct { type InvalidUUIDError struct {
DeviceName string NetworkElementName string
} }
func (e *InvalidUUIDError) Error() string { func (e *InvalidUUIDError) Error() string {
...@@ -255,24 +255,24 @@ func (e AMQPMessageFailError) Error() string { ...@@ -255,24 +255,24 @@ func (e AMQPMessageFailError) Error() string {
// SubscribeResponseError implements the Error interface and is called if there is an issue during a ongoing // SubscribeResponseError implements the Error interface and is called if there is an issue during a ongoing
// gNMI Subscription. // gNMI Subscription.
type SubscribeResponseError struct { type SubscribeResponseError struct {
PndID string PndID string
DeviceID string NetworkElementID string
DeviceName string NetworkElementName string
Err string Err string
} }
func (e SubscribeResponseError) Error() string { func (e SubscribeResponseError) Error() string {
return fmt.Sprintf("Subscribe failed, PndID: %s, DeviceID: %s, DeviceName: %s, Internal error: %s", e.PndID, e.DeviceID, e.DeviceName, e.Err) return fmt.Sprintf("Subscribe failed, PndID: %s, NetworkElementID: %s, NetworkElementName: %s, Internal error: %s", e.PndID, e.NetworkElementID, e.NetworkElementName, e.Err)
} }
// SubscribeSyncResponseError implements the Error interface and is called if there is an issue syncing a // SubscribeSyncResponseError implements the Error interface and is called if there is an issue syncing a
// gNMI Subscription. // gNMI Subscription.
type SubscribeSyncResponseError struct { type SubscribeSyncResponseError struct {
PndID string PndID string
DeviceID string NetworkElementID string
DeviceName string NetworkElementName string
} }
func (e SubscribeSyncResponseError) Error() string { func (e SubscribeSyncResponseError) Error() string {
return fmt.Sprintf("Sync failed, PndID: %s, DeviceID: %s, DeviceName: %s", e.PndID, e.DeviceID, e.DeviceName) return fmt.Sprintf("Sync failed, PndID: %s, NetworkElementID: %s, NetworkElementName: %s", e.PndID, e.NetworkElementID, e.NetworkElementName)
} }
...@@ -32,8 +32,8 @@ type ( ...@@ -32,8 +32,8 @@ type (
// for distinguishing from which network element the information is from, to stop subscriptions and // for distinguishing from which network element the information is from, to stop subscriptions and
// error handling. // error handling.
type SubscriptionInformation struct { type SubscriptionInformation struct {
PndID string PndID string
DeviceID string NetworkElementID string
DeviceName string NetworkElementName string
StopContext context.Context StopContext context.Context
} }
...@@ -23,15 +23,15 @@ const ( ...@@ -23,15 +23,15 @@ const (
gNMIStreamMode string = "on_change" gNMIStreamMode string = "on_change"
) )
// NetworkElementWatcher is a component that subscribes to devices via gNMI from within the controller and handles // NetworkElementWatcher is a component that subscribes to network elements via gNMI from within the controller and handles
// responses by triggering the internal event process. // responses by triggering the internal event process.
type NetworkElementWatcher struct { type NetworkElementWatcher struct {
pndStore networkdomain.PndStore pndStore networkdomain.PndStore
deviceSubcriptions map[uuid.UUID]*deviceSubscriptionHelper networkelementSubcriptions map[uuid.UUID]*networkelementSubscriptionHelper
} }
// deviceSubscriptionHelper is used to store information to stop a running subscribe go routine. // networkelementSubscriptionHelper is used to store information to stop a running subscribe go routine.
type deviceSubscriptionHelper struct { type networkelementSubscriptionHelper struct {
stopSubscribeCtx context.Context stopSubscribeCtx context.Context
stopFunc context.CancelFunc stopFunc context.CancelFunc
} }
...@@ -39,15 +39,15 @@ type deviceSubscriptionHelper struct { ...@@ -39,15 +39,15 @@ type deviceSubscriptionHelper struct {
// NewNetworkElementWatcher takes a pndStore to subscribe to network element paths. // NewNetworkElementWatcher takes a pndStore to subscribe to network element paths.
func NewNetworkElementWatcher(pndStore networkdomain.PndStore) *NetworkElementWatcher { func NewNetworkElementWatcher(pndStore networkdomain.PndStore) *NetworkElementWatcher {
return &NetworkElementWatcher{ return &NetworkElementWatcher{
pndStore: pndStore, pndStore: pndStore,
deviceSubcriptions: make(map[uuid.UUID]*deviceSubscriptionHelper), networkelementSubcriptions: make(map[uuid.UUID]*networkelementSubscriptionHelper),
} }
} }
// SubToDevices subscribes to every available network element in each network domain according to provided SubscribeOptions. // SubToNetworkElements subscribes to every available network element in each network domain according to provided SubscribeOptions.
// Paths should be provided in the following format [][]string{{"system", "config", "hostname"}} // Paths should be provided in the following format [][]string{{"system", "config", "hostname"}}
// SubscribeOptions can be nil. Use nil for a fixed, pre-defined set of gNMI subscription options (streaming in sample mode each second). // SubscribeOptions can be nil. Use nil for a fixed, pre-defined set of gNMI subscription options (streaming in sample mode each second).
func (d *NetworkElementWatcher) SubToDevices(paths [][]string, opts *gnmi.SubscribeOptions) { func (n *NetworkElementWatcher) SubToNetworkElements(paths [][]string, opts *gnmi.SubscribeOptions) {
if opts == nil { if opts == nil {
opts = &gnmi.SubscribeOptions{ opts = &gnmi.SubscribeOptions{
Mode: gNMISubscribeMode, Mode: gNMISubscribeMode,
...@@ -57,102 +57,102 @@ func (d *NetworkElementWatcher) SubToDevices(paths [][]string, opts *gnmi.Subscr ...@@ -57,102 +57,102 @@ func (d *NetworkElementWatcher) SubToDevices(paths [][]string, opts *gnmi.Subscr
} }
} }
pnds, err := d.pndStore.GetAll() pnds, err := n.pndStore.GetAll()
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} }
for _, pnd := range pnds { for _, pnd := range pnds {
d.subscribeToPndDevices(pnd.ID().String(), pnd, opts) n.subscribeToPndNetworkElements(pnd.ID().String(), pnd, opts)
} }
} }
func (d *NetworkElementWatcher) subscribeToPndDevices(pndID string, pnd networkdomain.NetworkDomain, opts *gnmi.SubscribeOptions) { func (n *NetworkElementWatcher) subscribeToPndNetworkElements(pndID string, pnd networkdomain.NetworkDomain, opts *gnmi.SubscribeOptions) {
for _, mne := range pnd.NetworkElements() { for _, mne := range pnd.NetworkElements() {
subID := uuid.New() subID := uuid.New()
stopContext, cancel := context.WithCancel(context.Background()) stopContext, cancel := context.WithCancel(context.Background())
d.addToDeviceSubscriptions(subID, &deviceSubscriptionHelper{ n.addToNetworkElementSubscriptions(subID, &networkelementSubscriptionHelper{
stopSubscribeCtx: stopContext, stopSubscribeCtx: stopContext,
stopFunc: cancel, stopFunc: cancel,
}) })
go d.callSubscribe(stopContext, pndID, mne, opts) go n.callSubscribe(stopContext, pndID, mne, opts)
} }
} }
func (d *NetworkElementWatcher) callSubscribe(stopContext context.Context, pndID string, mne networkelement.NetworkElement, opts *gnmi.SubscribeOptions) { func (n *NetworkElementWatcher) callSubscribe(stopContext context.Context, pndID string, mne networkelement.NetworkElement, opts *gnmi.SubscribeOptions) {
gNMIOptionsCtx := context.Background() gNMIOptionsCtx := context.Background()
gNMIOptionsCtx = context.WithValue(gNMIOptionsCtx, types.CtxKeyOpts, opts) gNMIOptionsCtx = context.WithValue(gNMIOptionsCtx, types.CtxKeyOpts, opts)
// SubscriptionInformation contains pnd ID, network element ID and name to be used in the internal subscribe to check // SubscriptionInformation contains pnd ID, network element ID and name to be used in the internal subscribe to check
// from which network element a response was sent // from which network element a response was sent
if err := mne.Transport().ControlPlaneSubscribe(gNMIOptionsCtx, d.handleSubscribeResponse, &transport.SubscriptionInformation{ if err := mne.Transport().ControlPlaneSubscribe(gNMIOptionsCtx, n.handleSubscribeResponse, &transport.SubscriptionInformation{
PndID: pndID, PndID: pndID,
DeviceID: mne.ID().String(), NetworkElementID: mne.ID().String(),
DeviceName: mne.Name(), NetworkElementName: mne.Name(),
StopContext: stopContext, StopContext: stopContext,
}); err != nil { }); err != nil {
log.Error(err) log.Error(err)
} }
} }
func (d *NetworkElementWatcher) addToDeviceSubscriptions(subID uuid.UUID, devSub *deviceSubscriptionHelper) { func (n *NetworkElementWatcher) addToNetworkElementSubscriptions(subID uuid.UUID, devSub *networkelementSubscriptionHelper) {
//TODO: improve handling of subscriptions, like be able to expose to apps so specific subscriptions instead of only all can be stopped in the future //TODO: improve handling of subscriptions, like be able to expose to apps so specific subscriptions instead of only all can be stopped in the future
d.deviceSubcriptions[subID] = devSub n.networkelementSubcriptions[subID] = devSub
} }
// StopAndRemoveAllDeviceSubscriptions stops and removes all the available running subscriptions. // StopAndRemoveAllNetworkElementSubscriptions stops and removes all the available running subscriptions.
func (d *NetworkElementWatcher) StopAndRemoveAllDeviceSubscriptions() { func (n *NetworkElementWatcher) StopAndRemoveAllNetworkElementSubscriptions() {
for key := range d.deviceSubcriptions { for key := range n.networkelementSubcriptions {
d.StopAndRemoveDeviceSubscription(key) n.StopAndRemoveNetworkElementSubscription(key)
} }
} }
// StopAndRemoveDeviceSubscription passes a subscription uuid to stop the running subscription go routing and removes the entry from the map // StopAndRemoveNetworkElementSubscription passes a subscription uuid to stop the running subscription go routing and removes the entry from the map
// of network element subscriptions. // of network element subscriptions.
func (d *NetworkElementWatcher) StopAndRemoveDeviceSubscription(subID uuid.UUID) { func (n *NetworkElementWatcher) StopAndRemoveNetworkElementSubscription(subID uuid.UUID) {
d.deviceSubcriptions[subID].stopFunc() n.networkelementSubcriptions[subID].stopFunc()
delete(d.deviceSubcriptions, subID) delete(n.networkelementSubcriptions, subID)
} }
// handleSubscribeResponse takes the subscribe response and additional information about the network element to distinguish // handleSubscribeResponse takes the subscribe response and additional information about the network element to distinguish
// from which network element a subscribe response was sent including improved error handling. // from which network element a subscribe response was sent including improved error handling.
func (d *NetworkElementWatcher) handleSubscribeResponse(resp *gpb.SubscribeResponse, subscriptionInfo *transport.SubscriptionInformation) { func (n *NetworkElementWatcher) handleSubscribeResponse(resp *gpb.SubscribeResponse, subscriptionInfo *transport.SubscriptionInformation) {
switch resp := resp.Response.(type) { switch resp := resp.Response.(type) {
case *gpb.SubscribeResponse_Error: case *gpb.SubscribeResponse_Error:
log.Error(&customerrs.SubscribeResponseError{ log.Error(&customerrs.SubscribeResponseError{
PndID: subscriptionInfo.PndID, PndID: subscriptionInfo.PndID,
DeviceID: subscriptionInfo.DeviceID, NetworkElementID: subscriptionInfo.NetworkElementID,
DeviceName: subscriptionInfo.DeviceName, NetworkElementName: subscriptionInfo.NetworkElementName,
Err: fmt.Sprint("SubscribeResponse_Error"), Err: fmt.Sprint("SubscribeResponse_Error"),
}) })
case *gpb.SubscribeResponse_SyncResponse: case *gpb.SubscribeResponse_SyncResponse:
if !resp.SyncResponse { if !resp.SyncResponse {
log.Error(&customerrs.SubscribeSyncResponseError{ log.Error(&customerrs.SubscribeSyncResponseError{
PndID: subscriptionInfo.PndID, PndID: subscriptionInfo.PndID,
DeviceID: subscriptionInfo.DeviceID, NetworkElementID: subscriptionInfo.NetworkElementID,
DeviceName: subscriptionInfo.DeviceName, NetworkElementName: subscriptionInfo.NetworkElementName,
}) })
} }
case *gpb.SubscribeResponse_Update: case *gpb.SubscribeResponse_Update:
d.handleSubscribeResponseUpdate(resp, subscriptionInfo) n.handleSubscribeResponseUpdate(resp, subscriptionInfo)
default: default:
log.Infof("Invalid SubscribeResponse, %v", resp) log.Infof("Invalid SubscribeResponse, %v", resp)
} }
} }
func (d *NetworkElementWatcher) handleSubscribeResponseUpdate(resp *gpb.SubscribeResponse_Update, subscriptionInfo *transport.SubscriptionInformation) { func (n *NetworkElementWatcher) handleSubscribeResponseUpdate(resp *gpb.SubscribeResponse_Update, subscriptionInfo *transport.SubscriptionInformation) {
pndID, err := uuid.Parse(subscriptionInfo.PndID) pndID, err := uuid.Parse(subscriptionInfo.PndID)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} }
pnd, err := d.pndStore.Get(store.Query{ID: pndID}) pnd, err := n.pndStore.Get(store.Query{ID: pndID})
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} }
mne, err := pnd.GetNetworkElement(subscriptionInfo.DeviceID) mne, err := pnd.GetNetworkElement(subscriptionInfo.NetworkElementID)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} }
......
...@@ -21,7 +21,7 @@ func FromString(id string) (uuid.UUID, error) { ...@@ -21,7 +21,7 @@ func FromString(id string) (uuid.UUID, error) {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"identifier": id, "identifier": id,
}).Debug(err) }).Debug(err)
return uuid.Nil, &customerrs.InvalidUUIDError{DeviceName: id} return uuid.Nil, &customerrs.InvalidUUIDError{NetworkElementName: id}
} }
return idAsUUID, nil return idAsUUID, nil
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment