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:
- if: $CI_PIPELINE_SOURCE == 'push'
stages:
- tools
- build
- test
- analyze
......@@ -25,3 +26,4 @@ include:
- local: "/.gitlab/ci/.integration-test-containerlab.yml"
- local: "/.gitlab/ci/.integration-test.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 {
}
c.networkElementWatcher = nucleus.NewNetworkElementWatcher(c.pndStore)
c.networkElementWatcher.SubToDevices(config.GetGnmiSubscriptionPaths(), nil)
c.networkElementWatcher.SubToNetworkElements(config.GetGnmiSubscriptionPaths(), nil)
err = ensureDefaultRoleExists()
if err != nil {
......
......@@ -35,7 +35,7 @@ func (e *AlreadyExistsError) Error() string {
// InvalidUUIDError implements the Error interface and is called if a UUID is not valid.
type InvalidUUIDError struct {
DeviceName string
NetworkElementName string
}
func (e *InvalidUUIDError) 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
// gNMI Subscription.
type SubscribeResponseError struct {
PndID string
DeviceID string
DeviceName string
Err string
PndID string
NetworkElementID string
NetworkElementName string
Err 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
// gNMI Subscription.
type SubscribeSyncResponseError struct {
PndID string
DeviceID string
DeviceName string
PndID string
NetworkElementID string
NetworkElementName 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 (
// for distinguishing from which network element the information is from, to stop subscriptions and
// error handling.
type SubscriptionInformation struct {
PndID string
DeviceID string
DeviceName string
StopContext context.Context
PndID string
NetworkElementID string
NetworkElementName string
StopContext context.Context
}
......@@ -23,15 +23,15 @@ const (
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.
type NetworkElementWatcher struct {
pndStore networkdomain.PndStore
deviceSubcriptions map[uuid.UUID]*deviceSubscriptionHelper
pndStore networkdomain.PndStore
networkelementSubcriptions map[uuid.UUID]*networkelementSubscriptionHelper
}
// deviceSubscriptionHelper is used to store information to stop a running subscribe go routine.
type deviceSubscriptionHelper struct {
// networkelementSubscriptionHelper is used to store information to stop a running subscribe go routine.
type networkelementSubscriptionHelper struct {
stopSubscribeCtx context.Context
stopFunc context.CancelFunc
}
......@@ -39,15 +39,15 @@ type deviceSubscriptionHelper struct {
// NewNetworkElementWatcher takes a pndStore to subscribe to network element paths.
func NewNetworkElementWatcher(pndStore networkdomain.PndStore) *NetworkElementWatcher {
return &NetworkElementWatcher{
pndStore: pndStore,
deviceSubcriptions: make(map[uuid.UUID]*deviceSubscriptionHelper),
pndStore: pndStore,
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"}}
// 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 {
opts = &gnmi.SubscribeOptions{
Mode: gNMISubscribeMode,
......@@ -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 {
log.Error(err)
}
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() {
subID := uuid.New()
stopContext, cancel := context.WithCancel(context.Background())
d.addToDeviceSubscriptions(subID, &deviceSubscriptionHelper{
n.addToNetworkElementSubscriptions(subID, &networkelementSubscriptionHelper{
stopSubscribeCtx: stopContext,
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.WithValue(gNMIOptionsCtx, types.CtxKeyOpts, opts)
// 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
if err := mne.Transport().ControlPlaneSubscribe(gNMIOptionsCtx, d.handleSubscribeResponse, &transport.SubscriptionInformation{
PndID: pndID,
DeviceID: mne.ID().String(),
DeviceName: mne.Name(),
StopContext: stopContext,
if err := mne.Transport().ControlPlaneSubscribe(gNMIOptionsCtx, n.handleSubscribeResponse, &transport.SubscriptionInformation{
PndID: pndID,
NetworkElementID: mne.ID().String(),
NetworkElementName: mne.Name(),
StopContext: stopContext,
}); err != nil {
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
d.deviceSubcriptions[subID] = devSub
n.networkelementSubcriptions[subID] = devSub
}
// StopAndRemoveAllDeviceSubscriptions stops and removes all the available running subscriptions.
func (d *NetworkElementWatcher) StopAndRemoveAllDeviceSubscriptions() {
for key := range d.deviceSubcriptions {
d.StopAndRemoveDeviceSubscription(key)
// StopAndRemoveAllNetworkElementSubscriptions stops and removes all the available running subscriptions.
func (n *NetworkElementWatcher) StopAndRemoveAllNetworkElementSubscriptions() {
for key := range n.networkelementSubcriptions {
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.
func (d *NetworkElementWatcher) StopAndRemoveDeviceSubscription(subID uuid.UUID) {
d.deviceSubcriptions[subID].stopFunc()
delete(d.deviceSubcriptions, subID)
func (n *NetworkElementWatcher) StopAndRemoveNetworkElementSubscription(subID uuid.UUID) {
n.networkelementSubcriptions[subID].stopFunc()
delete(n.networkelementSubcriptions, subID)
}
// 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.
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) {
case *gpb.SubscribeResponse_Error:
log.Error(&customerrs.SubscribeResponseError{
PndID: subscriptionInfo.PndID,
DeviceID: subscriptionInfo.DeviceID,
DeviceName: subscriptionInfo.DeviceName,
Err: fmt.Sprint("SubscribeResponse_Error"),
PndID: subscriptionInfo.PndID,
NetworkElementID: subscriptionInfo.NetworkElementID,
NetworkElementName: subscriptionInfo.NetworkElementName,
Err: fmt.Sprint("SubscribeResponse_Error"),
})
case *gpb.SubscribeResponse_SyncResponse:
if !resp.SyncResponse {
log.Error(&customerrs.SubscribeSyncResponseError{
PndID: subscriptionInfo.PndID,
DeviceID: subscriptionInfo.DeviceID,
DeviceName: subscriptionInfo.DeviceName,
PndID: subscriptionInfo.PndID,
NetworkElementID: subscriptionInfo.NetworkElementID,
NetworkElementName: subscriptionInfo.NetworkElementName,
})
}
case *gpb.SubscribeResponse_Update:
d.handleSubscribeResponseUpdate(resp, subscriptionInfo)
n.handleSubscribeResponseUpdate(resp, subscriptionInfo)
default:
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)
if err != nil {
log.Error(err)
}
pnd, err := d.pndStore.Get(store.Query{ID: pndID})
pnd, err := n.pndStore.Get(store.Query{ID: pndID})
if err != nil {
log.Error(err)
}
mne, err := pnd.GetNetworkElement(subscriptionInfo.DeviceID)
mne, err := pnd.GetNetworkElement(subscriptionInfo.NetworkElementID)
if err != nil {
log.Error(err)
}
......
......@@ -21,7 +21,7 @@ func FromString(id string) (uuid.UUID, error) {
log.WithFields(log.Fields{
"identifier": id,
}).Debug(err)
return uuid.Nil, &customerrs.InvalidUUIDError{DeviceName: id}
return uuid.Nil, &customerrs.InvalidUUIDError{NetworkElementName: id}
}
return idAsUUID, nil
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment