Skip to content

Receiving Configuration#

For our application to work it needs to receive its own configuration from the SR Linux Management Server. This process is facilitated by the NDK and subscriptions to the configuration notifications.

In the NDK Operations section about Subscribing to Notifications we explained how NDK plays a somewhat "proxy" role for your application when it needs to receive updates from other SR Linux applications.

sequenceDiagram
    participant App as NDK App
    participant NDK as NDK Service
    participant IDB as Messaging bus<br/>IDB
    participant LLDP as LLDP Manager
    App->>NDK: I want to receive LLDP notifications
    NDK->>IDB: Subscribing to LLDP notifications
    LLDP-->>IDB: LLDP event
    IDB-->>NDK: LLDP event
    NDK-->>App: LLDP event

Our greeter app is no different, it needs to receive notifications from the NDK, but it only needs to receive a particular notification type - its own configuration updates.
Whenever we configure the /greeter/name leaf and commit the configuration, our app needs to receive updates and act on them.

It all begins in the Start function where we called a.receiveConfigNotifications(ctx) function.

greeter/app.go
func (a *App) Start(ctx context.Context) {
    go a.receiveConfigNotifications(ctx)

    for {
        select {
        case <-a.configReceivedCh:
            a.logger.Info().Msg("Received full config")

            a.processConfig(ctx)

            a.updateState(ctx)

        case <-ctx.Done():
            a.stop()
            return
        }
    }
}

We start this function in a goroutine because we want this function to signal when the full configuration has been received by writing to receivedCh channel. We will see how this is used later.

Inside the receiveConfigNotifications function we start by creating the Configuration Notification Stream; this is the stream of notifications about greeter's config.

greeter/config.go
func (a *App) receiveConfigNotifications(ctx context.Context) {
    configStream := a.StartConfigNotificationStream(ctx)

    for cfgStreamResp := range configStream {
        b, err := prototext.MarshalOptions{Multiline: true, Indent: "  "}.Marshal(cfgStreamResp)
        if err != nil {
            a.logger.Info().
                Msgf("Config notification Marshal failed: %+v", err)
            continue
        }

        a.logger.Info().
            Msgf("Received notifications:\n%s", b)

        a.handleConfigNotifications(cfgStreamResp)
    }
}

Then we start receiving notifications from the stream. For every received NotificationStreamResponse from the configStream channel we handle that notification with handleConfigNotifications function.

But first, let's understand how the notification stream is started in the next chapter.

Comments