Skip to content

Updating State#

When processConfig function finished processing the configuration, we need to update the state datastore with the new values. We do this by calling the updateState 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
        }
    }
}

In SR Linux, the state data store contains both configuration and read-only elements, so we need to update the state datastore with the ConfigState struct that contains both the name and greeting values.

greeter/state.go
const greeterKeyPath = ".greeter"

func (a *App) updateState(ctx context.Context) {
    jsData, err := json.Marshal(a.configState)
    if err != nil {
        a.logger.Info().Msgf("failed to marshal json data: %v", err)
        return
    }

    a.telemetryAddOrUpdate(ctx, greeterKeyPath, string(jsData))
}

The updateState function first marshals the ConfigState struct to JSON and then calls telemetryAddOrUpdate function to post these changes to the state datastore.

Let's see what's inside the telemetryAddOrUpdate:

greeter/state.go
func (a *App) telemetryAddOrUpdate(ctx context.Context, jsPath string, jsData string) {
    a.logger.Info().Msgf("updating: %s: %s", jsPath, jsData)

    key := &ndk.TelemetryKey{JsPath: jsPath}
    data := &ndk.TelemetryData{JsonContent: jsData}
    info := &ndk.TelemetryInfo{Key: key, Data: data}
    req := &ndk.TelemetryUpdateRequest{
        State: []*ndk.TelemetryInfo{info},
    }

    a.logger.Info().Msgf("Telemetry Request: %+v", req)

    r1, err := a.TelemetryServiceClient.TelemetryAddOrUpdate(ctx, req)
    if err != nil {
        a.logger.Info().Msgf("Could not update telemetry key=%s: err=%v", jsPath, err)
        return
    }

    a.logger.Info().Msgf("Telemetry add/update status: %s, error_string: %q",
        r1.GetStatus().String(), r1.GetErrorStr())
}

As we covered in the Handling application's configuration and state section, NDK's Telemetry service provides the RPCs to add/update and delete data from SR Linux's state data store. We initialized the Telemetry service client when we created the application's instance at the very beginning of this tutorial, and now we use it to modify the state data.

First we craft the TelemetryUpdateRequest that has TelemetryInfo message nested in it, which contains the TelemetryKey and TelemetryData messages. The TelemetryKey message contains the path field that specifies the path to the state data element we want to update. The TelemetryData message contains the json field that contains the JSON representation of the data we want to add/update.

Our ConfigState struct was already marshaled to JSON, so we just need to set the json field of the TelemetryData message to the marshaled JSON and call TelemetryAddOrUpdate function of the Telemetry service client.

This will update the state data store with the new values.

Congratulations 🥳! You have successfully implemented the greeter application with bare NDK Go bindings and reached the end of this tutorial. Using bare NDK Go bindings without the srl-labs/bond helper package is not an easy task, therefore most likely you will use Bond to implement your applications.

Comments