[VOL-3199] Added support for dynamic enable/disable of Trace Publishing for running components
Change-Id: Iddf7d04e4795a3c64abca216e9f106953c76601e
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/common.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/common.go
index 37e05fd..a69e290 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/common.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/common.go
@@ -19,12 +19,12 @@
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
-var logger log.Logger
+var logger log.CLogger
func init() {
// Setup this package so that it's log level can be modified at run time
var err error
- logger, err = log.AddPackage(log.JSON, log.ErrorLevel, log.Fields{"pkg": "config"})
+ logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
if err != nil {
panic(err)
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/configmanager.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/configmanager.go
index 24988be..9ea86f7 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/configmanager.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/configmanager.go
@@ -41,10 +41,11 @@
ConfigTypeLogLevel ConfigType = iota
ConfigTypeMetadata
ConfigTypeKafka
+ ConfigTypeLogFeatures
)
func (c ConfigType) String() string {
- return [...]string{"loglevel", "metadata", "kafka"}[c]
+ return [...]string{"loglevel", "metadata", "kafka", "logfeatures"}[c]
}
// ChangeEvent represents the event recieved from watch
@@ -96,14 +97,14 @@
kvStoreEventChan chan *kvstore.Event
}
-func NewConfigManager(kvClient kvstore.Client, kvStoreType, kvStoreAddress string, kvStoreTimeout time.Duration) *ConfigManager {
+func NewConfigManager(ctx context.Context, kvClient kvstore.Client, kvStoreType, kvStoreAddress string, kvStoreTimeout time.Duration) *ConfigManager {
var kvStorePrefix string
if prefix, present := os.LookupEnv("KV_STORE_DATAPATH_PREFIX"); present {
kvStorePrefix = prefix
- logger.Infow("KV_STORE_DATAPATH_PREFIX env variable is set, ", log.Fields{"kvStoreDataPathPrefix": kvStorePrefix})
+ logger.Infow(ctx, "KV_STORE_DATAPATH_PREFIX env variable is set, ", log.Fields{"kvStoreDataPathPrefix": kvStorePrefix})
} else {
kvStorePrefix = defaultkvStoreDataPathPrefix
- logger.Infow("KV_STORE_DATAPATH_PREFIX env variable is not set, using default", log.Fields{"kvStoreDataPathPrefix": defaultkvStoreDataPathPrefix})
+ logger.Infow(ctx, "KV_STORE_DATAPATH_PREFIX env variable is not set, using default", log.Fields{"kvStoreDataPathPrefix": defaultkvStoreDataPathPrefix})
}
return &ConfigManager{
KVStoreConfigPrefix: defaultkvStoreConfigPath,
@@ -176,31 +177,31 @@
func (c *ComponentConfig) MonitorForConfigChange(ctx context.Context) chan *ConfigChangeEvent {
key := c.makeConfigPath()
- logger.Debugw("monitoring-for-config-change", log.Fields{"key": key})
+ logger.Debugw(ctx, "monitoring-for-config-change", log.Fields{"key": key})
c.changeEventChan = make(chan *ConfigChangeEvent, 1)
c.kvStoreEventChan = c.cManager.Backend.CreateWatch(ctx, key, true)
- go c.processKVStoreWatchEvents()
+ go c.processKVStoreWatchEvents(ctx)
return c.changeEventChan
}
// processKVStoreWatchEvents process event channel recieved from the Backend for any ChangeType
// It checks for the EventType is valid or not.For the valid EventTypes creates ConfigChangeEvent and send it on channel
-func (c *ComponentConfig) processKVStoreWatchEvents() {
+func (c *ComponentConfig) processKVStoreWatchEvents(ctx context.Context) {
ccKeyPrefix := c.makeConfigPath()
- logger.Debugw("processing-kvstore-event-change", log.Fields{"key-prefix": ccKeyPrefix})
+ logger.Debugw(ctx, "processing-kvstore-event-change", log.Fields{"key-prefix": ccKeyPrefix})
ccPathPrefix := c.cManager.Backend.PathPrefix + ccKeyPrefix + kvStorePathSeparator
for watchResp := range c.kvStoreEventChan {
if watchResp.EventType == kvstore.CONNECTIONDOWN || watchResp.EventType == kvstore.UNKNOWN {
- logger.Warnw("received-invalid-change-type-in-watch-channel-from-kvstore", log.Fields{"change-type": watchResp.EventType})
+ logger.Warnw(ctx, "received-invalid-change-type-in-watch-channel-from-kvstore", log.Fields{"change-type": watchResp.EventType})
continue
}
@@ -220,7 +221,7 @@
func (c *ComponentConfig) Retrieve(ctx context.Context, configKey string) (string, error) {
key := c.makeConfigPath() + "/" + configKey
- logger.Debugw("retrieving-config", log.Fields{"key": key})
+ logger.Debugw(ctx, "retrieving-config", log.Fields{"key": key})
if kvpair, err := c.cManager.Backend.Get(ctx, key); err != nil {
return "", err
@@ -230,7 +231,7 @@
}
value := strings.Trim(fmt.Sprintf("%s", kvpair.Value), "\"")
- logger.Debugw("retrieved-config", log.Fields{"key": key, "value": value})
+ logger.Debugw(ctx, "retrieved-config", log.Fields{"key": key, "value": value})
return value, nil
}
}
@@ -238,7 +239,7 @@
func (c *ComponentConfig) RetrieveAll(ctx context.Context) (map[string]string, error) {
key := c.makeConfigPath()
- logger.Debugw("retreiving-list", log.Fields{"key": key})
+ logger.Debugw(ctx, "retreiving-list", log.Fields{"key": key})
data, err := c.cManager.Backend.List(ctx, key)
if err != nil {
@@ -261,7 +262,7 @@
func (c *ComponentConfig) Save(ctx context.Context, configKey string, configValue string) error {
key := c.makeConfigPath() + "/" + configKey
- logger.Debugw("saving-config", log.Fields{"key": key, "value": configValue})
+ logger.Debugw(ctx, "saving-config", log.Fields{"key": key, "value": configValue})
//save the data for update config
if err := c.cManager.Backend.Put(ctx, key, configValue); err != nil {
@@ -274,7 +275,7 @@
//construct key using makeConfigPath
key := c.makeConfigPath() + "/" + configKey
- logger.Debugw("deleting-config", log.Fields{"key": key})
+ logger.Debugw(ctx, "deleting-config", log.Fields{"key": key})
//delete the config
if err := c.cManager.Backend.Delete(ctx, key); err != nil {
return err
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/logcontroller.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/logcontroller.go
index b00569f..f83e383 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/logcontroller.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/logcontroller.go
@@ -51,9 +51,8 @@
initialLogLevel string // Initial default log level set by helm chart
}
-func NewComponentLogController(cm *ConfigManager) (*ComponentLogController, error) {
-
- logger.Debug("creating-new-component-log-controller")
+func NewComponentLogController(ctx context.Context, cm *ConfigManager) (*ComponentLogController, error) {
+ logger.Debug(ctx, "creating-new-component-log-controller")
componentName := os.Getenv("COMPONENT_NAME")
if componentName == "" {
return nil, errors.New("Unable to retrieve PoD Component Name from Runtime env")
@@ -80,17 +79,17 @@
// Then, it persists initial default Loglevels into Config Store before
// starting the loading and processing of all Log Configuration
func StartLogLevelConfigProcessing(cm *ConfigManager, ctx context.Context) {
- cc, err := NewComponentLogController(cm)
+ cc, err := NewComponentLogController(ctx, cm)
if err != nil {
- logger.Errorw("unable-to-construct-component-log-controller-instance-for-log-config-monitoring", log.Fields{"error": err})
+ logger.Errorw(ctx, "unable-to-construct-component-log-controller-instance-for-log-config-monitoring", log.Fields{"error": err})
return
}
cc.GlobalConfig = cm.InitComponentConfig(globalConfigRootNode, ConfigTypeLogLevel)
- logger.Debugw("global-log-config", log.Fields{"cc-global-config": cc.GlobalConfig})
+ logger.Debugw(ctx, "global-log-config", log.Fields{"cc-global-config": cc.GlobalConfig})
cc.componentNameConfig = cm.InitComponentConfig(cc.ComponentName, ConfigTypeLogLevel)
- logger.Debugw("component-log-config", log.Fields{"cc-component-name-config": cc.componentNameConfig})
+ logger.Debugw(ctx, "component-log-config", log.Fields{"cc-component-name-config": cc.componentNameConfig})
cc.persistInitialDefaultLogConfigs(ctx)
@@ -105,21 +104,21 @@
_, err := c.GlobalConfig.Retrieve(ctx, defaultLogLevelKey)
if err != nil {
- logger.Debugw("failed-to-retrieve-global-default-log-config-at-startup", log.Fields{"error": err})
+ logger.Debugw(ctx, "failed-to-retrieve-global-default-log-config-at-startup", log.Fields{"error": err})
err = c.GlobalConfig.Save(ctx, defaultLogLevelKey, initialGlobalDefaultLogLevelValue)
if err != nil {
- logger.Errorw("failed-to-persist-global-default-log-config-at-startup", log.Fields{"error": err, "loglevel": initialGlobalDefaultLogLevelValue})
+ logger.Errorw(ctx, "failed-to-persist-global-default-log-config-at-startup", log.Fields{"error": err, "loglevel": initialGlobalDefaultLogLevelValue})
}
}
_, err = c.componentNameConfig.Retrieve(ctx, defaultLogLevelKey)
if err != nil {
- logger.Debugw("failed-to-retrieve-component-default-log-config-at-startup", log.Fields{"error": err})
+ logger.Debugw(ctx, "failed-to-retrieve-component-default-log-config-at-startup", log.Fields{"error": err})
err = c.componentNameConfig.Save(ctx, defaultLogLevelKey, c.initialLogLevel)
if err != nil {
- logger.Errorw("failed-to-persist-component-default-log-config-at-startup", log.Fields{"error": err, "loglevel": c.initialLogLevel})
+ logger.Errorw(ctx, "failed-to-persist-component-default-log-config-at-startup", log.Fields{"error": err, "loglevel": c.initialLogLevel})
}
}
}
@@ -129,7 +128,7 @@
func (c *ComponentLogController) persistRegisteredLogPackageList(ctx context.Context) {
componentMetadataConfig := c.configManager.InitComponentConfig(c.ComponentName, ConfigTypeMetadata)
- logger.Debugw("component-metadata-config", log.Fields{"component-metadata-config": componentMetadataConfig})
+ logger.Debugw(ctx, "component-metadata-config", log.Fields{"component-metadata-config": componentMetadataConfig})
packageList := log.GetPackageNames()
packageList = append(packageList, defaultLogLevelKey)
@@ -137,12 +136,12 @@
packageNames, err := json.Marshal(packageList)
if err != nil {
- logger.Errorw("failed-to-marshal-log-package-list-for-storage", log.Fields{"error": err, "packageList": packageList})
+ logger.Errorw(ctx, "failed-to-marshal-log-package-list-for-storage", log.Fields{"error": err, "packageList": packageList})
return
}
if err := componentMetadataConfig.Save(ctx, logPackagesListKey, string(packageNames)); err != nil {
- logger.Errorw("failed-to-persist-component-registered-log-package-list-at-startup", log.Fields{"error": err, "packageNames": packageNames})
+ logger.Errorw(ctx, "failed-to-persist-component-registered-log-package-list-at-startup", log.Fields{"error": err, "packageNames": packageNames})
}
}
@@ -155,10 +154,10 @@
// Load and apply Log Config for first time
initialLogConfig, err := c.buildUpdatedLogConfig(ctx)
if err != nil {
- logger.Warnw("unable-to-load-log-config-at-startup", log.Fields{"error": err})
+ logger.Warnw(ctx, "unable-to-load-log-config-at-startup", log.Fields{"error": err})
} else {
- if err := c.loadAndApplyLogConfig(initialLogConfig); err != nil {
- logger.Warnw("unable-to-apply-log-config-at-startup", log.Fields{"error": err})
+ if err := c.loadAndApplyLogConfig(ctx, initialLogConfig); err != nil {
+ logger.Warnw(ctx, "unable-to-apply-log-config-at-startup", log.Fields{"error": err})
}
}
@@ -174,25 +173,25 @@
case configEvent = <-componentConfigEventChan:
}
- logger.Debugw("processing-log-config-change", log.Fields{"ChangeType": configEvent.ChangeType, "Package": configEvent.ConfigAttribute})
+ logger.Debugw(ctx, "processing-log-config-change", log.Fields{"ChangeType": configEvent.ChangeType, "Package": configEvent.ConfigAttribute})
updatedLogConfig, err := c.buildUpdatedLogConfig(ctx)
if err != nil {
- logger.Warnw("unable-to-fetch-updated-log-config", log.Fields{"error": err})
+ logger.Warnw(ctx, "unable-to-fetch-updated-log-config", log.Fields{"error": err})
continue
}
- logger.Debugw("applying-updated-log-config", log.Fields{"updated-log-config": updatedLogConfig})
+ logger.Debugw(ctx, "applying-updated-log-config", log.Fields{"updated-log-config": updatedLogConfig})
- if err := c.loadAndApplyLogConfig(updatedLogConfig); err != nil {
- logger.Warnw("unable-to-load-and-apply-log-config", log.Fields{"error": err})
+ if err := c.loadAndApplyLogConfig(ctx, updatedLogConfig); err != nil {
+ logger.Warnw(ctx, "unable-to-load-and-apply-log-config", log.Fields{"error": err})
}
}
}
// get active loglevel from the zap logger
-func getActiveLogLevels() map[string]string {
+func getActiveLogLevels(ctx context.Context) map[string]string {
loglevels := make(map[string]string)
// now do the default log level
@@ -204,7 +203,7 @@
for _, packageName := range log.GetPackageNames() {
level, err := log.GetPackageLogLevel(packageName)
if err != nil {
- logger.Warnw("unable-to-fetch-current-active-loglevel-for-package-name", log.Fields{"package-name": packageName, "error": err})
+ logger.Warnw(ctx, "unable-to-fetch-current-active-loglevel-for-package-name", log.Fields{"package-name": packageName, "error": err})
continue
}
@@ -213,7 +212,7 @@
}
}
- logger.Debugw("retreived-log-levels-from-zap-logger", log.Fields{"loglevels": loglevels})
+ logger.Debugw(ctx, "retreived-log-levels-from-zap-logger", log.Fields{"loglevels": loglevels})
return loglevels
}
@@ -228,16 +227,16 @@
// Handle edge cases when global default loglevel is deleted directly from etcd or set to a invalid value
// We should use hard-coded initial default value in such cases
if globalDefaultLogLevel == "" {
- logger.Warn("global-default-loglevel-not-found-in-config-store")
+ logger.Warn(ctx, "global-default-loglevel-not-found-in-config-store")
globalDefaultLogLevel = initialGlobalDefaultLogLevelValue
}
if _, err := log.StringToLogLevel(globalDefaultLogLevel); err != nil {
- logger.Warnw("unsupported-loglevel-config-defined-at-global-default", log.Fields{"log-level": globalDefaultLogLevel})
+ logger.Warnw(ctx, "unsupported-loglevel-config-defined-at-global-default", log.Fields{"log-level": globalDefaultLogLevel})
globalDefaultLogLevel = initialGlobalDefaultLogLevelValue
}
- logger.Debugw("retrieved-global-default-loglevel", log.Fields{"level": globalDefaultLogLevel})
+ logger.Debugw(ctx, "retrieved-global-default-loglevel", log.Fields{"level": globalDefaultLogLevel})
return globalDefaultLogLevel, nil
}
@@ -251,7 +250,7 @@
effectiveDefaultLogLevel := ""
for logConfigKey, logConfigValue := range componentLogConfig {
if _, err := log.StringToLogLevel(logConfigValue); err != nil || logConfigKey == "" {
- logger.Warnw("unsupported-loglevel-config-defined-at-component-context", log.Fields{"package-name": logConfigKey, "log-level": logConfigValue})
+ logger.Warnw(ctx, "unsupported-loglevel-config-defined-at-component-context", log.Fields{"package-name": logConfigKey, "log-level": logConfigValue})
delete(componentLogConfig, logConfigKey)
} else {
if logConfigKey == defaultLogLevelKey {
@@ -268,7 +267,7 @@
componentLogConfig[defaultLogLevelKey] = effectiveDefaultLogLevel
- logger.Debugw("retrieved-component-log-config", log.Fields{"component-log-level": componentLogConfig})
+ logger.Debugw(ctx, "retrieved-component-log-config", log.Fields{"component-log-level": componentLogConfig})
return componentLogConfig, nil
}
@@ -282,7 +281,7 @@
func (c *ComponentLogController) buildUpdatedLogConfig(ctx context.Context) (map[string]string, error) {
globalLogLevel, err := c.getGlobalLogConfig(ctx)
if err != nil {
- logger.Errorw("unable-to-retrieve-global-log-config", log.Fields{"err": err})
+ logger.Errorw(ctx, "unable-to-retrieve-global-log-config", log.Fields{"err": err})
}
componentLogConfig, err := c.getComponentLogConfig(ctx, globalLogLevel)
@@ -302,17 +301,17 @@
// create hash of loaded configuration using GenerateLogConfigHash
// if there is previous hash stored, compare the hash to stored hash
// if there is any change will call UpdateLogLevels
-func (c *ComponentLogController) loadAndApplyLogConfig(logConfig map[string]string) error {
+func (c *ComponentLogController) loadAndApplyLogConfig(ctx context.Context, logConfig map[string]string) error {
currentLogHash, err := GenerateLogConfigHash(logConfig)
if err != nil {
return err
}
if c.logHash != currentLogHash {
- UpdateLogLevels(logConfig)
+ updateLogLevels(ctx, logConfig)
c.logHash = currentLogHash
} else {
- logger.Debug("effective-loglevel-config-same-as-currently-active")
+ logger.Debug(ctx, "effective-loglevel-config-same-as-currently-active")
}
return nil
@@ -322,7 +321,7 @@
// to identify and create map of modified Log Levels of 2 types:
// - Packages for which log level has been changed
// - Packages for which log level config has been cleared - set to default log level
-func createModifiedLogLevels(activeLogLevels, updatedLogLevels map[string]string) map[string]string {
+func createModifiedLogLevels(ctx context.Context, activeLogLevels, updatedLogLevels map[string]string) map[string]string {
defaultLevel := updatedLogLevels[defaultLogLevelKey]
modifiedLogLevels := make(map[string]string)
@@ -339,7 +338,7 @@
// Log warnings for all invalid packages for which log config has been set
for key, value := range updatedLogLevels {
if _, exist := activeLogLevels[key]; !exist {
- logger.Warnw("ignoring-loglevel-set-for-invalid-package", log.Fields{"package": key, "log-level": value})
+ logger.Warnw(ctx, "ignoring-loglevel-set-for-invalid-package", log.Fields{"package": key, "log-level": value})
}
}
@@ -349,18 +348,18 @@
// updateLogLevels update the loglevels for the component
// retrieve active confguration from logger
// compare with entries one by one and apply
-func UpdateLogLevels(updatedLogConfig map[string]string) {
+func updateLogLevels(ctx context.Context, updatedLogConfig map[string]string) {
- activeLogLevels := getActiveLogLevels()
- changedLogLevels := createModifiedLogLevels(activeLogLevels, updatedLogConfig)
+ activeLogLevels := getActiveLogLevels(ctx)
+ changedLogLevels := createModifiedLogLevels(ctx, activeLogLevels, updatedLogConfig)
// If no changed log levels are found, just return. It may happen on configuration of a invalid package
if len(changedLogLevels) == 0 {
- logger.Debug("no-change-in-effective-loglevel-config")
+ logger.Debug(ctx, "no-change-in-effective-loglevel-config")
return
}
- logger.Debugw("applying-log-level-for-modified-packages", log.Fields{"changed-log-levels": changedLogLevels})
+ logger.Debugw(ctx, "applying-log-level-for-modified-packages", log.Fields{"changed-log-levels": changedLogLevels})
for key, level := range changedLogLevels {
if key == defaultLogLevelKey {
if l, err := log.StringToLogLevel(level); err == nil {
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/logfeaturescontroller.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/logfeaturescontroller.go
new file mode 100644
index 0000000..a0d77b8
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/config/logfeaturescontroller.go
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package config
+
+import (
+ "context"
+ "errors"
+ "github.com/opencord/voltha-lib-go/v3/pkg/log"
+ "os"
+ "strings"
+)
+
+const (
+ defaultTracingStatusKey = "trace_publish" // kvstore key containing tracing configuration status
+)
+
+// ComponentLogFeatureController represents Configuration for Logging related features of Tracing and Log
+// Correlation of specific Voltha component.
+type ComponentLogFeaturesController struct {
+ ComponentName string
+ componentNameConfig *ComponentConfig
+ configManager *ConfigManager
+ initialTracingStatus bool // Initial default tracing status set by helm chart
+}
+
+func NewComponentLogFeaturesController(ctx context.Context, cm *ConfigManager) (*ComponentLogFeaturesController, error) {
+ logger.Debug(ctx, "creating-new-component-log-features-controller")
+ componentName := os.Getenv("COMPONENT_NAME")
+ if componentName == "" {
+ return nil, errors.New("Unable to retrieve PoD Component Name from Runtime env")
+ }
+
+ tracingStatus := log.GetGlobalLFM().GetTracePublishingStatus()
+
+ return &ComponentLogFeaturesController{
+ ComponentName: componentName,
+ componentNameConfig: nil,
+ configManager: cm,
+ initialTracingStatus: tracingStatus,
+ }, nil
+
+}
+
+// StartLogFeaturesConfigProcessing persists initial config of Log Features into Config Store before
+// starting the loading and processing of Configuration updates
+func StartLogFeaturesConfigProcessing(cm *ConfigManager, ctx context.Context) {
+ cc, err := NewComponentLogFeaturesController(ctx, cm)
+ if err != nil {
+ logger.Errorw(ctx, "unable-to-construct-component-log-features-controller-instance-for-monitoring", log.Fields{"error": err})
+ return
+ }
+
+ cc.componentNameConfig = cm.InitComponentConfig(cc.ComponentName, ConfigTypeLogFeatures)
+ logger.Debugw(ctx, "component-log-features-config", log.Fields{"cc-component-name-config": cc.componentNameConfig})
+
+ cc.persistInitialLogFeaturesConfigs(ctx)
+
+ cc.processLogFeaturesConfig(ctx)
+}
+
+// Method to persist Initial status of Log Correlation and Tracing features (as set from command line)
+// into config store (etcd kvstore), if not set yet
+func (cc *ComponentLogFeaturesController) persistInitialLogFeaturesConfigs(ctx context.Context) {
+
+ _, err := cc.componentNameConfig.Retrieve(ctx, defaultTracingStatusKey)
+ if err != nil {
+ statusString := "DISABLED"
+ if cc.initialTracingStatus {
+ statusString = "ENABLED"
+ }
+ err = cc.componentNameConfig.Save(ctx, defaultTracingStatusKey, statusString)
+ if err != nil {
+ logger.Errorw(ctx, "failed-to-persist-component-initial-tracing-status-at-startup", log.Fields{"error": err, "tracingstatus": statusString})
+ }
+ }
+}
+
+// processLogFeaturesConfig will first load and apply configuration of log features. Then it will start waiting for any changes
+// made to configuration in config store (etcd) and apply the same
+func (cc *ComponentLogFeaturesController) processLogFeaturesConfig(ctx context.Context) {
+
+ // Load and apply Tracing Status for first time
+ cc.loadAndApplyTracingStatusUpdate(ctx)
+
+ componentConfigEventChan := cc.componentNameConfig.MonitorForConfigChange(ctx)
+
+ // process the change events received on the channel
+ var configEvent *ConfigChangeEvent
+ for {
+ select {
+ case <-ctx.Done():
+ return
+
+ case configEvent = <-componentConfigEventChan:
+ logger.Debugw(ctx, "processing-log-features-config-change", log.Fields{"ChangeType": configEvent.ChangeType, "Package": configEvent.ConfigAttribute})
+
+ if strings.HasSuffix(configEvent.ConfigAttribute, defaultTracingStatusKey) {
+ cc.loadAndApplyTracingStatusUpdate(ctx)
+ }
+ }
+ }
+
+}
+
+func (cc *ComponentLogFeaturesController) loadAndApplyTracingStatusUpdate(ctx context.Context) {
+
+ desiredTracingStatus, err := cc.componentNameConfig.Retrieve(ctx, defaultTracingStatusKey)
+ if err != nil || desiredTracingStatus == "" {
+ logger.Warn(ctx, "unable-to-retrieve-tracing-status-from-config-store")
+ return
+ }
+
+ if desiredTracingStatus != "ENABLED" && desiredTracingStatus != "DISABLED" {
+ logger.Warnw(ctx, "unsupported-tracing-status-configured-in-config-store", log.Fields{"tracing-status": desiredTracingStatus})
+ return
+ }
+
+ logger.Debugw(ctx, "retrieved-tracing-status", log.Fields{"tracing-status": desiredTracingStatus})
+
+ log.GetGlobalLFM().SetTracePublishingStatus(desiredTracingStatus == "ENABLED")
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/backend.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/backend.go
index 1e23a0f..efc0953 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/backend.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/backend.go
@@ -20,6 +20,7 @@
"context"
"errors"
"fmt"
+ "sync"
"time"
"github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
@@ -40,14 +41,15 @@
Timeout time.Duration
Address string
PathPrefix string
- alive bool // Is this backend connection alive?
+ alive bool // Is this backend connection alive?
+ livenessMutex sync.Mutex
liveness chan bool // channel to post alive state
LivenessChannelInterval time.Duration // regularly push alive state beyond this interval
lastLivenessTime time.Time // Instant of last alive state push
}
// NewBackend creates a new instance of a Backend structure
-func NewBackend(storeType string, address string, timeout time.Duration, pathPrefix string) *Backend {
+func NewBackend(ctx context.Context, storeType string, address string, timeout time.Duration, pathPrefix string) *Backend {
var err error
b := &Backend{
@@ -59,8 +61,8 @@
alive: false, // connection considered down at start
}
- if b.Client, err = b.newClient(address, timeout); err != nil {
- logger.Errorw("failed-to-create-kv-client",
+ if b.Client, err = b.newClient(ctx, address, timeout); err != nil {
+ logger.Errorw(ctx, "failed-to-create-kv-client",
log.Fields{
"type": storeType, "address": address,
"timeout": timeout, "prefix": pathPrefix,
@@ -71,34 +73,35 @@
return b
}
-func (b *Backend) newClient(address string, timeout time.Duration) (kvstore.Client, error) {
+func (b *Backend) newClient(ctx context.Context, address string, timeout time.Duration) (kvstore.Client, error) {
switch b.StoreType {
case "consul":
- return kvstore.NewConsulClient(address, timeout)
+ return kvstore.NewConsulClient(ctx, address, timeout)
case "etcd":
- return kvstore.NewEtcdClient(address, timeout, log.WarnLevel)
+ return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
}
return nil, errors.New("unsupported-kv-store")
}
-func (b *Backend) makePath(key string) string {
+func (b *Backend) makePath(ctx context.Context, key string) string {
path := fmt.Sprintf("%s/%s", b.PathPrefix, key)
return path
}
-func (b *Backend) updateLiveness(alive bool) {
+func (b *Backend) updateLiveness(ctx context.Context, alive bool) {
// Periodically push stream of liveness data to the channel,
// so that in a live state, the core does not timeout and
// send a forced liveness message. Push alive state if the
// last push to channel was beyond livenessChannelInterval
+ b.livenessMutex.Lock()
+ defer b.livenessMutex.Unlock()
if b.liveness != nil {
-
if b.alive != alive {
- logger.Debug("update-liveness-channel-reason-change")
+ logger.Debug(ctx, "update-liveness-channel-reason-change")
b.liveness <- alive
b.lastLivenessTime = time.Now()
} else if time.Since(b.lastLivenessTime) > b.LivenessChannelInterval {
- logger.Debug("update-liveness-channel-reason-interval")
+ logger.Debug(ctx, "update-liveness-channel-reason-interval")
b.liveness <- alive
b.lastLivenessTime = time.Now()
}
@@ -106,7 +109,7 @@
// Emit log message only for alive state change
if b.alive != alive {
- logger.Debugw("change-kvstore-alive-status", log.Fields{"alive": alive})
+ logger.Debugw(ctx, "change-kvstore-alive-status", log.Fields{"alive": alive})
b.alive = alive
}
}
@@ -115,9 +118,9 @@
// post on Liveness channel
func (b *Backend) PerformLivenessCheck(ctx context.Context) bool {
alive := b.Client.IsConnectionUp(ctx)
- logger.Debugw("kvstore-liveness-check-result", log.Fields{"alive": alive})
+ logger.Debugw(ctx, "kvstore-liveness-check-result", log.Fields{"alive": alive})
- b.updateLiveness(alive)
+ b.updateLiveness(ctx, alive)
return alive
}
@@ -126,16 +129,12 @@
// or not the connection is still Live. This channel is then picked up
// by the service (i.e. rw_core / ro_core) to update readiness status
// and/or take other actions.
-func (b *Backend) EnableLivenessChannel() chan bool {
- logger.Debug("enable-kvstore-liveness-channel")
-
+func (b *Backend) EnableLivenessChannel(ctx context.Context) chan bool {
+ logger.Debug(ctx, "enable-kvstore-liveness-channel")
+ b.livenessMutex.Lock()
+ defer b.livenessMutex.Unlock()
if b.liveness == nil {
- logger.Debug("create-kvstore-liveness-channel")
-
- // Channel size of 10 to avoid any possibility of blocking in Load conditions
b.liveness = make(chan bool, 10)
-
- // Post initial alive state
b.liveness <- b.alive
b.lastLivenessTime = time.Now()
}
@@ -144,7 +143,7 @@
}
// Extract Alive status of Kvstore based on type of error
-func (b *Backend) isErrorIndicatingAliveKvstore(err error) bool {
+func (b *Backend) isErrorIndicatingAliveKvstore(ctx context.Context, err error) bool {
// Alive unless observed an error indicating so
alive := true
@@ -182,64 +181,82 @@
// List retrieves one or more items that match the specified key
func (b *Backend) List(ctx context.Context, key string) (map[string]*kvstore.KVPair, error) {
- formattedPath := b.makePath(key)
- logger.Debugw("listing-key", log.Fields{"key": key, "path": formattedPath})
+ span, ctx := log.CreateChildSpan(ctx, "etcd-list")
+ defer span.Finish()
+
+ formattedPath := b.makePath(ctx, key)
+ logger.Debugw(ctx, "listing-key", log.Fields{"key": key, "path": formattedPath})
pair, err := b.Client.List(ctx, formattedPath)
- b.updateLiveness(b.isErrorIndicatingAliveKvstore(err))
+ b.updateLiveness(ctx, b.isErrorIndicatingAliveKvstore(ctx, err))
return pair, err
}
// Get retrieves an item that matches the specified key
func (b *Backend) Get(ctx context.Context, key string) (*kvstore.KVPair, error) {
- formattedPath := b.makePath(key)
- logger.Debugw("getting-key", log.Fields{"key": key, "path": formattedPath})
+ span, ctx := log.CreateChildSpan(ctx, "etcd-get")
+ defer span.Finish()
+
+ formattedPath := b.makePath(ctx, key)
+ logger.Debugw(ctx, "getting-key", log.Fields{"key": key, "path": formattedPath})
pair, err := b.Client.Get(ctx, formattedPath)
- b.updateLiveness(b.isErrorIndicatingAliveKvstore(err))
+ b.updateLiveness(ctx, b.isErrorIndicatingAliveKvstore(ctx, err))
return pair, err
}
// Put stores an item value under the specifed key
func (b *Backend) Put(ctx context.Context, key string, value interface{}) error {
- formattedPath := b.makePath(key)
- logger.Debugw("putting-key", log.Fields{"key": key, "path": formattedPath})
+ span, ctx := log.CreateChildSpan(ctx, "etcd-put")
+ defer span.Finish()
+
+ formattedPath := b.makePath(ctx, key)
+ logger.Debugw(ctx, "putting-key", log.Fields{"key": key, "path": formattedPath})
err := b.Client.Put(ctx, formattedPath, value)
- b.updateLiveness(b.isErrorIndicatingAliveKvstore(err))
+ b.updateLiveness(ctx, b.isErrorIndicatingAliveKvstore(ctx, err))
return err
}
// Delete removes an item under the specified key
func (b *Backend) Delete(ctx context.Context, key string) error {
- formattedPath := b.makePath(key)
- logger.Debugw("deleting-key", log.Fields{"key": key, "path": formattedPath})
+ span, ctx := log.CreateChildSpan(ctx, "etcd-delete")
+ defer span.Finish()
+
+ formattedPath := b.makePath(ctx, key)
+ logger.Debugw(ctx, "deleting-key", log.Fields{"key": key, "path": formattedPath})
err := b.Client.Delete(ctx, formattedPath)
- b.updateLiveness(b.isErrorIndicatingAliveKvstore(err))
+ b.updateLiveness(ctx, b.isErrorIndicatingAliveKvstore(ctx, err))
return err
}
// CreateWatch starts watching events for the specified key
func (b *Backend) CreateWatch(ctx context.Context, key string, withPrefix bool) chan *kvstore.Event {
- formattedPath := b.makePath(key)
- logger.Debugw("creating-key-watch", log.Fields{"key": key, "path": formattedPath})
+ span, ctx := log.CreateChildSpan(ctx, "etcd-create-watch")
+ defer span.Finish()
+
+ formattedPath := b.makePath(ctx, key)
+ logger.Debugw(ctx, "creating-key-watch", log.Fields{"key": key, "path": formattedPath})
return b.Client.Watch(ctx, formattedPath, withPrefix)
}
// DeleteWatch stops watching events for the specified key
-func (b *Backend) DeleteWatch(key string, ch chan *kvstore.Event) {
- formattedPath := b.makePath(key)
- logger.Debugw("deleting-key-watch", log.Fields{"key": key, "path": formattedPath})
+func (b *Backend) DeleteWatch(ctx context.Context, key string, ch chan *kvstore.Event) {
+ span, ctx := log.CreateChildSpan(ctx, "etcd-delete-watch")
+ defer span.Finish()
- b.Client.CloseWatch(formattedPath, ch)
+ formattedPath := b.makePath(ctx, key)
+ logger.Debugw(ctx, "deleting-key-watch", log.Fields{"key": key, "path": formattedPath})
+
+ b.Client.CloseWatch(ctx, formattedPath, ch)
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/common.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/common.go
index 1cf2e1c..9d50f24 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/common.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/common.go
@@ -19,12 +19,12 @@
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
-var logger log.Logger
+var logger log.CLogger
func init() {
// Setup this package so that it's log level can be modified at run time
var err error
- logger, err = log.AddPackage(log.JSON, log.ErrorLevel, log.Fields{"pkg": "db"})
+ logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
if err != nil {
panic(err)
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/client.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/client.go
index 158e626..480d476 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/client.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/client.go
@@ -88,6 +88,6 @@
AcquireLock(ctx context.Context, lockName string, timeout time.Duration) error
ReleaseLock(lockName string) error
IsConnectionUp(ctx context.Context) bool // timeout in second
- CloseWatch(key string, ch chan *Event)
- Close()
+ CloseWatch(ctx context.Context, key string, ch chan *Event)
+ Close(ctx context.Context)
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/common.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/common.go
index aa7aeb0..bb38a94 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/common.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/common.go
@@ -19,12 +19,12 @@
"github.com/opencord/voltha-lib-go/v3/pkg/log"
)
-var logger log.Logger
+var logger log.CLogger
func init() {
// Setup this package so that it's log level can be modified at run time
var err error
- logger, err = log.AddPackage(log.JSON, log.ErrorLevel, log.Fields{"pkg": "kvstore"})
+ logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
if err != nil {
panic(err)
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/consulclient.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/consulclient.go
index d2544dd..c2cd841 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/consulclient.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/consulclient.go
@@ -44,14 +44,13 @@
}
// NewConsulClient returns a new client for the Consul KV store
-func NewConsulClient(addr string, timeout time.Duration) (*ConsulClient, error) {
-
+func NewConsulClient(ctx context.Context, addr string, timeout time.Duration) (*ConsulClient, error) {
config := consulapi.DefaultConfig()
config.Address = addr
config.WaitTime = timeout
consul, err := consulapi.NewClient(config)
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return nil, err
}
@@ -63,7 +62,7 @@
// IsConnectionUp returns whether the connection to the Consul KV store is up
func (c *ConsulClient) IsConnectionUp(ctx context.Context) bool {
- logger.Error("Unimplemented function")
+ logger.Error(ctx, "Unimplemented function")
return false
}
@@ -80,7 +79,7 @@
// For now we ignore meta data
kvps, _, err := kv.List(key, &queryOptions)
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return nil, err
}
m := make(map[string]*KVPair)
@@ -103,7 +102,7 @@
// For now we ignore meta data
kvp, _, err := kv.Get(key, &queryOptions)
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return nil, err
}
if kvp != nil {
@@ -122,7 +121,7 @@
var val []byte
var er error
if val, er = ToByte(value); er != nil {
- logger.Error(er)
+ logger.Error(ctx, er)
return er
}
@@ -134,7 +133,7 @@
defer c.writeLock.Unlock()
_, err := kv.Put(&kvp, &writeOptions)
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return err
}
return nil
@@ -149,26 +148,26 @@
defer c.writeLock.Unlock()
_, err := kv.Delete(key, &writeOptions)
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return err
}
return nil
}
-func (c *ConsulClient) deleteSession() {
+func (c *ConsulClient) deleteSession(ctx context.Context) {
if c.sessionID != "" {
- logger.Debug("cleaning-up-session")
+ logger.Debug(ctx, "cleaning-up-session")
session := c.consul.Session()
_, err := session.Destroy(c.sessionID, nil)
if err != nil {
- logger.Errorw("error-cleaning-session", log.Fields{"session": c.sessionID, "error": err})
+ logger.Errorw(ctx, "error-cleaning-session", log.Fields{"session": c.sessionID, "error": err})
}
}
c.sessionID = ""
c.session = nil
}
-func (c *ConsulClient) createSession(ttl time.Duration, retries int) (*consulapi.Session, string, error) {
+func (c *ConsulClient) createSession(ctx context.Context, ttl time.Duration, retries int) (*consulapi.Session, string, error) {
session := c.consul.Session()
entry := &consulapi.SessionEntry{
Behavior: consulapi.SessionBehaviorDelete,
@@ -178,17 +177,17 @@
for {
id, meta, err := session.Create(entry, nil)
if err != nil {
- logger.Errorw("create-session-error", log.Fields{"error": err})
+ logger.Errorw(ctx, "create-session-error", log.Fields{"error": err})
if retries == 0 {
return nil, "", err
}
} else if meta.RequestTime == 0 {
- logger.Errorw("create-session-bad-meta-data", log.Fields{"meta-data": meta})
+ logger.Errorw(ctx, "create-session-bad-meta-data", log.Fields{"meta-data": meta})
if retries == 0 {
return nil, "", errors.New("bad-meta-data")
}
} else if id == "" {
- logger.Error("create-session-nil-id")
+ logger.Error(ctx, "create-session-nil-id")
if retries == 0 {
return nil, "", errors.New("ID-nil")
}
@@ -199,7 +198,7 @@
if retries > 0 {
retries--
}
- logger.Debug("retrying-session-create-after-a-second-delay")
+ logger.Debug(ctx, "retrying-session-create-after-a-second-delay")
time.Sleep(time.Duration(1) * time.Second)
}
}
@@ -226,30 +225,30 @@
var val []byte
var er error
if val, er = ToByte(value); er != nil {
- logger.Error(er)
+ logger.Error(ctx, er)
return nil, er
}
// Cleanup any existing session and recreate new ones. A key is reserved against a session
if c.sessionID != "" {
- c.deleteSession()
+ c.deleteSession(ctx)
}
// Clear session if reservation is not successful
reservationSuccessful := false
defer func() {
if !reservationSuccessful {
- logger.Debug("deleting-session")
- c.deleteSession()
+ logger.Debug(ctx, "deleting-session")
+ c.deleteSession(ctx)
}
}()
- session, sessionID, err := c.createSession(ttl, -1)
+ session, sessionID, err := c.createSession(ctx, ttl, -1)
if err != nil {
- logger.Errorw("no-session-created", log.Fields{"error": err})
+ logger.Errorw(ctx, "no-session-created", log.Fields{"error": err})
return "", errors.New("no-session-created")
}
- logger.Debugw("session-created", log.Fields{"session-id": sessionID})
+ logger.Debugw(ctx, "session-created", log.Fields{"session-id": sessionID})
c.sessionID = sessionID
c.session = session
@@ -258,11 +257,11 @@
kvp := consulapi.KVPair{Key: key, Value: val, Session: c.sessionID}
result, _, err := kv.Acquire(&kvp, nil)
if err != nil {
- logger.Errorw("error-acquiring-keys", log.Fields{"error": err})
+ logger.Errorw(ctx, "error-acquiring-keys", log.Fields{"error": err})
return nil, err
}
- logger.Debugw("key-acquired", log.Fields{"key": key, "status": result})
+ logger.Debugw(ctx, "key-acquired", log.Fields{"key": key, "status": result})
// Irrespective whether we were successful in acquiring the key, let's read it back and see if it's us.
m, err := c.Get(ctx, key)
@@ -270,7 +269,7 @@
return nil, err
}
if m != nil {
- logger.Debugw("response-received", log.Fields{"key": m.Key, "m.value": string(m.Value.([]byte)), "value": value})
+ logger.Debugw(ctx, "response-received", log.Fields{"key": m.Key, "m.value": string(m.Value.([]byte)), "value": value})
if m.Key == key && isEqual(m.Value, value) {
// My reservation is successful - register it. For now, support is only for 1 reservation per key
// per session.
@@ -300,11 +299,11 @@
kvp = consulapi.KVPair{Key: key, Value: value.([]byte), Session: c.sessionID}
result, _, err = kv.Release(&kvp, nil)
if err != nil {
- logger.Errorw("cannot-release-reservation", log.Fields{"key": key, "error": err})
+ logger.Errorw(ctx, "cannot-release-reservation", log.Fields{"key": key, "error": err})
return err
}
if !result {
- logger.Errorw("cannot-release-reservation", log.Fields{"key": key})
+ logger.Errorw(ctx, "cannot-release-reservation", log.Fields{"key": key})
}
delete(c.keyReservations, key)
}
@@ -384,21 +383,21 @@
// CloseWatch closes a specific watch. Both the key and the channel are required when closing a watch as there
// may be multiple listeners on the same key. The previously created channel serves as a key
-func (c *ConsulClient) CloseWatch(key string, ch chan *Event) {
+func (c *ConsulClient) CloseWatch(ctx context.Context, key string, ch chan *Event) {
// First close the context
var ok bool
var watchedChannelsContexts []*channelContextMap
c.writeLock.Lock()
defer c.writeLock.Unlock()
if watchedChannelsContexts, ok = c.watchedChannelsContext[key]; !ok {
- logger.Errorw("key-has-no-watched-context-or-channel", log.Fields{"key": key})
+ logger.Errorw(ctx, "key-has-no-watched-context-or-channel", log.Fields{"key": key})
return
}
// Look for the channels
var pos = -1
for i, chCtxMap := range watchedChannelsContexts {
if chCtxMap.channel == ch {
- logger.Debug("channel-found")
+ logger.Debug(ctx, "channel-found")
chCtxMap.cancel()
//close the channel
close(ch)
@@ -410,7 +409,7 @@
if pos >= 0 {
c.watchedChannelsContext[key] = append(c.watchedChannelsContext[key][:pos], c.watchedChannelsContext[key][pos+1:]...)
}
- logger.Debugw("watched-channel-exiting", log.Fields{"key": key, "channel": c.watchedChannelsContext[key]})
+ logger.Debugw(ctx, "watched-channel-exiting", log.Fields{"key": key, "channel": c.watchedChannelsContext[key]})
}
func (c *ConsulClient) isKVEqual(kv1 *consulapi.KVPair, kv2 *consulapi.KVPair) bool {
@@ -430,10 +429,10 @@
return true
}
-func (c *ConsulClient) listenForKeyChange(watchContext context.Context, key string, ch chan *Event) {
- logger.Debugw("start-watching-channel", log.Fields{"key": key, "channel": ch})
+func (c *ConsulClient) listenForKeyChange(ctx context.Context, key string, ch chan *Event) {
+ logger.Debugw(ctx, "start-watching-channel", log.Fields{"key": key, "channel": ch})
- defer c.CloseWatch(key, ch)
+ defer c.CloseWatch(ctx, key, ch)
kv := c.consul.KV()
var queryOptions consulapi.QueryOptions
queryOptions.WaitTime = defaultKVGetTimeout
@@ -441,7 +440,7 @@
// Get the existing value, if any
previousKVPair, meta, err := kv.Get(key, &queryOptions)
if err != nil {
- logger.Debug(err)
+ logger.Debug(ctx, err)
}
lastIndex := meta.LastIndex
@@ -449,37 +448,37 @@
//var waitOptions consulapi.QueryOptions
var pair *consulapi.KVPair
//watchContext, _ := context.WithCancel(context.Background())
- waitOptions := queryOptions.WithContext(watchContext)
+ waitOptions := queryOptions.WithContext(ctx)
for {
//waitOptions = consulapi.QueryOptions{WaitIndex: lastIndex}
waitOptions.WaitIndex = lastIndex
pair, meta, err = kv.Get(key, waitOptions)
select {
- case <-watchContext.Done():
- logger.Debug("done-event-received-exiting")
+ case <-ctx.Done():
+ logger.Debug(ctx, "done-event-received-exiting")
return
default:
if err != nil {
- logger.Warnw("error-from-watch", log.Fields{"error": err})
+ logger.Warnw(ctx, "error-from-watch", log.Fields{"error": err})
ch <- NewEvent(CONNECTIONDOWN, key, []byte(""), -1)
} else {
- logger.Debugw("index-state", log.Fields{"lastindex": lastIndex, "newindex": meta.LastIndex, "key": key})
+ logger.Debugw(ctx, "index-state", log.Fields{"lastindex": lastIndex, "newindex": meta.LastIndex, "key": key})
}
}
if err != nil {
- logger.Debug(err)
+ logger.Debug(ctx, err)
// On error, block for 10 milliseconds to prevent endless loop
time.Sleep(10 * time.Millisecond)
} else if meta.LastIndex <= lastIndex {
- logger.Info("no-index-change-or-negative")
+ logger.Info(ctx, "no-index-change-or-negative")
} else {
- logger.Debugw("update-received", log.Fields{"pair": pair})
+ logger.Debugw(ctx, "update-received", log.Fields{"pair": pair})
if pair == nil {
ch <- NewEvent(DELETE, key, []byte(""), -1)
} else if !c.isKVEqual(pair, previousKVPair) {
// Push the change onto the channel if the data has changed
// For now just assume it's a PUT change
- logger.Debugw("pair-details", log.Fields{"session": pair.Session, "key": pair.Key, "value": pair.Value})
+ logger.Debugw(ctx, "pair-details", log.Fields{"session": pair.Session, "key": pair.Key, "value": pair.Value})
ch <- NewEvent(PUT, pair.Key, pair.Value, -1)
}
previousKVPair = pair
@@ -489,7 +488,7 @@
}
// Close closes the KV store client
-func (c *ConsulClient) Close() {
+func (c *ConsulClient) Close(ctx context.Context) {
var writeOptions consulapi.WriteOptions
// Inform any goroutine it's time to say goodbye.
c.writeLock.Lock()
@@ -500,7 +499,7 @@
// Clear the sessionID
if _, err := c.consul.Session().Destroy(c.sessionID, &writeOptions); err != nil {
- logger.Errorw("error-closing-client", log.Fields{"error": err})
+ logger.Errorw(ctx, "error-closing-client", log.Fields{"error": err})
}
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/etcdclient.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/etcdclient.go
index 8d4a462..0165e18 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/etcdclient.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore/etcdclient.go
@@ -40,7 +40,7 @@
}
// NewEtcdClient returns a new client for the Etcd KV store
-func NewEtcdClient(addr string, timeout time.Duration, level log.LogLevel) (*EtcdClient, error) {
+func NewEtcdClient(ctx context.Context, addr string, timeout time.Duration, level log.LogLevel) (*EtcdClient, error) {
logconfig := log.ConstructZapConfig(log.JSON, level, log.Fields{})
c, err := v3Client.New(v3Client.Config{
@@ -49,7 +49,7 @@
LogConfig: &logconfig,
})
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return nil, err
}
@@ -77,7 +77,7 @@
func (c *EtcdClient) List(ctx context.Context, key string) (map[string]*KVPair, error) {
resp, err := c.ectdAPI.Get(ctx, key, v3Client.WithPrefix())
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return nil, err
}
m := make(map[string]*KVPair)
@@ -94,7 +94,7 @@
resp, err := c.ectdAPI.Get(ctx, key)
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return nil, err
}
for _, ev := range resp.Kvs {
@@ -131,13 +131,13 @@
if err != nil {
switch err {
case context.Canceled:
- logger.Warnw("context-cancelled", log.Fields{"error": err})
+ logger.Warnw(ctx, "context-cancelled", log.Fields{"error": err})
case context.DeadlineExceeded:
- logger.Warnw("context-deadline-exceeded", log.Fields{"error": err})
+ logger.Warnw(ctx, "context-deadline-exceeded", log.Fields{"error": err})
case v3rpcTypes.ErrEmptyKey:
- logger.Warnw("etcd-client-error", log.Fields{"error": err})
+ logger.Warnw(ctx, "etcd-client-error", log.Fields{"error": err})
default:
- logger.Warnw("bad-endpoints", log.Fields{"error": err})
+ logger.Warnw(ctx, "bad-endpoints", log.Fields{"error": err})
}
return err
}
@@ -150,10 +150,10 @@
// delete the key
if _, err := c.ectdAPI.Delete(ctx, key); err != nil {
- logger.Errorw("failed-to-delete-key", log.Fields{"key": key, "error": err})
+ logger.Errorw(ctx, "failed-to-delete-key", log.Fields{"key": key, "error": err})
return err
}
- logger.Debugw("key(s)-deleted", log.Fields{"key": key})
+ logger.Debugw(ctx, "key(s)-deleted", log.Fields{"key": key})
return nil
}
@@ -172,7 +172,7 @@
resp, err := c.ectdAPI.Grant(ctx, int64(ttl.Seconds()))
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return nil, err
}
// Register the lease id
@@ -185,7 +185,7 @@
defer func() {
if !reservationSuccessful {
if err = c.ReleaseReservation(context.Background(), key); err != nil {
- logger.Error("cannot-release-lease")
+ logger.Error(ctx, "cannot-release-lease")
}
}
}()
@@ -240,7 +240,7 @@
for key, leaseID := range c.keyReservations {
_, err := c.ectdAPI.Revoke(ctx, *leaseID)
if err != nil {
- logger.Errorw("cannot-release-reservation", log.Fields{"key": key, "error": err})
+ logger.Errorw(ctx, "cannot-release-reservation", log.Fields{"key": key, "error": err})
return err
}
delete(c.keyReservations, key)
@@ -251,7 +251,7 @@
// ReleaseReservation releases reservation for a specific key.
func (c *EtcdClient) ReleaseReservation(ctx context.Context, key string) error {
// Get the leaseid using the key
- logger.Debugw("Release-reservation", log.Fields{"key": key})
+ logger.Debugw(ctx, "Release-reservation", log.Fields{"key": key})
var ok bool
var leaseID *v3Client.LeaseID
c.keyReservationsLock.Lock()
@@ -263,7 +263,7 @@
if leaseID != nil {
_, err := c.ectdAPI.Revoke(ctx, *leaseID)
if err != nil {
- logger.Error(err)
+ logger.Error(ctx, err)
return err
}
delete(c.keyReservations, key)
@@ -288,7 +288,7 @@
if leaseID != nil {
_, err := c.ectdAPI.KeepAliveOnce(ctx, *leaseID)
if err != nil {
- logger.Errorw("lease-may-have-expired", log.Fields{"error": err})
+ logger.Errorw(ctx, "lease-may-have-expired", log.Fields{"error": err})
return err
}
} else {
@@ -320,9 +320,9 @@
// Changing the log field (from channelMaps) as the underlying logger cannot format the map of channels into a
// json format.
- logger.Debugw("watched-channels", log.Fields{"len": len(channelMaps)})
+ logger.Debugw(ctx, "watched-channels", log.Fields{"len": len(channelMaps)})
// Launch a go routine to listen for updates
- go c.listenForKeyChange(channel, ch, cancel)
+ go c.listenForKeyChange(ctx, channel, ch, cancel)
return ch
@@ -369,23 +369,23 @@
// CloseWatch closes a specific watch. Both the key and the channel are required when closing a watch as there
// may be multiple listeners on the same key. The previously created channel serves as a key
-func (c *EtcdClient) CloseWatch(key string, ch chan *Event) {
+func (c *EtcdClient) CloseWatch(ctx context.Context, key string, ch chan *Event) {
// Get the array of channels mapping
var watchedChannels []map[chan *Event]v3Client.Watcher
var ok bool
if watchedChannels, ok = c.getChannelMaps(key); !ok {
- logger.Warnw("key-has-no-watched-channels", log.Fields{"key": key})
+ logger.Warnw(ctx, "key-has-no-watched-channels", log.Fields{"key": key})
return
}
// Look for the channels
var pos = -1
for i, chMap := range watchedChannels {
if t, ok := chMap[ch]; ok {
- logger.Debug("channel-found")
+ logger.Debug(ctx, "channel-found")
// Close the etcd watcher before the client channel. This should close the etcd channel as well
if err := t.Close(); err != nil {
- logger.Errorw("watcher-cannot-be-closed", log.Fields{"key": key, "error": err})
+ logger.Errorw(ctx, "watcher-cannot-be-closed", log.Fields{"key": key, "error": err})
}
pos = i
break
@@ -397,11 +397,11 @@
if pos >= 0 {
channelMaps = c.removeChannelMap(key, pos)
}
- logger.Infow("watcher-channel-exiting", log.Fields{"key": key, "channel": channelMaps})
+ logger.Infow(ctx, "watcher-channel-exiting", log.Fields{"key": key, "channel": channelMaps})
}
-func (c *EtcdClient) listenForKeyChange(channel v3Client.WatchChan, ch chan<- *Event, cancel context.CancelFunc) {
- logger.Debug("start-listening-on-channel ...")
+func (c *EtcdClient) listenForKeyChange(ctx context.Context, channel v3Client.WatchChan, ch chan<- *Event, cancel context.CancelFunc) {
+ logger.Debug(ctx, "start-listening-on-channel ...")
defer cancel()
defer close(ch)
for resp := range channel {
@@ -409,7 +409,7 @@
ch <- NewEvent(getEventType(ev), ev.Kv.Key, ev.Kv.Value, ev.Kv.Version)
}
}
- logger.Debug("stop-listening-on-channel ...")
+ logger.Debug(ctx, "stop-listening-on-channel ...")
}
func getEventType(event *v3Client.Event) int {
@@ -423,9 +423,9 @@
}
// Close closes the KV store client
-func (c *EtcdClient) Close() {
+func (c *EtcdClient) Close(ctx context.Context) {
if err := c.ectdAPI.Close(); err != nil {
- logger.Errorw("error-closing-client", log.Fields{"error": err})
+ logger.Errorw(ctx, "error-closing-client", log.Fields{"error": err})
}
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/common.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/common.go
new file mode 100644
index 0000000..b0ce81b
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/common.go
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package log
+
+var logger CLogger
+
+func init() {
+ // Setup this package so that it's log level can be modified at run time
+ var err error
+ logger, err = RegisterPackage(JSON, ErrorLevel, Fields{})
+ if err != nil {
+ panic(err)
+ }
+}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/log.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/log.go
index 9e0a0b5..b8d498c 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/log.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/log.go
@@ -14,33 +14,44 @@
* limitations under the License.
*/
-//Package log provides a structured Logger interface implemented using zap logger. It provides the following capabilities:
-//1. Package level logging - a go package can register itself (AddPackage) and have a logger created for that package.
-//2. Dynamic log level change - for all registered packages (SetAllLogLevel)
-//3. Dynamic log level change - for a given package (SetPackageLogLevel)
-//4. Provides a default logger for unregistered packages
-//5. Allow key-value pairs to be added to a logger(UpdateLogger) or all loggers (UpdateAllLoggers) at run time
-//6. Add to the log output the location where the log was invoked (filename.functionname.linenumber)
+// Package log provides a structured Logger interface implemented using zap logger. It provides the following capabilities:
+// 1. Package level logging - a go package can register itself (AddPackage) and have a logger created for that package.
+// 2. Dynamic log level change - for all registered packages (SetAllLogLevel)
+// 3. Dynamic log level change - for a given package (SetPackageLogLevel)
+// 4. Provides a default logger for unregistered packages (however avoid its usage)
+// 5. Allow key-value pairs to be added to a logger(UpdateLogger) or all loggers (UpdateAllLoggers) at run time
+// 6. Add to the log output the location where the log was invoked (filename.functionname.linenumber)
//
// Using package-level logging (recommended approach). In the examples below, log refers to this log package.
-// 1. In the appropriate package add the following in the init section of the package. The log level can be changed
-// and any number of default fields can be added as well. The log level specifies the lowest log level that will be
-// in the output while the fields will be automatically added to all log printouts.
//
-// log.AddPackage(mylog.JSON, log.WarnLevel, log.Fields{"anyFieldName": "any value"})
+// 1. In the appropriate package, add the following in the init section of the package (usually in a common.go file)
+// The log level can be changed and any number of default fields can be added as well. The log level specifies
+// the lowest log level that will be in the output while the fields will be automatically added to all log printouts.
+// However, as voltha components re-initialize the log level of each registered package to default initial loglevel
+// passed as CLI argument, the log level passed in RegisterPackage call effectively has no effect.
//
-//2. In the calling package, just invoke any of the publicly available functions of the logger. Here is an example
-// to write an Info log with additional fields:
+// var logger log.CLogger
+// func init() {
+// logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{"key1": "value1"})
+// }
//
-//log.Infow("An example", mylog.Fields{"myStringOutput": "output", "myIntOutput": 2})
+// 2. In the calling package, use any of the publicly available functions of local package-level logger instance created
+// in previous step. Here is an example to write an Info log with additional fields:
//
-//3. To dynamically change the log level, you can use 1)SetLogLevel from inside your package or 2) SetPackageLogLevel
-// from anywhere or 3) SetAllLogLevel from anywhere.
+// logger.Infow("An example", mylog.Fields{"myStringOutput": "output", "myIntOutput": 2})
//
+// 3. To dynamically change the log level, you can use
+// a) SetLogLevel from inside your package or
+// b) SetPackageLogLevel from anywhere or
+// c) SetAllLogLevel from anywhere.
+//
+// Dynamic Loglevel configuration feature also uses SetPackageLogLevel method based on triggers received due to
+// Changes to configured loglevels
package log
import (
+ "context"
"errors"
"fmt"
zp "go.uber.org/zap"
@@ -71,41 +82,41 @@
// JSON formats the log using json format, mostly used by an automated logging system consumption
const JSON = "json"
-// Logger represents an abstract logging interface. Any logging implementation used
+// Context Aware Logger represents an abstract logging interface. Any logging implementation used
// will need to abide by this interface
-type Logger interface {
- Debug(...interface{})
- Debugln(...interface{})
- Debugf(string, ...interface{})
- Debugw(string, Fields)
+type CLogger interface {
+ Debug(context.Context, ...interface{})
+ Debugln(context.Context, ...interface{})
+ Debugf(context.Context, string, ...interface{})
+ Debugw(context.Context, string, Fields)
- Info(...interface{})
- Infoln(...interface{})
- Infof(string, ...interface{})
- Infow(string, Fields)
+ Info(context.Context, ...interface{})
+ Infoln(context.Context, ...interface{})
+ Infof(context.Context, string, ...interface{})
+ Infow(context.Context, string, Fields)
- Warn(...interface{})
- Warnln(...interface{})
- Warnf(string, ...interface{})
- Warnw(string, Fields)
+ Warn(context.Context, ...interface{})
+ Warnln(context.Context, ...interface{})
+ Warnf(context.Context, string, ...interface{})
+ Warnw(context.Context, string, Fields)
- Error(...interface{})
- Errorln(...interface{})
- Errorf(string, ...interface{})
- Errorw(string, Fields)
+ Error(context.Context, ...interface{})
+ Errorln(context.Context, ...interface{})
+ Errorf(context.Context, string, ...interface{})
+ Errorw(context.Context, string, Fields)
- Fatal(...interface{})
- Fatalln(...interface{})
- Fatalf(string, ...interface{})
- Fatalw(string, Fields)
+ Fatal(context.Context, ...interface{})
+ Fatalln(context.Context, ...interface{})
+ Fatalf(context.Context, string, ...interface{})
+ Fatalw(context.Context, string, Fields)
- With(Fields) Logger
+ With(Fields) CLogger
// The following are added to be able to use this logger as a gRPC LoggerV2 if needed
//
- Warning(...interface{})
- Warningln(...interface{})
- Warningf(string, ...interface{})
+ Warning(context.Context, ...interface{})
+ Warningln(context.Context, ...interface{})
+ Warningf(context.Context, string, ...interface{})
// V reports whether verbosity level l is at least the requested verbose level.
V(l LogLevel) bool
@@ -117,13 +128,13 @@
// Fields is used as key-value pairs for structured logging
type Fields map[string]interface{}
-var defaultLogger *logger
+var defaultLogger *clogger
var cfg zp.Config
-var loggers map[string]*logger
+var loggers map[string]*clogger
var cfgs map[string]zp.Config
-type logger struct {
+type clogger struct {
log *zp.SugaredLogger
parent *zp.Logger
packageName string
@@ -238,7 +249,7 @@
// SetLogger needs to be invoked before the logger API can be invoked. This function
// initialize the default logger (zap's sugaredlogger)
-func SetDefaultLogger(outputType string, level LogLevel, defaultFields Fields) (Logger, error) {
+func SetDefaultLogger(outputType string, level LogLevel, defaultFields Fields) (CLogger, error) {
// Build a custom config using zap
cfg = getDefaultConfig(outputType, level, defaultFields)
@@ -247,7 +258,7 @@
return nil, err
}
- defaultLogger = &logger{
+ defaultLogger = &clogger{
log: l.Sugar(),
parent: l,
}
@@ -264,12 +275,12 @@
// be available to it, notably log tracing with filename.functionname.linenumber annotation.
//
// pkgNames parameter should be used for testing only as this function detects the caller's package.
-func AddPackage(outputType string, level LogLevel, defaultFields Fields, pkgNames ...string) (Logger, error) {
+func RegisterPackage(outputType string, level LogLevel, defaultFields Fields, pkgNames ...string) (CLogger, error) {
if cfgs == nil {
cfgs = make(map[string]zp.Config)
}
if loggers == nil {
- loggers = make(map[string]*logger)
+ loggers = make(map[string]*clogger)
}
var pkgName string
@@ -292,7 +303,7 @@
return nil, err
}
- loggers[pkgName] = &logger{
+ loggers[pkgName] = &clogger{
log: l.Sugar(),
parent: l,
packageName: pkgName,
@@ -502,311 +513,149 @@
return packageName, fileName, funcName, foundFrame.Line
}
-func getPackageLevelSugaredLogger() *zp.SugaredLogger {
- pkgName, _, _, _ := getCallerInfo()
- if _, exist := loggers[pkgName]; exist {
- return loggers[pkgName].log
- }
- return defaultLogger.log
-}
-
-func getPackageLevelLogger() Logger {
- pkgName, _, _, _ := getCallerInfo()
- if _, exist := loggers[pkgName]; exist {
- return loggers[pkgName]
- }
- return defaultLogger
-}
-
-func serializeMap(fields Fields) []interface{} {
- data := make([]interface{}, len(fields)*2)
- i := 0
- for k, v := range fields {
- data[i] = k
- data[i+1] = v
- i = i + 2
- }
- return data
-}
-
// With returns a logger initialized with the key-value pairs
-func (l logger) With(keysAndValues Fields) Logger {
- return logger{log: l.log.With(serializeMap(keysAndValues)...), parent: l.parent}
+func (l clogger) With(keysAndValues Fields) CLogger {
+ return clogger{log: l.log.With(serializeMap(keysAndValues)...), parent: l.parent}
}
// Debug logs a message at level Debug on the standard logger.
-func (l logger) Debug(args ...interface{}) {
- l.log.Debug(args...)
+func (l clogger) Debug(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Debug(args...)
}
// Debugln logs a message at level Debug on the standard logger with a line feed. Default in any case.
-func (l logger) Debugln(args ...interface{}) {
- l.log.Debug(args...)
+func (l clogger) Debugln(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Debug(args...)
}
// Debugw logs a message at level Debug on the standard logger.
-func (l logger) Debugf(format string, args ...interface{}) {
- l.log.Debugf(format, args...)
+func (l clogger) Debugf(ctx context.Context, format string, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Debugf(format, args...)
}
// Debugw logs a message with some additional context. The variadic key-value
// pairs are treated as they are in With.
-func (l logger) Debugw(msg string, keysAndValues Fields) {
+func (l clogger) Debugw(ctx context.Context, msg string, keysAndValues Fields) {
if l.V(DebugLevel) {
- l.log.Debugw(msg, serializeMap(keysAndValues)...)
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Debugw(msg, serializeMap(keysAndValues)...)
}
}
// Info logs a message at level Info on the standard logger.
-func (l logger) Info(args ...interface{}) {
- l.log.Info(args...)
+func (l clogger) Info(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Info(args...)
}
// Infoln logs a message at level Info on the standard logger with a line feed. Default in any case.
-func (l logger) Infoln(args ...interface{}) {
- l.log.Info(args...)
+func (l clogger) Infoln(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Info(args...)
//msg := fmt.Sprintln(args...)
//l.sourced().Info(msg[:len(msg)-1])
}
// Infof logs a message at level Info on the standard logger.
-func (l logger) Infof(format string, args ...interface{}) {
- l.log.Infof(format, args...)
+func (l clogger) Infof(ctx context.Context, format string, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Infof(format, args...)
}
// Infow logs a message with some additional context. The variadic key-value
// pairs are treated as they are in With.
-func (l logger) Infow(msg string, keysAndValues Fields) {
+func (l clogger) Infow(ctx context.Context, msg string, keysAndValues Fields) {
if l.V(InfoLevel) {
- l.log.Infow(msg, serializeMap(keysAndValues)...)
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Infow(msg, serializeMap(keysAndValues)...)
}
}
// Warn logs a message at level Warn on the standard logger.
-func (l logger) Warn(args ...interface{}) {
- l.log.Warn(args...)
+func (l clogger) Warn(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Warn(args...)
}
// Warnln logs a message at level Warn on the standard logger with a line feed. Default in any case.
-func (l logger) Warnln(args ...interface{}) {
- l.log.Warn(args...)
+func (l clogger) Warnln(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Warn(args...)
}
// Warnf logs a message at level Warn on the standard logger.
-func (l logger) Warnf(format string, args ...interface{}) {
- l.log.Warnf(format, args...)
+func (l clogger) Warnf(ctx context.Context, format string, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Warnf(format, args...)
}
// Warnw logs a message with some additional context. The variadic key-value
// pairs are treated as they are in With.
-func (l logger) Warnw(msg string, keysAndValues Fields) {
+func (l clogger) Warnw(ctx context.Context, msg string, keysAndValues Fields) {
if l.V(WarnLevel) {
- l.log.Warnw(msg, serializeMap(keysAndValues)...)
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Warnw(msg, serializeMap(keysAndValues)...)
}
}
// Error logs a message at level Error on the standard logger.
-func (l logger) Error(args ...interface{}) {
- l.log.Error(args...)
+func (l clogger) Error(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Error(args...)
}
// Errorln logs a message at level Error on the standard logger with a line feed. Default in any case.
-func (l logger) Errorln(args ...interface{}) {
- l.log.Error(args...)
+func (l clogger) Errorln(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Error(args...)
}
// Errorf logs a message at level Error on the standard logger.
-func (l logger) Errorf(format string, args ...interface{}) {
- l.log.Errorf(format, args...)
+func (l clogger) Errorf(ctx context.Context, format string, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Errorf(format, args...)
}
// Errorw logs a message with some additional context. The variadic key-value
// pairs are treated as they are in With.
-func (l logger) Errorw(msg string, keysAndValues Fields) {
+func (l clogger) Errorw(ctx context.Context, msg string, keysAndValues Fields) {
if l.V(ErrorLevel) {
- l.log.Errorw(msg, serializeMap(keysAndValues)...)
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Errorw(msg, serializeMap(keysAndValues)...)
}
}
// Fatal logs a message at level Fatal on the standard logger.
-func (l logger) Fatal(args ...interface{}) {
- l.log.Fatal(args...)
+func (l clogger) Fatal(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Fatal(args...)
}
// Fatalln logs a message at level Fatal on the standard logger with a line feed. Default in any case.
-func (l logger) Fatalln(args ...interface{}) {
- l.log.Fatal(args...)
+func (l clogger) Fatalln(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Fatal(args...)
}
// Fatalf logs a message at level Fatal on the standard logger.
-func (l logger) Fatalf(format string, args ...interface{}) {
- l.log.Fatalf(format, args...)
+func (l clogger) Fatalf(ctx context.Context, format string, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Fatalf(format, args...)
}
// Fatalw logs a message with some additional context. The variadic key-value
// pairs are treated as they are in With.
-func (l logger) Fatalw(msg string, keysAndValues Fields) {
+func (l clogger) Fatalw(ctx context.Context, msg string, keysAndValues Fields) {
if l.V(FatalLevel) {
- l.log.Fatalw(msg, serializeMap(keysAndValues)...)
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Fatalw(msg, serializeMap(keysAndValues)...)
}
}
// Warning logs a message at level Warn on the standard logger.
-func (l logger) Warning(args ...interface{}) {
- l.log.Warn(args...)
+func (l clogger) Warning(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Warn(args...)
}
// Warningln logs a message at level Warn on the standard logger with a line feed. Default in any case.
-func (l logger) Warningln(args ...interface{}) {
- l.log.Warn(args...)
+func (l clogger) Warningln(ctx context.Context, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Warn(args...)
}
// Warningf logs a message at level Warn on the standard logger.
-func (l logger) Warningf(format string, args ...interface{}) {
- l.log.Warnf(format, args...)
+func (l clogger) Warningf(ctx context.Context, format string, args ...interface{}) {
+ l.log.With(GetGlobalLFM().ExtractContextAttributes(ctx)...).Warnf(format, args...)
}
// V reports whether verbosity level l is at least the requested verbose level.
-func (l logger) V(level LogLevel) bool {
+func (l clogger) V(level LogLevel) bool {
return l.parent.Core().Enabled(logLevelToLevel(level))
}
// GetLogLevel returns the current level of the logger
-func (l logger) GetLogLevel() LogLevel {
+func (l clogger) GetLogLevel() LogLevel {
return levelToLogLevel(cfgs[l.packageName].Level.Level())
}
-
-// With returns a logger initialized with the key-value pairs
-func With(keysAndValues Fields) Logger {
- return logger{log: getPackageLevelSugaredLogger().With(serializeMap(keysAndValues)...), parent: defaultLogger.parent}
-}
-
-// Debug logs a message at level Debug on the standard logger.
-func Debug(args ...interface{}) {
- getPackageLevelSugaredLogger().Debug(args...)
-}
-
-// Debugln logs a message at level Debug on the standard logger.
-func Debugln(args ...interface{}) {
- getPackageLevelSugaredLogger().Debug(args...)
-}
-
-// Debugf logs a message at level Debug on the standard logger.
-func Debugf(format string, args ...interface{}) {
- getPackageLevelSugaredLogger().Debugf(format, args...)
-}
-
-// Debugw logs a message with some additional context. The variadic key-value
-// pairs are treated as they are in With.
-func Debugw(msg string, keysAndValues Fields) {
- getPackageLevelSugaredLogger().Debugw(msg, serializeMap(keysAndValues)...)
-}
-
-// Info logs a message at level Info on the standard logger.
-func Info(args ...interface{}) {
- getPackageLevelSugaredLogger().Info(args...)
-}
-
-// Infoln logs a message at level Info on the standard logger.
-func Infoln(args ...interface{}) {
- getPackageLevelSugaredLogger().Info(args...)
-}
-
-// Infof logs a message at level Info on the standard logger.
-func Infof(format string, args ...interface{}) {
- getPackageLevelSugaredLogger().Infof(format, args...)
-}
-
-//Infow logs a message with some additional context. The variadic key-value
-//pairs are treated as they are in With.
-func Infow(msg string, keysAndValues Fields) {
- getPackageLevelSugaredLogger().Infow(msg, serializeMap(keysAndValues)...)
-}
-
-// Warn logs a message at level Warn on the standard logger.
-func Warn(args ...interface{}) {
- getPackageLevelSugaredLogger().Warn(args...)
-}
-
-// Warnln logs a message at level Warn on the standard logger.
-func Warnln(args ...interface{}) {
- getPackageLevelSugaredLogger().Warn(args...)
-}
-
-// Warnf logs a message at level Warn on the standard logger.
-func Warnf(format string, args ...interface{}) {
- getPackageLevelSugaredLogger().Warnf(format, args...)
-}
-
-// Warnw logs a message with some additional context. The variadic key-value
-// pairs are treated as they are in With.
-func Warnw(msg string, keysAndValues Fields) {
- getPackageLevelSugaredLogger().Warnw(msg, serializeMap(keysAndValues)...)
-}
-
-// Error logs a message at level Error on the standard logger.
-func Error(args ...interface{}) {
- getPackageLevelSugaredLogger().Error(args...)
-}
-
-// Errorln logs a message at level Error on the standard logger.
-func Errorln(args ...interface{}) {
- getPackageLevelSugaredLogger().Error(args...)
-}
-
-// Errorf logs a message at level Error on the standard logger.
-func Errorf(format string, args ...interface{}) {
- getPackageLevelSugaredLogger().Errorf(format, args...)
-}
-
-// Errorw logs a message with some additional context. The variadic key-value
-// pairs are treated as they are in With.
-func Errorw(msg string, keysAndValues Fields) {
- getPackageLevelSugaredLogger().Errorw(msg, serializeMap(keysAndValues)...)
-}
-
-// Fatal logs a message at level Fatal on the standard logger.
-func Fatal(args ...interface{}) {
- getPackageLevelSugaredLogger().Fatal(args...)
-}
-
-// Fatalln logs a message at level Fatal on the standard logger.
-func Fatalln(args ...interface{}) {
- getPackageLevelSugaredLogger().Fatal(args...)
-}
-
-// Fatalf logs a message at level Fatal on the standard logger.
-func Fatalf(format string, args ...interface{}) {
- getPackageLevelSugaredLogger().Fatalf(format, args...)
-}
-
-// Fatalw logs a message with some additional context. The variadic key-value
-// pairs are treated as they are in With.
-func Fatalw(msg string, keysAndValues Fields) {
- getPackageLevelSugaredLogger().Fatalw(msg, serializeMap(keysAndValues)...)
-}
-
-// Warning logs a message at level Warn on the standard logger.
-func Warning(args ...interface{}) {
- getPackageLevelSugaredLogger().Warn(args...)
-}
-
-// Warningln logs a message at level Warn on the standard logger.
-func Warningln(args ...interface{}) {
- getPackageLevelSugaredLogger().Warn(args...)
-}
-
-// Warningf logs a message at level Warn on the standard logger.
-func Warningf(format string, args ...interface{}) {
- getPackageLevelSugaredLogger().Warnf(format, args...)
-}
-
-// V reports whether verbosity level l is at least the requested verbose level.
-func V(level LogLevel) bool {
- return getPackageLevelLogger().V(level)
-}
-
-//GetLogLevel returns the log level of the invoking package
-func GetLogLevel() LogLevel {
- return getPackageLevelLogger().GetLogLevel()
-}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/utils.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/utils.go
new file mode 100644
index 0000000..82c3d7d
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/log/utils.go
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// File contains utility functions to support Open Tracing in conjunction with
+// Enhanced Logging based on context propagation
+
+package log
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "github.com/opentracing/opentracing-go"
+ jtracing "github.com/uber/jaeger-client-go"
+ jcfg "github.com/uber/jaeger-client-go/config"
+ "io"
+ "os"
+ "strings"
+ "sync"
+)
+
+const (
+ RootSpanNameKey = "op-name"
+)
+
+// Global Settings governing the Log Correlation and Tracing features. Should only
+// be updated through the exposed public methods
+type LogFeaturesManager struct {
+ isTracePublishingEnabled bool
+ isLogCorrelationEnabled bool
+ componentName string // Name of component extracted from ENV variable
+ activeTraceAgentAddress string
+ lock sync.Mutex
+}
+
+var globalLFM *LogFeaturesManager = &LogFeaturesManager{}
+
+func GetGlobalLFM() *LogFeaturesManager {
+ return globalLFM
+}
+
+// A Wrapper to utilize currently Active Tracer instance. The middleware library being used for generating
+// Spans for GRPC API calls does not support dynamically setting the Active Tracer similar to the SetGlobalTracer method
+// provided by OpenTracing API
+type ActiveTracerProxy struct {
+}
+
+func (atw ActiveTracerProxy) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
+ return opentracing.GlobalTracer().StartSpan(operationName, opts...)
+}
+
+func (atw ActiveTracerProxy) Inject(sm opentracing.SpanContext, format interface{}, carrier interface{}) error {
+ return opentracing.GlobalTracer().Inject(sm, format, carrier)
+}
+
+func (atw ActiveTracerProxy) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
+ return opentracing.GlobalTracer().Extract(format, carrier)
+}
+
+// Jaeger complaint Logger instance to redirect logs to Default Logger
+type traceLogger struct {
+ logger *clogger
+}
+
+func (tl traceLogger) Error(msg string) {
+ tl.logger.Error(context.Background(), msg)
+}
+
+func (tl traceLogger) Infof(msg string, args ...interface{}) {
+ // Tracing logs should be performed only at Debug Verbosity
+ tl.logger.Debugf(context.Background(), msg, args...)
+}
+
+// Wrapper to handle correct Closer call at the time of Process Termination
+type traceCloser struct {
+}
+
+func (c traceCloser) Close() error {
+ currentActiveTracer := opentracing.GlobalTracer()
+ if currentActiveTracer != nil {
+ if jTracer, ok := currentActiveTracer.(*jtracing.Tracer); ok {
+ jTracer.Close()
+ }
+ }
+
+ return nil
+}
+
+// Method to Initialize Jaeger based Tracing client based on initial status of Tracing Publish and Log Correlation
+func (lfm *LogFeaturesManager) InitTracingAndLogCorrelation(tracePublishEnabled bool, traceAgentAddress string, logCorrelationEnabled bool) (io.Closer, error) {
+ lfm.componentName = os.Getenv("COMPONENT_NAME")
+ if lfm.componentName == "" {
+ return nil, errors.New("Unable to retrieve PoD Component Name from Runtime env")
+ }
+
+ lfm.lock.Lock()
+ defer lfm.lock.Unlock()
+
+ // Use NoopTracer when both Tracing Publishing and Log Correlation are disabled
+ if !tracePublishEnabled && !logCorrelationEnabled {
+ logger.Info(context.Background(), "Skipping Global Tracer initialization as both Trace publish and Log correlation are configured as disabled")
+ lfm.isTracePublishingEnabled = false
+ lfm.isLogCorrelationEnabled = false
+ opentracing.SetGlobalTracer(opentracing.NoopTracer{})
+ return traceCloser{}, nil
+ }
+
+ tracer, _, err := lfm.constructJaegerTracer(tracePublishEnabled, traceAgentAddress, true)
+ if err != nil {
+ return nil, err
+ }
+
+ // Initialize variables representing Active Status
+ opentracing.SetGlobalTracer(tracer)
+ lfm.isTracePublishingEnabled = tracePublishEnabled
+ lfm.activeTraceAgentAddress = traceAgentAddress
+ lfm.isLogCorrelationEnabled = logCorrelationEnabled
+ return traceCloser{}, nil
+}
+
+// Method to replace Active Tracer along with graceful closer of previous tracer
+func (lfm *LogFeaturesManager) replaceActiveTracer(tracer opentracing.Tracer) {
+ currentActiveTracer := opentracing.GlobalTracer()
+ opentracing.SetGlobalTracer(tracer)
+
+ if currentActiveTracer != nil {
+ if jTracer, ok := currentActiveTracer.(*jtracing.Tracer); ok {
+ jTracer.Close()
+ }
+ }
+}
+
+func (lfm *LogFeaturesManager) GetLogCorrelationStatus() bool {
+ lfm.lock.Lock()
+ defer lfm.lock.Unlock()
+
+ return lfm.isLogCorrelationEnabled
+}
+
+func (lfm *LogFeaturesManager) SetLogCorrelationStatus(isEnabled bool) {
+ lfm.lock.Lock()
+ defer lfm.lock.Unlock()
+
+ if isEnabled == lfm.isLogCorrelationEnabled {
+ logger.Debugf(context.Background(), "Ignoring Log Correlation Set operation with value %t; current Status same as desired", isEnabled)
+ return
+ }
+
+ if isEnabled {
+ // Construct new Tracer instance if Log Correlation has been enabled and current active tracer is a NoopTracer instance.
+ // Continue using the earlier tracer instance in case of any error
+ if _, ok := opentracing.GlobalTracer().(opentracing.NoopTracer); ok {
+ tracer, _, err := lfm.constructJaegerTracer(lfm.isTracePublishingEnabled, lfm.activeTraceAgentAddress, false)
+ if err != nil {
+ logger.Warnf(context.Background(), "Log Correlation Enable operation failed with error: %s", err.Error())
+ return
+ }
+
+ lfm.replaceActiveTracer(tracer)
+ }
+
+ lfm.isLogCorrelationEnabled = true
+ logger.Info(context.Background(), "Log Correlation has been enabled")
+
+ } else {
+ // Switch to NoopTracer when Log Correlation has been disabled and Tracing Publish is already disabled
+ if _, ok := opentracing.GlobalTracer().(opentracing.NoopTracer); !ok && !lfm.isTracePublishingEnabled {
+ lfm.replaceActiveTracer(opentracing.NoopTracer{})
+ }
+
+ lfm.isLogCorrelationEnabled = false
+ logger.Info(context.Background(), "Log Correlation has been disabled")
+ }
+}
+
+func (lfm *LogFeaturesManager) GetTracePublishingStatus() bool {
+ lfm.lock.Lock()
+ defer lfm.lock.Unlock()
+
+ return lfm.isTracePublishingEnabled
+}
+
+func (lfm *LogFeaturesManager) SetTracePublishingStatus(isEnabled bool) {
+ lfm.lock.Lock()
+ defer lfm.lock.Unlock()
+
+ if isEnabled == lfm.isTracePublishingEnabled {
+ logger.Debugf(context.Background(), "Ignoring Trace Publishing Set operation with value %t; current Status same as desired", isEnabled)
+ return
+ }
+
+ if isEnabled {
+ // Construct new Tracer instance if Tracing Publish has been enabled (even if a Jaeger instance is already active)
+ // This is needed to ensure that a fresh lookup of Jaeger Agent address is performed again while performing
+ // Disable-Enable of Tracing
+ tracer, _, err := lfm.constructJaegerTracer(isEnabled, lfm.activeTraceAgentAddress, false)
+ if err != nil {
+ logger.Warnf(context.Background(), "Trace Publishing Enable operation failed with error: %s", err.Error())
+ return
+ }
+ lfm.replaceActiveTracer(tracer)
+
+ lfm.isTracePublishingEnabled = true
+ logger.Info(context.Background(), "Tracing Publishing has been enabled")
+ } else {
+ // Switch to NoopTracer when Tracing Publish has been disabled and Log Correlation is already disabled
+ if !lfm.isLogCorrelationEnabled {
+ lfm.replaceActiveTracer(opentracing.NoopTracer{})
+ } else {
+ // Else construct a new Jaeger Instance with publishing disabled
+ tracer, _, err := lfm.constructJaegerTracer(isEnabled, lfm.activeTraceAgentAddress, false)
+ if err != nil {
+ logger.Warnf(context.Background(), "Trace Publishing Disable operation failed with error: %s", err.Error())
+ return
+ }
+ lfm.replaceActiveTracer(tracer)
+ }
+
+ lfm.isTracePublishingEnabled = false
+ logger.Info(context.Background(), "Tracing Publishing has been disabled")
+ }
+}
+
+// Method to contruct a new Jaeger Tracer instance based on given Trace Agent address and Publish status.
+// The last attribute indicates whether to use Loopback IP for creating Jaeger Client when the DNS lookup
+// of supplied Trace Agent address has failed. It is fine to fallback during the initialization step, but
+// not later (when enabling/disabling the status dynamically)
+func (lfm *LogFeaturesManager) constructJaegerTracer(tracePublishEnabled bool, traceAgentAddress string, fallbackToLoopbackAllowed bool) (opentracing.Tracer, io.Closer, error) {
+ cfg := jcfg.Configuration{ServiceName: lfm.componentName}
+
+ var err error
+ var jReporterConfig jcfg.ReporterConfig
+ var jReporterCfgOption jtracing.Reporter
+
+ logger.Info(context.Background(), "Constructing new Jaeger Tracer instance")
+
+ // Attempt Trace Agent Address first; will fallback to Loopback IP if it fails
+ jReporterConfig = jcfg.ReporterConfig{LocalAgentHostPort: traceAgentAddress, LogSpans: true}
+ jReporterCfgOption, err = jReporterConfig.NewReporter(lfm.componentName, jtracing.NewNullMetrics(), traceLogger{logger: logger.(*clogger)})
+
+ if err != nil {
+ if !fallbackToLoopbackAllowed {
+ return nil, nil, errors.New("Reporter Creation for given Trace Agent address " + traceAgentAddress + " failed with error : " + err.Error())
+ }
+
+ logger.Infow(context.Background(), "Unable to create Reporter with given Trace Agent address",
+ Fields{"error": err, "address": traceAgentAddress})
+ // The Reporter initialization may fail due to Invalid Agent address or non-existent Agent (DNS lookup failure).
+ // It is essential for Tracer Instance to still start for correct Span propagation needed for log correlation.
+ // Thus, falback to use loopback IP for Reporter initialization before throwing back any error
+ tracePublishEnabled = false
+
+ jReporterConfig.LocalAgentHostPort = "127.0.0.1:6831"
+ jReporterCfgOption, err = jReporterConfig.NewReporter(lfm.componentName, jtracing.NewNullMetrics(), traceLogger{logger: logger.(*clogger)})
+ if err != nil {
+ return nil, nil, errors.New("Failed to initialize Jaeger Tracing due to Reporter creation error : " + err.Error())
+ }
+ }
+
+ // To start with, we are using Constant Sampling type
+ samplerParam := 0 // 0: Do not publish span, 1: Publish
+ if tracePublishEnabled {
+ samplerParam = 1
+ }
+ jSamplerConfig := jcfg.SamplerConfig{Type: "const", Param: float64(samplerParam)}
+ jSamplerCfgOption, err := jSamplerConfig.NewSampler(lfm.componentName, jtracing.NewNullMetrics())
+ if err != nil {
+ return nil, nil, errors.New("Unable to create Sampler : " + err.Error())
+ }
+
+ return cfg.NewTracer(jcfg.Reporter(jReporterCfgOption), jcfg.Sampler(jSamplerCfgOption))
+}
+
+func TerminateTracing(c io.Closer) {
+ err := c.Close()
+ if err != nil {
+ logger.Error(context.Background(), "error-while-closing-jaeger-tracer", Fields{"err": err})
+ }
+}
+
+// Extracts details of Execution Context as log fields from the Tracing Span injected into the
+// context instance. Following log fields are extracted:
+// 1. Operation Name : key as 'op-name' and value as Span operation name
+// 2. Operation Id : key as 'op-id' and value as 64 bit Span Id in hex digits string
+//
+// Additionally, any tags present in Span are also extracted to use as log fields e.g. device-id.
+//
+// If no Span is found associated with context, blank slice is returned without any log fields
+func (lfm *LogFeaturesManager) ExtractContextAttributes(ctx context.Context) []interface{} {
+ if !lfm.isLogCorrelationEnabled {
+ return make([]interface{}, 0)
+ }
+
+ attrMap := make(map[string]interface{})
+
+ if ctx != nil {
+ if span := opentracing.SpanFromContext(ctx); span != nil {
+ if jspan, ok := span.(*jtracing.Span); ok {
+ // Add Log fields for operation identified by Root Level Span (Trace)
+ opId := fmt.Sprintf("%016x", jspan.SpanContext().TraceID().Low) // Using Sprintf to avoid removal of leading 0s
+ opName := jspan.BaggageItem(RootSpanNameKey)
+
+ taskId := fmt.Sprintf("%016x", uint64(jspan.SpanContext().SpanID())) // Using Sprintf to avoid removal of leading 0s
+ taskName := jspan.OperationName()
+
+ if opName == "" {
+ span.SetBaggageItem(RootSpanNameKey, taskName)
+ opName = taskName
+ }
+
+ attrMap["op-id"] = opId
+ attrMap["op-name"] = opName
+
+ // Add Log fields for task identified by Current Span, if it is different
+ // than operation
+ if taskId != opId {
+ attrMap["task-id"] = taskId
+ attrMap["task-name"] = taskName
+ }
+
+ for k, v := range jspan.Tags() {
+ // Ignore the special tags added by Jaeger, middleware (sampler.type, span.*) present in the span
+ if strings.HasPrefix(k, "sampler.") || strings.HasPrefix(k, "span.") || k == "component" {
+ continue
+ }
+
+ attrMap[k] = v
+ }
+
+ processBaggageItems := func(k, v string) bool {
+ if k != "rpc-span-name" {
+ attrMap[k] = v
+ }
+ return true
+ }
+
+ jspan.SpanContext().ForeachBaggageItem(processBaggageItems)
+ }
+ }
+ }
+
+ return serializeMap(attrMap)
+}
+
+// Method to inject additional log fields into Span e.g. device-id
+func EnrichSpan(ctx context.Context, keyAndValues ...Fields) {
+ span := opentracing.SpanFromContext(ctx)
+ if span != nil {
+ if jspan, ok := span.(*jtracing.Span); ok {
+ // Inject as a BaggageItem when the Span is the Root Span so that it propagates
+ // across the components along with Root Span (called as Trace)
+ // Else, inject as a Tag so that it is attached to the Child Task
+ isRootSpan := false
+ if jspan.SpanContext().TraceID().String() == jspan.SpanContext().SpanID().String() {
+ isRootSpan = true
+ }
+
+ for _, field := range keyAndValues {
+ for k, v := range field {
+ if isRootSpan {
+ span.SetBaggageItem(k, v.(string))
+ } else {
+ span.SetTag(k, v)
+ }
+ }
+ }
+ }
+ }
+}
+
+// Method to inject Error into the Span in event of any operation failure
+func MarkSpanError(ctx context.Context, err error) {
+ span := opentracing.SpanFromContext(ctx)
+ if span != nil {
+ span.SetTag("error", true)
+ span.SetTag("err", err)
+ }
+}
+
+// Creates a Child Span from Parent Span embedded in passed context. Should be used before starting a new major
+// operation in Synchronous or Asynchronous mode (go routine), such as following:
+// 1. Start of all implemented External API methods unless using a interceptor for auto-injection of Span (Server side impl)
+// 2. Just before calling an Third-Party lib which is invoking a External API (etcd, kafka)
+// 3. In start of a Go Routine responsible for performing a major task involving significant duration
+// 4. Any method which is suspected to be time consuming...
+func CreateChildSpan(ctx context.Context, taskName string, keyAndValues ...Fields) (opentracing.Span, context.Context) {
+ if !GetGlobalLFM().GetLogCorrelationStatus() && !GetGlobalLFM().GetTracePublishingStatus() {
+ return opentracing.NoopTracer{}.StartSpan(taskName), ctx
+ }
+
+ parentSpan := opentracing.SpanFromContext(ctx)
+ childSpan, newCtx := opentracing.StartSpanFromContext(ctx, taskName)
+
+ if parentSpan == nil || parentSpan.BaggageItem(RootSpanNameKey) == "" {
+ childSpan.SetBaggageItem(RootSpanNameKey, taskName)
+ }
+
+ EnrichSpan(newCtx, keyAndValues...)
+ return childSpan, newCtx
+}
+
+// Creates a Async Child Span with Follows-From relationship from Parent Span embedded in passed context.
+// Should be used only in scenarios when
+// a) There is dis-continuation in execution and thus result of Child span does not affect the Parent flow at all
+// b) The execution of Child Span is guaranteed to start after the completion of Parent Span
+// In case of any confusion, use CreateChildSpan method
+// Some situations where this method would be suitable includes Kafka Async RPC call, Propagation of Event across
+// a channel etc.
+func CreateAsyncSpan(ctx context.Context, taskName string, keyAndValues ...Fields) (opentracing.Span, context.Context) {
+ if !GetGlobalLFM().GetLogCorrelationStatus() && !GetGlobalLFM().GetTracePublishingStatus() {
+ return opentracing.NoopTracer{}.StartSpan(taskName), ctx
+ }
+
+ var asyncSpan opentracing.Span
+ var newCtx context.Context
+
+ parentSpan := opentracing.SpanFromContext(ctx)
+
+ // We should always be creating Aysnc span from a Valid parent span. If not, create a Child span instead
+ if parentSpan == nil {
+ logger.Warn(context.Background(), "Async span must be created with a Valid parent span only")
+ asyncSpan, newCtx = opentracing.StartSpanFromContext(ctx, taskName)
+ } else {
+ // Use Background context as the base for Follows-from case; else new span is getting both Child and FollowsFrom relationship
+ asyncSpan, newCtx = opentracing.StartSpanFromContext(context.Background(), taskName, opentracing.FollowsFrom(parentSpan.Context()))
+ }
+
+ if parentSpan == nil || parentSpan.BaggageItem(RootSpanNameKey) == "" {
+ asyncSpan.SetBaggageItem(RootSpanNameKey, taskName)
+ }
+
+ EnrichSpan(newCtx, keyAndValues...)
+ return asyncSpan, newCtx
+}
+
+// Extracts the span from Source context and injects into the supplied Target context.
+// This should be used in situations wherein we are calling a time-sensitive operation (etcd update) and hence
+// had a context.Background() used earlier to avoid any cancellation/timeout of operation by passed context.
+// This will allow propagation of span with a different base context (and not the original context)
+func WithSpanFromContext(targetCtx, sourceCtx context.Context) context.Context {
+ span := opentracing.SpanFromContext(sourceCtx)
+ return opentracing.ContextWithSpan(targetCtx, span)
+}
+
+// Utility method to convert log Fields into array of interfaces expected by zap logger methods
+func serializeMap(fields Fields) []interface{} {
+ data := make([]interface{}, len(fields)*2)
+ i := 0
+ for k, v := range fields {
+ data[i] = k
+ data[i+1] = v
+ i = i + 2
+ }
+ return data
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v3/go/voltha/adapter.pb.go b/vendor/github.com/opencord/voltha-protos/v3/go/voltha/adapter.pb.go
index 9359dc1..3d12f3f 100644
--- a/vendor/github.com/opencord/voltha-protos/v3/go/voltha/adapter.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v3/go/voltha/adapter.pb.go
@@ -238,34 +238,34 @@
func init() { proto.RegisterFile("voltha_protos/adapter.proto", fileDescriptor_7e998ce153307274) }
var fileDescriptor_7e998ce153307274 = []byte{
- // 463 bytes of a gzipped FileDescriptorProto
+ // 455 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0xdd, 0x6e, 0xd3, 0x30,
- 0x14, 0x56, 0xda, 0x35, 0x6d, 0x3d, 0x15, 0x3a, 0x43, 0x91, 0x09, 0x9a, 0x16, 0x55, 0x80, 0x72,
- 0xc1, 0x12, 0xb1, 0xbd, 0x00, 0xed, 0x76, 0xb3, 0x5b, 0x6b, 0xe2, 0x82, 0x9b, 0xca, 0xb5, 0xbd,
- 0xcc, 0x52, 0xe2, 0x13, 0xc5, 0x6e, 0xa4, 0x3e, 0x24, 0x2f, 0xc0, 0x13, 0xf0, 0x04, 0x5c, 0xa3,
- 0x3a, 0x0e, 0xfd, 0x41, 0xda, 0x55, 0x72, 0xbe, 0xef, 0x3b, 0xdf, 0xf9, 0x33, 0xfa, 0xd0, 0x40,
- 0x61, 0x9f, 0xd9, 0xaa, 0xaa, 0xc1, 0x82, 0xc9, 0x98, 0x60, 0x95, 0x95, 0x75, 0xea, 0x42, 0x1c,
- 0xb6, 0x64, 0xf4, 0x3e, 0x07, 0xc8, 0x0b, 0x99, 0x39, 0x74, 0xbd, 0x79, 0xca, 0x98, 0xde, 0xb6,
- 0x92, 0x28, 0x3a, 0xce, 0xe7, 0x50, 0x96, 0xa0, 0x3d, 0x47, 0x8e, 0xb9, 0x52, 0x5a, 0xe6, 0x99,
- 0xab, 0x53, 0x43, 0xab, 0x4a, 0x69, 0x2c, 0x2b, 0xab, 0x56, 0x30, 0xa7, 0x68, 0xb2, 0x68, 0x5b,
- 0xb9, 0x03, 0xfd, 0xa4, 0x72, 0xbc, 0x40, 0x17, 0x4c, 0x08, 0x65, 0x15, 0x68, 0x56, 0xac, 0xb8,
- 0x03, 0xc9, 0xb7, 0x38, 0x48, 0xce, 0x6f, 0xde, 0xa6, 0xad, 0x5b, 0xda, 0xb9, 0xa5, 0x0b, 0xbd,
- 0xa5, 0xd3, 0xbd, 0xbc, 0xb5, 0x98, 0xff, 0xea, 0xa3, 0xa1, 0x37, 0xc5, 0x33, 0xd4, 0x53, 0x82,
- 0x04, 0x71, 0x90, 0x8c, 0x97, 0x83, 0xdf, 0x7f, 0x7e, 0x5e, 0x06, 0xb4, 0xa7, 0x04, 0xbe, 0x44,
- 0x61, 0x23, 0xb5, 0x80, 0x9a, 0xf4, 0x0e, 0x29, 0x0f, 0xe2, 0x2b, 0x34, 0x6c, 0x64, 0x6d, 0x14,
- 0x68, 0xd2, 0x3f, 0xe4, 0x3b, 0x14, 0x5f, 0xa3, 0xd0, 0xb7, 0x36, 0x75, 0xad, 0xcd, 0xd2, 0x76,
- 0x05, 0xe9, 0xd1, 0x30, 0xd4, 0x8b, 0x30, 0x45, 0xef, 0x0e, 0x86, 0x12, 0xd2, 0xf0, 0x5a, 0x55,
- 0xbb, 0xe8, 0xa5, 0xc9, 0xba, 0xa2, 0xb3, 0x7d, 0xea, 0xfd, 0x3e, 0x13, 0x7f, 0x41, 0xb8, 0x80,
- 0x5c, 0x71, 0x67, 0xd8, 0x28, 0x2e, 0x57, 0x4a, 0x18, 0x72, 0x16, 0xf7, 0x93, 0x31, 0x9d, 0x7a,
- 0xe6, 0xde, 0x11, 0x0f, 0xc2, 0xe0, 0x07, 0x84, 0x0b, 0x66, 0xec, 0x6a, 0x77, 0xb7, 0x8d, 0x56,
- 0x9c, 0xb9, 0xea, 0x03, 0x57, 0x3d, 0xfa, 0xaf, 0xfa, 0x63, 0x77, 0x25, 0x7a, 0xb1, 0xcb, 0xba,
- 0x3b, 0x4c, 0xc2, 0x9f, 0xd1, 0x2b, 0xbe, 0xa9, 0x6b, 0xa9, 0x2d, 0x95, 0x55, 0xa1, 0x38, 0x23,
- 0x61, 0x1c, 0x24, 0x03, 0x7a, 0x82, 0xe2, 0x8f, 0x68, 0x62, 0xc1, 0xb2, 0xc2, 0xc7, 0x86, 0x0c,
- 0x9d, 0xec, 0x18, 0xc4, 0x11, 0x1a, 0x49, 0x2d, 0x2a, 0x50, 0xda, 0x92, 0xd1, 0x6e, 0xd7, 0xf4,
- 0x5f, 0x8c, 0x31, 0x3a, 0xb3, 0xdb, 0x4a, 0x92, 0xb1, 0xc3, 0xdd, 0xff, 0xfc, 0x2b, 0x1a, 0xf9,
- 0x1d, 0x1b, 0xfc, 0x09, 0x0d, 0x94, 0x95, 0xa5, 0x21, 0x41, 0xdc, 0x4f, 0xce, 0x6f, 0x5e, 0x9f,
- 0x1c, 0x81, 0xb6, 0xec, 0xf2, 0x11, 0xbd, 0x81, 0x3a, 0x4f, 0xa1, 0x92, 0x9a, 0x43, 0x2d, 0xbc,
- 0x6a, 0x39, 0xf9, 0xee, 0xbe, 0x5e, 0xfc, 0x23, 0xcd, 0x95, 0x7d, 0xde, 0xac, 0x53, 0x0e, 0x65,
- 0xd6, 0x49, 0xb3, 0x56, 0x7a, 0xed, 0x1f, 0x76, 0x73, 0x9b, 0xe5, 0xe0, 0xb1, 0x75, 0xe8, 0xc0,
- 0xdb, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xef, 0x64, 0x5e, 0x10, 0x59, 0x03, 0x00, 0x00,
+ 0x14, 0x56, 0xda, 0xf5, 0xcf, 0x53, 0xa1, 0x33, 0x14, 0x99, 0xa2, 0x69, 0x51, 0x05, 0x28, 0x17,
+ 0x2c, 0x11, 0xdb, 0x0b, 0xd0, 0x6e, 0x37, 0xbb, 0xb5, 0x26, 0x2e, 0xb8, 0xa9, 0x5c, 0xdb, 0xcb,
+ 0x2c, 0x25, 0x3e, 0x51, 0xec, 0x46, 0xea, 0x43, 0xf2, 0x02, 0x3c, 0x01, 0x4f, 0xc0, 0x35, 0xaa,
+ 0xed, 0xd0, 0x1f, 0xa4, 0x5d, 0x25, 0xe7, 0xfb, 0x39, 0x9f, 0xcf, 0xb1, 0xd1, 0x87, 0x06, 0x0a,
+ 0xfb, 0xcc, 0x56, 0x55, 0x0d, 0x16, 0x4c, 0xc6, 0x04, 0xab, 0xac, 0xac, 0x53, 0x57, 0xe2, 0xbe,
+ 0x27, 0x67, 0xef, 0x73, 0x80, 0xbc, 0x90, 0x99, 0x43, 0xd7, 0x9b, 0xa7, 0x8c, 0xe9, 0xad, 0x97,
+ 0xcc, 0xc8, 0xb1, 0xbf, 0x94, 0x96, 0x05, 0xe6, 0xea, 0xd4, 0x64, 0x55, 0x29, 0x8d, 0x65, 0x65,
+ 0xe5, 0x05, 0x73, 0x8a, 0xc6, 0x0b, 0x1f, 0x77, 0x07, 0xfa, 0x49, 0xe5, 0x78, 0x81, 0x2e, 0x98,
+ 0x10, 0xca, 0x2a, 0xd0, 0xac, 0x58, 0x71, 0x07, 0x92, 0x6f, 0x71, 0x94, 0x9c, 0xdf, 0xbc, 0x4d,
+ 0x7d, 0xb7, 0xb4, 0xed, 0x96, 0x2e, 0xf4, 0x96, 0x4e, 0xf6, 0x72, 0xdf, 0x62, 0xfe, 0xab, 0x8b,
+ 0x06, 0xa1, 0x29, 0x9e, 0xa2, 0x8e, 0x12, 0x24, 0x8a, 0xa3, 0x64, 0xb4, 0xec, 0xfd, 0xfe, 0xf3,
+ 0xf3, 0x32, 0xa2, 0x1d, 0x25, 0xf0, 0x25, 0xea, 0x37, 0x52, 0x0b, 0xa8, 0x49, 0xe7, 0x90, 0x0a,
+ 0x20, 0xbe, 0x42, 0x83, 0x46, 0xd6, 0x46, 0x81, 0x26, 0xdd, 0x43, 0xbe, 0x45, 0xf1, 0x35, 0xea,
+ 0x87, 0xa3, 0x4d, 0xdc, 0xd1, 0xa6, 0xa9, 0x5f, 0x41, 0x7a, 0x34, 0x0c, 0x0d, 0x22, 0x4c, 0xd1,
+ 0xbb, 0x83, 0xa1, 0x84, 0x34, 0xbc, 0x56, 0xd5, 0xae, 0x7a, 0x69, 0xb2, 0x36, 0x74, 0xba, 0xb7,
+ 0xde, 0xef, 0x9d, 0xf8, 0x0b, 0xc2, 0x05, 0xe4, 0x8a, 0xbb, 0x86, 0x8d, 0xe2, 0x72, 0xa5, 0x84,
+ 0x21, 0x67, 0x71, 0x37, 0x19, 0xd1, 0x49, 0x60, 0xee, 0x1d, 0xf1, 0x20, 0x0c, 0x7e, 0x40, 0xb8,
+ 0x60, 0xc6, 0xae, 0x38, 0x94, 0xe5, 0x46, 0x2b, 0xce, 0x5c, 0x7a, 0xcf, 0xa5, 0xcf, 0xfe, 0x4b,
+ 0x7f, 0x6c, 0x6f, 0x89, 0x5e, 0xec, 0x5c, 0x77, 0x87, 0x26, 0xfc, 0x19, 0xbd, 0xe2, 0x9b, 0xba,
+ 0x96, 0xda, 0x52, 0x59, 0x15, 0x8a, 0x33, 0xd2, 0x8f, 0xa3, 0xa4, 0x47, 0x4f, 0x50, 0xfc, 0x11,
+ 0x8d, 0x2d, 0x58, 0x56, 0x84, 0xda, 0x90, 0x81, 0x93, 0x1d, 0x83, 0x78, 0x86, 0x86, 0x52, 0x8b,
+ 0x0a, 0x94, 0xb6, 0x64, 0xb8, 0xdb, 0x35, 0xfd, 0x57, 0x63, 0x8c, 0xce, 0xec, 0xb6, 0x92, 0x64,
+ 0xe4, 0x70, 0xf7, 0x3f, 0xff, 0x8a, 0x86, 0x61, 0xc7, 0x06, 0x7f, 0x42, 0x3d, 0x65, 0x65, 0x69,
+ 0x48, 0x14, 0x77, 0x93, 0xf3, 0x9b, 0xd7, 0x27, 0x97, 0x40, 0x3d, 0xbb, 0x7c, 0x44, 0x6f, 0xa0,
+ 0xce, 0x53, 0xa8, 0xa4, 0xe6, 0x50, 0x8b, 0xa0, 0x5a, 0x8e, 0xbf, 0xbb, 0x6f, 0x10, 0xff, 0x48,
+ 0x73, 0x65, 0x9f, 0x37, 0xeb, 0x94, 0x43, 0x99, 0xb5, 0xd2, 0xcc, 0x4b, 0xaf, 0xc3, 0xc3, 0x6e,
+ 0x6e, 0xb3, 0x1c, 0x02, 0xb6, 0xee, 0x3b, 0xf0, 0xf6, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4c,
+ 0x2f, 0x33, 0x61, 0x3d, 0x03, 0x00, 0x00,
}
diff --git a/vendor/github.com/opencord/voltha-protos/v3/go/voltha/device.pb.go b/vendor/github.com/opencord/voltha-protos/v3/go/voltha/device.pb.go
index 5d0d344..764edcf 100644
--- a/vendor/github.com/opencord/voltha-protos/v3/go/voltha/device.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v3/go/voltha/device.pb.go
@@ -720,6 +720,7 @@
return nil
}
+//TODO: ImageDownload is not actively used (05/19/2020). When this is tackled, can remove extra/unnecessary fields.
type ImageDownload struct {
// Device Identifier
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
@@ -1180,10 +1181,7 @@
Reason string `protobuf:"bytes,22,opt,name=reason,proto3" json:"reason,omitempty"`
ConnectStatus common.ConnectStatus_Types `protobuf:"varint,18,opt,name=connect_status,json=connectStatus,proto3,enum=common.ConnectStatus_Types" json:"connect_status,omitempty"`
// Device type specific attributes
- Custom *any.Any `protobuf:"bytes,64,opt,name=custom,proto3" json:"custom,omitempty"`
- Ports []*Port `protobuf:"bytes,128,rep,name=ports,proto3" json:"ports,omitempty"`
- Flows *openflow_13.Flows `protobuf:"bytes,129,opt,name=flows,proto3" json:"flows,omitempty"`
- FlowGroups *openflow_13.FlowGroups `protobuf:"bytes,130,opt,name=flow_groups,json=flowGroups,proto3" json:"flow_groups,omitempty"`
+ Custom *any.Any `protobuf:"bytes,64,opt,name=custom,proto3" json:"custom,omitempty"`
// PmConfigs will eventually converted to a child node of the
// device to falicitata callbacks and to simplify manipulation.
PmConfigs *PmConfigs `protobuf:"bytes,131,opt,name=pm_configs,json=pmConfigs,proto3" json:"pm_configs,omitempty"`
@@ -1422,27 +1420,6 @@
return nil
}
-func (m *Device) GetPorts() []*Port {
- if m != nil {
- return m.Ports
- }
- return nil
-}
-
-func (m *Device) GetFlows() *openflow_13.Flows {
- if m != nil {
- return m.Flows
- }
- return nil
-}
-
-func (m *Device) GetFlowGroups() *openflow_13.FlowGroups {
- if m != nil {
- return m.FlowGroups
- }
- return nil
-}
-
func (m *Device) GetPmConfigs() *PmConfigs {
if m != nil {
return m.PmConfigs
@@ -1732,156 +1709,152 @@
func init() { proto.RegisterFile("voltha_protos/device.proto", fileDescriptor_200940f73d155856) }
var fileDescriptor_200940f73d155856 = []byte{
- // 2402 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x58, 0x4d, 0x73, 0xdb, 0xc6,
- 0xf9, 0x37, 0x29, 0x11, 0x24, 0x1e, 0xbe, 0x08, 0x5e, 0xcb, 0x31, 0x6c, 0xfd, 0x35, 0xf6, 0x9f,
- 0x4e, 0xa7, 0x8a, 0x53, 0x4b, 0x6e, 0xdc, 0x49, 0xd2, 0x43, 0x67, 0x4c, 0x91, 0xb0, 0x8d, 0xa9,
- 0x4a, 0xa9, 0x4b, 0x52, 0x69, 0x7b, 0xc1, 0x40, 0xc4, 0x52, 0xc2, 0x18, 0xc0, 0xd2, 0x0b, 0x90,
- 0x92, 0x73, 0x6a, 0x9a, 0x69, 0x4f, 0xbd, 0xf5, 0x4b, 0xf4, 0x1b, 0xe4, 0xd8, 0xce, 0xf4, 0x9c,
- 0xe9, 0x77, 0x68, 0x2f, 0xfd, 0x04, 0x39, 0x77, 0xf6, 0x59, 0x2c, 0x09, 0xc8, 0xae, 0xd3, 0x5e,
- 0x24, 0xee, 0xef, 0x79, 0xd9, 0xdd, 0xdf, 0xee, 0x3e, 0x2f, 0x80, 0x7b, 0x4b, 0x1e, 0x65, 0x17,
- 0xbe, 0x37, 0x17, 0x3c, 0xe3, 0xe9, 0x41, 0xc0, 0x96, 0xe1, 0x94, 0xed, 0xe3, 0x88, 0x18, 0x4a,
- 0x76, 0xef, 0xee, 0x39, 0xe7, 0xe7, 0x11, 0x3b, 0x40, 0xf4, 0x6c, 0x31, 0x3b, 0xf0, 0x93, 0x37,
- 0x4a, 0xe5, 0xde, 0x35, 0xf3, 0x29, 0x8f, 0x63, 0x9e, 0xe4, 0x32, 0xbb, 0x2c, 0x8b, 0x59, 0xe6,
- 0xe7, 0x92, 0xfb, 0x65, 0x09, 0x9f, 0xb3, 0x64, 0x16, 0xf1, 0x4b, 0xef, 0xc7, 0x4f, 0x95, 0x42,
- 0xf7, 0x2f, 0x55, 0x80, 0x01, 0x2e, 0x65, 0xfc, 0x66, 0xce, 0x48, 0x07, 0xaa, 0x61, 0x60, 0x57,
- 0x1e, 0x54, 0xf6, 0x4c, 0x5a, 0x0d, 0x03, 0xb2, 0x03, 0xe6, 0x92, 0x25, 0x01, 0x17, 0x5e, 0x18,
- 0xd8, 0x35, 0x84, 0x1b, 0x0a, 0x70, 0x03, 0xb2, 0x0b, 0xb0, 0x12, 0xa6, 0xb6, 0xf1, 0x60, 0x63,
- 0xcf, 0xa4, 0xa6, 0x96, 0xa6, 0xc4, 0x86, 0xba, 0x1f, 0xf8, 0xf3, 0x8c, 0x09, 0xbb, 0x8a, 0x96,
- 0x7a, 0x48, 0x3e, 0x03, 0xdb, 0x9f, 0x4e, 0xd9, 0x3c, 0x4b, 0xbd, 0xb3, 0x45, 0xf4, 0xca, 0xc3,
- 0x25, 0x2d, 0xe6, 0x81, 0x9f, 0x31, 0x7b, 0xe3, 0x41, 0x65, 0xaf, 0x41, 0x6f, 0xe7, 0xf2, 0xc3,
- 0x45, 0xf4, 0xea, 0x79, 0xc4, 0x2f, 0x27, 0x28, 0x24, 0x03, 0xb8, 0xaf, 0x0d, 0xfd, 0x20, 0xf0,
- 0x04, 0x8b, 0xf9, 0x92, 0x15, 0xcd, 0x53, 0x7b, 0x13, 0xed, 0x77, 0x72, 0xb5, 0x5e, 0x10, 0x50,
- 0x54, 0x5a, 0x3b, 0x49, 0xc9, 0x11, 0x3c, 0xd4, 0x5e, 0x82, 0x50, 0xb0, 0x69, 0xe6, 0x45, 0xfc,
- 0x3c, 0x9c, 0xfa, 0x11, 0x7a, 0x4a, 0xf5, 0x4a, 0xea, 0xe8, 0x49, 0x4f, 0x38, 0x40, 0xcd, 0x23,
- 0xa5, 0x28, 0xbd, 0xa5, 0xca, 0x5d, 0xf7, 0x33, 0x68, 0xae, 0x09, 0x4c, 0xc9, 0x1e, 0xd4, 0xc2,
- 0x8c, 0xc5, 0xa9, 0x5d, 0x79, 0xb0, 0xb1, 0xd7, 0xfc, 0x84, 0xec, 0xab, 0x13, 0xd8, 0x5f, 0xeb,
- 0x50, 0xa5, 0xd0, 0xfd, 0x6b, 0x05, 0x1a, 0x27, 0x71, 0x9f, 0x27, 0xb3, 0xf0, 0x9c, 0x10, 0xd8,
- 0x4c, 0xfc, 0x98, 0xe5, 0xd4, 0xe3, 0x6f, 0xf2, 0x31, 0x6c, 0x66, 0x6f, 0xe6, 0x0c, 0xd9, 0xeb,
- 0x7c, 0x72, 0x47, 0x7b, 0xd2, 0x36, 0xfb, 0x27, 0x31, 0xba, 0x43, 0x25, 0xc9, 0x36, 0x4b, 0xfc,
- 0xb3, 0x88, 0x05, 0x39, 0x85, 0x7a, 0x48, 0xee, 0x43, 0x33, 0xf5, 0xe3, 0x79, 0xc4, 0xbc, 0x99,
- 0x60, 0xaf, 0x91, 0xa0, 0x36, 0x05, 0x05, 0x3d, 0x17, 0xec, 0x75, 0xf7, 0x73, 0x30, 0x94, 0x2b,
- 0xd2, 0x84, 0x7a, 0xff, 0x78, 0x32, 0x1c, 0x3b, 0xd4, 0xba, 0x41, 0x4c, 0xa8, 0xbd, 0xe8, 0x4d,
- 0x5e, 0x38, 0x56, 0x45, 0xfe, 0x1c, 0x8d, 0x7b, 0x63, 0xc7, 0xaa, 0x2a, 0x95, 0xe1, 0xd8, 0xf9,
- 0xd5, 0xd8, 0xda, 0xe8, 0xfe, 0xa9, 0x02, 0xed, 0x93, 0xf8, 0x85, 0xe0, 0x8b, 0x79, 0xbe, 0x8f,
- 0x5d, 0x80, 0x73, 0x39, 0xf4, 0x0a, 0xbb, 0x31, 0x11, 0x19, 0xca, 0x2d, 0xad, 0xc4, 0xb8, 0x94,
- 0x2a, 0x2e, 0x45, 0x89, 0xe5, 0x4a, 0xde, 0xb3, 0x89, 0x47, 0x50, 0x8f, 0x59, 0x26, 0xc2, 0xa9,
- 0x3c, 0x61, 0x49, 0xac, 0x75, 0x9d, 0x0e, 0xaa, 0x15, 0xba, 0x5f, 0x55, 0xc1, 0xd4, 0x68, 0xfa,
- 0xd6, 0x95, 0xfe, 0x7f, 0x68, 0x05, 0x6c, 0xe6, 0x2f, 0xa2, 0xac, 0xb8, 0x88, 0x66, 0x8e, 0xe1,
- 0x32, 0xee, 0x43, 0x1d, 0xd7, 0xa4, 0x97, 0x71, 0x58, 0xfb, 0xd7, 0x77, 0xdf, 0xee, 0x56, 0xa8,
- 0x46, 0xc9, 0x23, 0x68, 0x4b, 0x5b, 0x8f, 0x2f, 0x99, 0x10, 0x61, 0xc0, 0xd4, 0xad, 0xd3, 0x6a,
- 0x2d, 0x29, 0x3b, 0xce, 0x45, 0xe4, 0x31, 0x18, 0x68, 0x96, 0xda, 0x35, 0x5c, 0xf8, 0xed, 0xf5,
- 0xc2, 0x0b, 0xc4, 0xd1, 0x5c, 0xa9, 0xb8, 0x51, 0xe3, 0x7b, 0x36, 0x4a, 0xee, 0x42, 0x23, 0xf6,
- 0xaf, 0xbc, 0xf4, 0x15, 0xbb, 0xc4, 0xdb, 0xda, 0xa6, 0xf5, 0xd8, 0xbf, 0x1a, 0xbd, 0x62, 0x97,
- 0xdd, 0xbf, 0x57, 0xa0, 0xe6, 0xc6, 0xfe, 0x39, 0x7b, 0xe7, 0xcd, 0xb2, 0xa1, 0xbe, 0x64, 0x22,
- 0x0d, 0x79, 0xa2, 0x9f, 0x66, 0x3e, 0x94, 0xda, 0x17, 0x7e, 0x7a, 0x81, 0xfb, 0x36, 0x29, 0xfe,
- 0x26, 0x1f, 0x81, 0x15, 0x26, 0x69, 0xe6, 0x47, 0x91, 0x27, 0x6f, 0x7c, 0x16, 0xc6, 0x6a, 0xc3,
- 0x26, 0xdd, 0xca, 0xf1, 0x41, 0x0e, 0xcb, 0x78, 0x11, 0xa6, 0x9e, 0x3f, 0xcd, 0xc2, 0x25, 0xc3,
- 0x78, 0xd1, 0xa0, 0x8d, 0x30, 0xed, 0xe1, 0x58, 0x32, 0x1f, 0xa6, 0x9e, 0x8c, 0x5c, 0x61, 0x96,
- 0xb1, 0xc0, 0x36, 0x50, 0xde, 0x0c, 0xd3, 0xbe, 0x86, 0xe4, 0x8e, 0xc2, 0xd4, 0x5b, 0xfa, 0x51,
- 0x18, 0xe4, 0xef, 0xaf, 0x1e, 0xa6, 0xa7, 0x72, 0xd8, 0x7d, 0x0c, 0x06, 0x6e, 0x28, 0x25, 0x0f,
- 0xa1, 0x16, 0xca, 0x5f, 0xf9, 0x13, 0x6b, 0x6b, 0x82, 0x50, 0x4c, 0x95, 0xac, 0xfb, 0xcf, 0x3a,
- 0xb4, 0x11, 0x18, 0xf0, 0xcb, 0x24, 0xe2, 0x7e, 0xf0, 0xd6, 0x45, 0xd0, 0xc4, 0x54, 0x0b, 0xc4,
- 0x58, 0xb0, 0xb1, 0x10, 0x51, 0xbe, 0x7b, 0xf9, 0x53, 0x22, 0x53, 0x31, 0xcd, 0x5f, 0x8d, 0xfc,
- 0x49, 0x8e, 0xa1, 0x13, 0xe4, 0x3e, 0xbd, 0x34, 0x93, 0x91, 0xa2, 0x86, 0x0f, 0x74, 0xaf, 0xb4,
- 0x0e, 0x3d, 0x6d, 0x79, 0x34, 0x92, 0xfa, 0xb4, 0x1d, 0x14, 0x87, 0xe4, 0x21, 0xb4, 0x71, 0xcd,
- 0x9e, 0x3e, 0x13, 0x03, 0xa7, 0x6f, 0x21, 0x78, 0x9a, 0x1f, 0xcc, 0x47, 0x60, 0x69, 0x2b, 0x16,
- 0x78, 0x67, 0x6f, 0x64, 0xac, 0x53, 0x67, 0xbe, 0xb5, 0xc6, 0x0f, 0x25, 0x4c, 0x5e, 0x82, 0x21,
- 0x98, 0x9f, 0xf2, 0xc4, 0x6e, 0xe0, 0xc2, 0x9e, 0xfc, 0x17, 0x0b, 0x7b, 0xee, 0x87, 0xd1, 0x42,
- 0x30, 0x8a, 0x76, 0x34, 0xb7, 0x27, 0x3f, 0x84, 0x2d, 0x3f, 0x08, 0xc2, 0x2c, 0xe4, 0x89, 0x1f,
- 0x79, 0x61, 0x32, 0xe3, 0xb6, 0x89, 0x6b, 0xeb, 0xac, 0x61, 0x37, 0x99, 0x71, 0x15, 0x63, 0x96,
- 0xcc, 0x9b, 0xe2, 0x0d, 0xb5, 0x01, 0x8f, 0x0e, 0x24, 0x94, 0xc7, 0x85, 0x1d, 0x30, 0x23, 0x2e,
- 0x43, 0x6c, 0x10, 0x0a, 0xbb, 0xa9, 0x12, 0x09, 0x02, 0x83, 0x50, 0x10, 0x17, 0x9a, 0x8a, 0x00,
- 0x45, 0x67, 0xeb, 0x7b, 0xe9, 0xc4, 0x0b, 0xe5, 0x67, 0x4c, 0xd1, 0x09, 0x68, 0xac, 0xb8, 0xdc,
- 0x01, 0x73, 0x16, 0x46, 0xcc, 0x4b, 0xc3, 0x2f, 0x99, 0xdd, 0x46, 0x7e, 0x1a, 0x12, 0x18, 0x85,
- 0x5f, 0xb2, 0xee, 0x37, 0x15, 0x20, 0x6f, 0x1f, 0x07, 0xd9, 0x06, 0x6b, 0x70, 0xfc, 0xc5, 0xf0,
- 0xe8, 0xb8, 0x37, 0xf0, 0x26, 0xc3, 0x9f, 0x0f, 0x8f, 0xbf, 0x18, 0x5a, 0x37, 0xc8, 0x07, 0x40,
- 0x56, 0xe8, 0x68, 0xd2, 0xef, 0x3b, 0xce, 0xc0, 0x19, 0x58, 0x95, 0x12, 0x4e, 0x9d, 0x5f, 0x4e,
- 0x9c, 0xd1, 0xd8, 0x19, 0x58, 0xd5, 0x92, 0x97, 0xd1, 0xb8, 0x47, 0x25, 0xba, 0x41, 0x6e, 0xc1,
- 0xd6, 0x0a, 0x7d, 0xde, 0x73, 0x8f, 0x9c, 0x81, 0xb5, 0x49, 0x6c, 0xd8, 0x2e, 0x4c, 0x38, 0x9a,
- 0x9c, 0x9c, 0x1c, 0xa3, 0x7a, 0xad, 0xe4, 0xbc, 0xdf, 0x1b, 0xf6, 0x9d, 0x23, 0x69, 0x61, 0x74,
- 0xff, 0x50, 0x81, 0x7b, 0xff, 0xf9, 0xbc, 0x48, 0x0b, 0x1a, 0xc3, 0x63, 0xcf, 0xa1, 0xf4, 0x58,
- 0x06, 0xee, 0x2d, 0x68, 0xba, 0xc3, 0xd3, 0xde, 0x91, 0x3b, 0xf0, 0x26, 0xf4, 0xc8, 0xaa, 0x48,
- 0x60, 0xe0, 0x9c, 0xba, 0x7d, 0xc7, 0x3b, 0x9c, 0x8c, 0x7e, 0x6d, 0x55, 0xe5, 0x34, 0xee, 0x70,
- 0x34, 0x79, 0xfe, 0xdc, 0xed, 0xbb, 0xce, 0x70, 0xec, 0x8d, 0x4e, 0x7a, 0x7d, 0xc7, 0xda, 0x20,
- 0x37, 0xa1, 0x9d, 0x13, 0x90, 0x3b, 0xdb, 0x24, 0x6d, 0x30, 0xd7, 0x0b, 0xa9, 0x75, 0xff, 0xa8,
- 0x29, 0x2c, 0x1d, 0x81, 0x34, 0x74, 0x7f, 0xd1, 0x7b, 0xe1, 0x14, 0xf8, 0x23, 0xd0, 0x51, 0x90,
- 0x3b, 0xec, 0xf5, 0xc7, 0xee, 0xa9, 0xcc, 0x23, 0xdb, 0x60, 0x29, 0x0c, 0x91, 0xde, 0xd8, 0x1d,
- 0xbe, 0xb0, 0xaa, 0xc4, 0x82, 0x56, 0x01, 0x75, 0x14, 0x6b, 0x0a, 0xa1, 0xce, 0xa9, 0x43, 0x51,
- 0x6d, 0x73, 0xed, 0x50, 0x81, 0xb8, 0x9c, 0x9f, 0x41, 0xa7, 0x44, 0x4b, 0x4a, 0x3e, 0xd6, 0xf9,
- 0xb7, 0x5a, 0x8e, 0xb6, 0x25, 0x35, 0x9d, 0x82, 0xbf, 0xa9, 0xc1, 0xe6, 0x09, 0x17, 0x19, 0xb9,
- 0x03, 0xf5, 0x39, 0x17, 0x99, 0x97, 0x70, 0x0c, 0x10, 0x6d, 0x6a, 0xc8, 0xe1, 0x90, 0x93, 0x6d,
- 0xa8, 0x45, 0xfe, 0x19, 0x8b, 0xf2, 0x28, 0xa1, 0x06, 0xe4, 0xa3, 0x3c, 0x33, 0x6f, 0xe0, 0x4d,
- 0x5d, 0x47, 0x74, 0x2e, 0x32, 0xfc, 0x53, 0xc8, 0xcb, 0x3f, 0x85, 0xa6, 0x1f, 0xc4, 0x61, 0x52,
- 0x0a, 0x15, 0xf6, 0x7e, 0x5e, 0xbf, 0xf5, 0xa4, 0x08, 0x29, 0xdc, 0xc7, 0xf2, 0x81, 0x82, 0xbf,
- 0x42, 0xa4, 0x29, 0x9f, 0x33, 0x81, 0x96, 0x8b, 0x14, 0xa3, 0x42, 0xc1, 0xf4, 0x78, 0xce, 0xc4,
- 0x08, 0x25, 0xda, 0x94, 0xaf, 0x10, 0xf9, 0x0c, 0x54, 0x81, 0xe9, 0xe5, 0x81, 0xd4, 0xa4, 0x0d,
- 0x05, 0xb8, 0x81, 0xa4, 0x68, 0xce, 0x98, 0x48, 0xed, 0xc6, 0xb5, 0x84, 0x84, 0xcb, 0x67, 0x4c,
- 0xc8, 0x1f, 0x54, 0xe9, 0xc8, 0x8c, 0x2d, 0xae, 0xbc, 0xb9, 0x3f, 0x7d, 0xc5, 0xb2, 0x14, 0x5f,
- 0xbf, 0x41, 0x4d, 0x71, 0x75, 0xa2, 0x00, 0x19, 0xb0, 0xc5, 0x55, 0x1e, 0x8e, 0x00, 0x85, 0x75,
- 0x71, 0xa5, 0xc2, 0xd0, 0x0e, 0x98, 0xe2, 0xca, 0x63, 0x42, 0x70, 0x91, 0xe2, 0x93, 0x37, 0x68,
- 0x43, 0x5c, 0x39, 0x38, 0x96, 0x6e, 0xb3, 0xb5, 0xdb, 0x96, 0x72, 0x9b, 0x15, 0xdd, 0x66, 0xda,
- 0x6d, 0x5b, 0xb9, 0xcd, 0xd6, 0x6e, 0xb3, 0x95, 0xdb, 0x8e, 0x72, 0x9b, 0x69, 0xb7, 0x4f, 0xa0,
- 0xc1, 0x67, 0x73, 0x4f, 0x1e, 0x9e, 0xbd, 0xf5, 0xa0, 0x82, 0xbb, 0x2b, 0x16, 0xbd, 0x5a, 0x48,
- 0xeb, 0x7c, 0x36, 0x97, 0xdb, 0xbc, 0xf7, 0x0c, 0x1a, 0x7a, 0xcb, 0x65, 0xd6, 0x2a, 0xd7, 0x58,
- 0x2b, 0x5c, 0x91, 0x6a, 0xf1, 0x8a, 0x74, 0x53, 0x68, 0xe8, 0x33, 0x97, 0xd5, 0xd1, 0xfa, 0x05,
- 0x58, 0xd0, 0x72, 0xc6, 0x2f, 0x1d, 0x3a, 0x74, 0xc6, 0xde, 0x70, 0xe8, 0x5a, 0x95, 0x12, 0x32,
- 0x19, 0xba, 0xaa, 0x9c, 0x3a, 0x39, 0x1e, 0x7a, 0xc7, 0x47, 0x63, 0x6b, 0x63, 0x35, 0x18, 0x4e,
- 0xd4, 0xc3, 0x3b, 0x75, 0xa4, 0xa2, 0x94, 0xd5, 0x0a, 0xc3, 0xe1, 0xc4, 0x32, 0xba, 0x1f, 0x43,
- 0x4d, 0x4e, 0x9a, 0x92, 0x6e, 0xb9, 0xde, 0x6c, 0x15, 0x0f, 0x53, 0x5f, 0xf3, 0xbf, 0xb5, 0xc0,
- 0x50, 0xf5, 0x27, 0xb9, 0xbd, 0x4e, 0x82, 0xba, 0x5c, 0x91, 0xb9, 0xf0, 0x6e, 0xa1, 0xd4, 0x5c,
- 0x09, 0xd4, 0x05, 0xbe, 0x0b, 0x9b, 0x82, 0xf3, 0xac, 0x5c, 0x09, 0x21, 0x44, 0xba, 0x60, 0xce,
- 0x7d, 0xc1, 0x92, 0x4c, 0xf2, 0xb5, 0x59, 0x34, 0x6d, 0x28, 0x1c, 0x2f, 0x5b, 0x27, 0xd7, 0xd1,
- 0xec, 0x6d, 0x4b, 0xf6, 0x56, 0xb5, 0x92, 0x12, 0x9e, 0xa8, 0xd7, 0xb6, 0x0b, 0x86, 0xea, 0x1f,
- 0x54, 0xaf, 0xa1, 0x95, 0x72, 0x90, 0xec, 0x40, 0x2d, 0xe6, 0x01, 0x8b, 0x54, 0x82, 0xd4, 0x52,
- 0x85, 0x91, 0x27, 0x60, 0x5d, 0xf8, 0x22, 0xb8, 0xf4, 0xc5, 0x3a, 0x91, 0xd6, 0x8b, 0x7a, 0x5b,
- 0x5a, 0xac, 0x53, 0xea, 0x13, 0xb0, 0x66, 0xa1, 0x88, 0x4b, 0x16, 0x8d, 0x92, 0x85, 0x16, 0x6b,
- 0x8b, 0xc7, 0x60, 0x60, 0xae, 0x51, 0x0f, 0xa1, 0xf9, 0x49, 0xa7, 0x14, 0x5d, 0xd2, 0xd5, 0x7a,
- 0x95, 0x92, 0x2c, 0x13, 0x53, 0x26, 0x42, 0x3f, 0xf2, 0x92, 0x45, 0x7c, 0xc6, 0x04, 0xbe, 0x90,
- 0x95, 0xf7, 0x96, 0x92, 0x0d, 0x51, 0x24, 0xb9, 0x5c, 0x77, 0x5a, 0x76, 0x89, 0xcb, 0x55, 0xc3,
- 0x75, 0x7f, 0xdd, 0x51, 0x35, 0x8b, 0x1a, 0xab, 0xc6, 0x8a, 0xc0, 0xe6, 0x32, 0xf2, 0x13, 0x7c,
- 0x4f, 0x6d, 0x8a, 0xbf, 0x65, 0x6a, 0x8e, 0xfd, 0xa9, 0xec, 0x97, 0x04, 0x4b, 0xd5, 0x6b, 0x32,
- 0x29, 0xc4, 0xfe, 0xb4, 0xa7, 0x10, 0xf2, 0x10, 0x5a, 0xe1, 0x7c, 0xf9, 0x93, 0x95, 0x86, 0x7c,
- 0x53, 0xe6, 0xcb, 0x1b, 0xb4, 0x29, 0xd1, 0xb2, 0xd2, 0xa7, 0x2b, 0xa5, 0xad, 0x82, 0xd2, 0xa7,
- 0x5a, 0xe9, 0x43, 0x68, 0x5f, 0xf0, 0x34, 0xf3, 0xfc, 0x24, 0x50, 0x4f, 0xf0, 0xb6, 0xd6, 0x92,
- 0x70, 0x2f, 0x09, 0xf0, 0x95, 0xed, 0x02, 0xb0, 0xab, 0x4c, 0xf8, 0x9e, 0x2f, 0xce, 0x53, 0xfb,
- 0x8e, 0x6a, 0x11, 0x10, 0xe9, 0x89, 0xf3, 0x94, 0x3c, 0x83, 0xf6, 0x5c, 0xf0, 0xab, 0x37, 0xab,
- 0xa9, 0x6e, 0x21, 0xd5, 0x3b, 0xe5, 0x46, 0x6a, 0xff, 0x44, 0xea, 0xe4, 0x13, 0xd3, 0xd6, 0xbc,
- 0x30, 0xba, 0x1e, 0x72, 0xad, 0xff, 0x21, 0xe4, 0x3e, 0x2b, 0x87, 0xdc, 0x9b, 0xef, 0x0f, 0xb9,
- 0x9a, 0xff, 0x62, 0xe4, 0xdd, 0x5d, 0x15, 0x5f, 0x1f, 0x94, 0xae, 0x70, 0x5e, 0x51, 0xb9, 0xd0,
- 0x99, 0xf2, 0x24, 0x91, 0x4d, 0x67, 0x3e, 0x07, 0xc1, 0x39, 0x76, 0xf4, 0x1c, 0x7d, 0x25, 0x7d,
- 0xd7, 0x34, 0xed, 0x69, 0x51, 0x46, 0x7e, 0x04, 0xc6, 0x74, 0x91, 0x66, 0x3c, 0xb6, 0x9f, 0x21,
- 0x43, 0xdb, 0xfb, 0xea, 0xeb, 0xc1, 0xbe, 0xfe, 0x7a, 0xb0, 0xdf, 0x4b, 0xde, 0xd0, 0x5c, 0x87,
- 0x3c, 0x85, 0x9a, 0x3c, 0x92, 0xd4, 0xfe, 0xed, 0x3b, 0x02, 0xc5, 0x61, 0xe7, 0x1f, 0xdf, 0x7d,
- 0xbb, 0x6b, 0xae, 0x22, 0x1c, 0x55, 0xba, 0xe4, 0x09, 0xd4, 0xb0, 0x25, 0xb6, 0xbf, 0xaa, 0xe0,
- 0x14, 0xa4, 0x14, 0x4c, 0xb1, 0x0b, 0x3e, 0xac, 0x49, 0xd3, 0x1b, 0x54, 0x29, 0x4a, 0x02, 0x51,
- 0x9c, 0xb7, 0x3c, 0xbf, 0x53, 0x76, 0x77, 0xde, 0xb2, 0xc3, 0xd6, 0x67, 0x65, 0x0c, 0xb3, 0x15,
- 0x44, 0x3e, 0x07, 0x98, 0xc7, 0x79, 0x21, 0x99, 0xda, 0x5f, 0x2b, 0x07, 0x37, 0xaf, 0x37, 0x41,
- 0x2b, 0x53, 0x73, 0xbe, 0xea, 0xf4, 0x8e, 0x60, 0x4b, 0x95, 0x91, 0xba, 0x20, 0x4e, 0xed, 0xdf,
- 0x57, 0xde, 0x53, 0x05, 0x1c, 0x36, 0xa5, 0x0b, 0x43, 0xb5, 0x01, 0xb4, 0x13, 0x96, 0x0a, 0x89,
- 0x7b, 0x5f, 0x57, 0xa1, 0x55, 0xbc, 0x64, 0xef, 0xcf, 0x0e, 0xf7, 0xa1, 0x99, 0x0b, 0xd7, 0x71,
- 0x94, 0x42, 0xb0, 0xfe, 0xb2, 0xb2, 0x0b, 0x30, 0xbd, 0xf0, 0x93, 0x84, 0x45, 0xd2, 0x7c, 0x43,
- 0x75, 0xbe, 0x39, 0xe2, 0x06, 0x64, 0x0f, 0x2c, 0x2d, 0x56, 0x0d, 0x72, 0x1e, 0x51, 0xdb, 0xb4,
- 0x93, 0xe3, 0x48, 0x8f, 0x1b, 0x90, 0x03, 0xb8, 0xa5, 0x35, 0x33, 0x26, 0xe2, 0x30, 0xf1, 0x65,
- 0x1d, 0x9e, 0x7f, 0x9c, 0x21, 0xb9, 0x68, 0xbc, 0x96, 0x90, 0xdb, 0x60, 0xf0, 0x64, 0x21, 0x1d,
- 0x1a, 0xe8, 0xb0, 0xc6, 0x93, 0x85, 0x1b, 0x90, 0x0f, 0xa1, 0x23, 0xe1, 0x94, 0xa5, 0x32, 0xb4,
- 0xe9, 0x3a, 0xa1, 0x4d, 0x5b, 0x3c, 0x59, 0x8c, 0x14, 0xe8, 0x06, 0x87, 0xa6, 0x0c, 0x39, 0xb8,
- 0xff, 0xee, 0x01, 0xd4, 0xd5, 0xdb, 0x93, 0x0f, 0xbd, 0x94, 0x74, 0x3a, 0xe5, 0xb7, 0xa9, 0xd3,
- 0xce, 0x9f, 0x37, 0x60, 0x7b, 0x14, 0xc6, 0x8b, 0xc8, 0xcf, 0x58, 0x2f, 0xf2, 0x45, 0x4c, 0xd9,
- 0xeb, 0x05, 0x4b, 0xb3, 0xb7, 0x3a, 0xb1, 0xff, 0x03, 0x33, 0x4c, 0x82, 0x70, 0xea, 0x67, 0x5c,
- 0x7f, 0x2b, 0x5a, 0x03, 0x32, 0xf1, 0x86, 0x49, 0x36, 0xd3, 0xb4, 0x99, 0xd4, 0x90, 0x43, 0xb5,
- 0x03, 0xbc, 0xaf, 0x92, 0x71, 0xf5, 0xbd, 0x41, 0x75, 0xa5, 0xad, 0x79, 0x9e, 0x8e, 0xf1, 0x93,
- 0x43, 0x17, 0xda, 0x72, 0x9f, 0xeb, 0xa3, 0x53, 0x4c, 0x35, 0x79, 0xb2, 0x18, 0xe8, 0xd3, 0x7b,
- 0x0a, 0x1f, 0x84, 0x89, 0x4c, 0x01, 0xcc, 0x3b, 0x0b, 0x33, 0x55, 0x5c, 0x78, 0x42, 0x06, 0x0f,
- 0x49, 0x59, 0x8d, 0xde, 0xca, 0xa5, 0x87, 0x61, 0x86, 0x85, 0x06, 0x55, 0x6d, 0x43, 0x2d, 0x10,
- 0xe1, 0x2c, 0x43, 0xde, 0x6a, 0x54, 0x0d, 0xe4, 0x6a, 0x13, 0x76, 0xe9, 0xb1, 0xd7, 0x01, 0xe6,
- 0x92, 0x1a, 0x35, 0x12, 0x76, 0xe9, 0xbc, 0x0e, 0xc8, 0x23, 0xb8, 0xa9, 0xf8, 0x2e, 0x26, 0x04,
- 0xd5, 0x4d, 0x6d, 0x21, 0xe5, 0x85, 0x64, 0xf0, 0x12, 0x4c, 0x19, 0x52, 0xd4, 0xc9, 0x02, 0x06,
- 0x88, 0x47, 0x9a, 0xe3, 0x77, 0x31, 0x8a, 0x91, 0x09, 0xb5, 0xb1, 0xf2, 0x5c, 0x1b, 0x77, 0x7f,
- 0x00, 0xed, 0x92, 0x8c, 0x98, 0x50, 0xa3, 0x3d, 0x77, 0xe4, 0xa8, 0x0f, 0x3c, 0xfd, 0x23, 0xa7,
- 0x47, 0xad, 0xca, 0xe1, 0x08, 0x6e, 0x71, 0x71, 0x8e, 0xaf, 0x74, 0xca, 0x45, 0x90, 0xcf, 0x75,
- 0xd8, 0x3a, 0xc5, 0xff, 0x8a, 0xa7, 0xdf, 0xec, 0x9f, 0x87, 0xd9, 0xc5, 0xe2, 0x4c, 0x46, 0xaa,
- 0x03, 0xad, 0x79, 0xa0, 0x34, 0x1f, 0xe7, 0x1f, 0x18, 0x97, 0x4f, 0x0f, 0xce, 0x79, 0x8e, 0x9d,
- 0x19, 0x08, 0x3e, 0xfd, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x23, 0x0e, 0xba, 0x2c, 0xfa, 0x14,
- 0x00, 0x00,
+ // 2341 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x58, 0xcd, 0x72, 0x1b, 0xb7,
+ 0x1d, 0x37, 0x29, 0x71, 0xc9, 0xfd, 0xf3, 0x43, 0x6b, 0x58, 0x4e, 0xd6, 0x56, 0x35, 0x76, 0xe9,
+ 0x74, 0xaa, 0x24, 0xb5, 0xe4, 0xc6, 0x9d, 0x24, 0x3d, 0x74, 0xc6, 0x14, 0xb9, 0xb6, 0x77, 0xaa,
+ 0x92, 0x2a, 0x48, 0x2a, 0x6d, 0x2f, 0x3b, 0x2b, 0x2e, 0x28, 0x61, 0xbc, 0xbb, 0xa0, 0x81, 0x25,
+ 0x25, 0xe7, 0xd6, 0xc9, 0xb4, 0xa7, 0xde, 0x7a, 0xeb, 0x13, 0xf4, 0x0d, 0x72, 0x6c, 0x5f, 0x20,
+ 0xd3, 0x77, 0x68, 0x2f, 0x7d, 0x82, 0x9c, 0x3b, 0x00, 0x16, 0xe4, 0xae, 0x9c, 0x3a, 0xed, 0x45,
+ 0x5a, 0xfc, 0xfe, 0x1f, 0x00, 0x7e, 0xc0, 0xff, 0x03, 0x84, 0xfb, 0x2b, 0x16, 0x67, 0x97, 0x61,
+ 0xb0, 0xe0, 0x2c, 0x63, 0xe2, 0x28, 0x22, 0x2b, 0x3a, 0x23, 0x87, 0x6a, 0x84, 0x2c, 0x2d, 0xbb,
+ 0x7f, 0xef, 0x82, 0xb1, 0x8b, 0x98, 0x1c, 0x29, 0xf4, 0x7c, 0x39, 0x3f, 0x0a, 0xd3, 0x37, 0x5a,
+ 0xe5, 0xfe, 0x0d, 0xf3, 0x19, 0x4b, 0x12, 0x96, 0xe6, 0x32, 0xb7, 0x2c, 0x4b, 0x48, 0x16, 0xe6,
+ 0x92, 0x07, 0x65, 0x09, 0x5b, 0x90, 0x74, 0x1e, 0xb3, 0xab, 0xe0, 0xa7, 0x4f, 0xb5, 0x42, 0xf7,
+ 0x6f, 0x55, 0x80, 0x81, 0x5a, 0xca, 0xe4, 0xcd, 0x82, 0xa0, 0x0e, 0x54, 0x69, 0xe4, 0x56, 0x1e,
+ 0x56, 0x0e, 0x6c, 0x5c, 0xa5, 0x11, 0xda, 0x03, 0x7b, 0x45, 0xd2, 0x88, 0xf1, 0x80, 0x46, 0x6e,
+ 0x4d, 0xc1, 0x0d, 0x0d, 0xf8, 0x11, 0xda, 0x07, 0x58, 0x0b, 0x85, 0x6b, 0x3d, 0xdc, 0x3a, 0xb0,
+ 0xb1, 0x6d, 0xa4, 0x02, 0xb9, 0x50, 0x0f, 0xa3, 0x70, 0x91, 0x11, 0xee, 0x56, 0x95, 0xa5, 0x19,
+ 0xa2, 0xcf, 0xc0, 0x0d, 0x67, 0x33, 0xb2, 0xc8, 0x44, 0x70, 0xbe, 0x8c, 0x5f, 0x05, 0x6a, 0x49,
+ 0xcb, 0x45, 0x14, 0x66, 0xc4, 0xdd, 0x7a, 0x58, 0x39, 0x68, 0xe0, 0xbb, 0xb9, 0xfc, 0x78, 0x19,
+ 0xbf, 0x7a, 0x1e, 0xb3, 0xab, 0xa9, 0x12, 0xa2, 0x01, 0x3c, 0x30, 0x86, 0x61, 0x14, 0x05, 0x9c,
+ 0x24, 0x6c, 0x45, 0x8a, 0xe6, 0xc2, 0xdd, 0x56, 0xf6, 0x7b, 0xb9, 0x5a, 0x2f, 0x8a, 0xb0, 0x52,
+ 0xda, 0x38, 0x11, 0xe8, 0x04, 0x1e, 0x19, 0x2f, 0x11, 0xe5, 0x64, 0x96, 0x05, 0x31, 0xbb, 0xa0,
+ 0xb3, 0x30, 0x56, 0x9e, 0x84, 0x59, 0x49, 0x5d, 0x79, 0x32, 0x13, 0x0e, 0x94, 0xe6, 0x89, 0x56,
+ 0x94, 0xde, 0x84, 0x76, 0xd7, 0xfd, 0x0c, 0x9a, 0x1b, 0x02, 0x05, 0x3a, 0x80, 0x1a, 0xcd, 0x48,
+ 0x22, 0xdc, 0xca, 0xc3, 0xad, 0x83, 0xe6, 0x27, 0xe8, 0x50, 0x9f, 0xc0, 0xe1, 0x46, 0x07, 0x6b,
+ 0x85, 0xee, 0xdf, 0x2b, 0xd0, 0x38, 0x4d, 0xfa, 0x2c, 0x9d, 0xd3, 0x0b, 0x84, 0x60, 0x3b, 0x0d,
+ 0x13, 0x92, 0x53, 0xaf, 0xbe, 0xd1, 0xc7, 0xb0, 0x9d, 0xbd, 0x59, 0x10, 0xc5, 0x5e, 0xe7, 0x93,
+ 0xf7, 0x8d, 0x27, 0x63, 0x73, 0x78, 0x9a, 0x28, 0x77, 0x4a, 0x49, 0xb2, 0x4d, 0xd2, 0xf0, 0x3c,
+ 0x26, 0x51, 0x4e, 0xa1, 0x19, 0xa2, 0x07, 0xd0, 0x14, 0x61, 0xb2, 0x88, 0x49, 0x30, 0xe7, 0xe4,
+ 0xb5, 0x22, 0xa8, 0x8d, 0x41, 0x43, 0xcf, 0x39, 0x79, 0xdd, 0xfd, 0x1c, 0x2c, 0xed, 0x0a, 0x35,
+ 0xa1, 0xde, 0x1f, 0x4d, 0x87, 0x13, 0x0f, 0x3b, 0xb7, 0x90, 0x0d, 0xb5, 0x17, 0xbd, 0xe9, 0x0b,
+ 0xcf, 0xa9, 0xc8, 0xcf, 0xf1, 0xa4, 0x37, 0xf1, 0x9c, 0xaa, 0x56, 0x19, 0x4e, 0xbc, 0xdf, 0x4c,
+ 0x9c, 0xad, 0xee, 0x9f, 0x2b, 0xd0, 0x3e, 0x4d, 0x5e, 0x70, 0xb6, 0x5c, 0xe4, 0xfb, 0xd8, 0x07,
+ 0xb8, 0x90, 0xc3, 0xa0, 0xb0, 0x1b, 0x5b, 0x21, 0x43, 0xb9, 0xa5, 0xb5, 0x58, 0x2d, 0xa5, 0xaa,
+ 0x96, 0xa2, 0xc5, 0x72, 0x25, 0xef, 0xd8, 0xc4, 0x47, 0x50, 0x4f, 0x48, 0xc6, 0xe9, 0x4c, 0x9e,
+ 0xb0, 0x24, 0xd6, 0xb9, 0x49, 0x07, 0x36, 0x0a, 0xdd, 0xdf, 0x57, 0xc1, 0x36, 0xa8, 0x78, 0xeb,
+ 0x4a, 0xff, 0x10, 0x5a, 0x11, 0x99, 0x87, 0xcb, 0x38, 0x2b, 0x2e, 0xa2, 0x99, 0x63, 0x6a, 0x19,
+ 0x0f, 0xa0, 0xae, 0xd6, 0x64, 0x96, 0x71, 0x5c, 0xfb, 0xf7, 0xb7, 0xdf, 0xec, 0x57, 0xb0, 0x41,
+ 0xd1, 0x47, 0xd0, 0x96, 0xb6, 0x01, 0x5b, 0x11, 0xce, 0x69, 0x44, 0xf4, 0xad, 0x33, 0x6a, 0x2d,
+ 0x29, 0x1b, 0xe5, 0x22, 0xf4, 0x18, 0x2c, 0x65, 0x26, 0xdc, 0x9a, 0x5a, 0xf8, 0xdd, 0xcd, 0xc2,
+ 0x0b, 0xc4, 0xe1, 0x5c, 0xa9, 0xb8, 0x51, 0xeb, 0x7b, 0x36, 0x8a, 0xee, 0x41, 0x23, 0x09, 0xaf,
+ 0x03, 0xf1, 0x8a, 0x5c, 0xa9, 0xdb, 0xda, 0xc6, 0xf5, 0x24, 0xbc, 0x1e, 0xbf, 0x22, 0x57, 0xdd,
+ 0x7f, 0x54, 0xa0, 0xe6, 0x27, 0xe1, 0x05, 0xf9, 0xce, 0x9b, 0xe5, 0x42, 0x7d, 0x45, 0xb8, 0xa0,
+ 0x2c, 0x35, 0xa1, 0x99, 0x0f, 0xa5, 0xf6, 0x65, 0x28, 0x2e, 0xd5, 0xbe, 0x6d, 0xac, 0xbe, 0xd1,
+ 0x87, 0xe0, 0xd0, 0x54, 0x64, 0x61, 0x1c, 0x07, 0xf2, 0xc6, 0x67, 0x34, 0xd1, 0x1b, 0xb6, 0xf1,
+ 0x4e, 0x8e, 0x0f, 0x72, 0x58, 0xe6, 0x0b, 0x2a, 0x82, 0x70, 0x96, 0xd1, 0x15, 0x51, 0xf9, 0xa2,
+ 0x81, 0x1b, 0x54, 0xf4, 0xd4, 0x58, 0x32, 0x4f, 0x45, 0x20, 0x33, 0x17, 0xcd, 0x32, 0x12, 0xb9,
+ 0x96, 0x92, 0x37, 0xa9, 0xe8, 0x1b, 0x48, 0xee, 0x88, 0x8a, 0x60, 0x15, 0xc6, 0x34, 0xca, 0xe3,
+ 0xaf, 0x4e, 0xc5, 0x99, 0x1c, 0x76, 0x1f, 0x83, 0xa5, 0x36, 0x24, 0xd0, 0x23, 0xa8, 0x51, 0xf9,
+ 0x95, 0x87, 0x58, 0xdb, 0x10, 0xa4, 0xc4, 0x58, 0xcb, 0xba, 0xff, 0xaa, 0x43, 0x5b, 0x01, 0x03,
+ 0x76, 0x95, 0xc6, 0x2c, 0x8c, 0xde, 0xba, 0x08, 0x86, 0x98, 0x6a, 0x81, 0x18, 0x07, 0xb6, 0x96,
+ 0x3c, 0xce, 0x77, 0x2f, 0x3f, 0x25, 0x32, 0xe3, 0xb3, 0x3c, 0x6a, 0xe4, 0x27, 0x1a, 0x41, 0x27,
+ 0xca, 0x7d, 0x06, 0x22, 0x93, 0x99, 0xa2, 0xa6, 0x02, 0xf4, 0xa0, 0xb4, 0x0e, 0x33, 0x6d, 0x79,
+ 0x34, 0x96, 0xfa, 0xb8, 0x1d, 0x15, 0x87, 0xe8, 0x11, 0xb4, 0xd5, 0x9a, 0x03, 0x73, 0x26, 0x96,
+ 0x9a, 0xbe, 0xa5, 0xc0, 0xb3, 0xfc, 0x60, 0x3e, 0x04, 0xc7, 0x58, 0x91, 0x28, 0x38, 0x7f, 0x23,
+ 0x73, 0x9d, 0x3e, 0xf3, 0x9d, 0x0d, 0x7e, 0x2c, 0x61, 0xf4, 0x12, 0x2c, 0x4e, 0x42, 0xc1, 0x52,
+ 0xb7, 0xa1, 0x16, 0xf6, 0xe4, 0x7f, 0x58, 0xd8, 0xf3, 0x90, 0xc6, 0x4b, 0x4e, 0xb0, 0xb2, 0xc3,
+ 0xb9, 0x3d, 0xfa, 0x31, 0xec, 0x84, 0x51, 0x44, 0x33, 0xca, 0xd2, 0x30, 0x0e, 0x68, 0x3a, 0x67,
+ 0xae, 0xad, 0xd6, 0xd6, 0xd9, 0xc0, 0x7e, 0x3a, 0x67, 0x3a, 0xc7, 0xac, 0x48, 0x30, 0x53, 0x37,
+ 0xd4, 0x05, 0x75, 0x74, 0x20, 0xa1, 0x3c, 0x2f, 0xec, 0x81, 0x1d, 0x33, 0x99, 0x62, 0x23, 0xca,
+ 0xdd, 0xa6, 0x2e, 0x24, 0x0a, 0x18, 0x50, 0x8e, 0x7c, 0x68, 0x6a, 0x02, 0x34, 0x9d, 0xad, 0xef,
+ 0xa5, 0x53, 0x5d, 0xa8, 0x30, 0x23, 0x9a, 0x4e, 0x50, 0xc6, 0x9a, 0xcb, 0x3d, 0xb0, 0xe7, 0x34,
+ 0x26, 0x81, 0xa0, 0x5f, 0x12, 0xb7, 0xad, 0xf8, 0x69, 0x48, 0x60, 0x4c, 0xbf, 0x24, 0xdd, 0xaf,
+ 0x2b, 0x80, 0xde, 0x3e, 0x0e, 0xb4, 0x0b, 0xce, 0x60, 0xf4, 0xc5, 0xf0, 0x64, 0xd4, 0x1b, 0x04,
+ 0xd3, 0xe1, 0x2f, 0x87, 0xa3, 0x2f, 0x86, 0xce, 0x2d, 0xf4, 0x1e, 0xa0, 0x35, 0x3a, 0x9e, 0xf6,
+ 0xfb, 0x9e, 0x37, 0xf0, 0x06, 0x4e, 0xa5, 0x84, 0x63, 0xef, 0xd7, 0x53, 0x6f, 0x3c, 0xf1, 0x06,
+ 0x4e, 0xb5, 0xe4, 0x65, 0x3c, 0xe9, 0x61, 0x89, 0x6e, 0xa1, 0x3b, 0xb0, 0xb3, 0x46, 0x9f, 0xf7,
+ 0xfc, 0x13, 0x6f, 0xe0, 0x6c, 0x23, 0x17, 0x76, 0x0b, 0x13, 0x8e, 0xa7, 0xa7, 0xa7, 0x23, 0xa5,
+ 0x5e, 0x2b, 0x39, 0xef, 0xf7, 0x86, 0x7d, 0xef, 0x44, 0x5a, 0x58, 0xdd, 0x3f, 0x56, 0xe0, 0xfe,
+ 0x7f, 0x3f, 0x2f, 0xd4, 0x82, 0xc6, 0x70, 0x14, 0x78, 0x18, 0x8f, 0x64, 0xe2, 0xde, 0x81, 0xa6,
+ 0x3f, 0x3c, 0xeb, 0x9d, 0xf8, 0x83, 0x60, 0x8a, 0x4f, 0x9c, 0x8a, 0x04, 0x06, 0xde, 0x99, 0xdf,
+ 0xf7, 0x82, 0xe3, 0xe9, 0xf8, 0xb7, 0x4e, 0x55, 0x4e, 0xe3, 0x0f, 0xc7, 0xd3, 0xe7, 0xcf, 0xfd,
+ 0xbe, 0xef, 0x0d, 0x27, 0xc1, 0xf8, 0xb4, 0xd7, 0xf7, 0x9c, 0x2d, 0x74, 0x1b, 0xda, 0x39, 0x01,
+ 0xb9, 0xb3, 0x6d, 0xd4, 0x06, 0x7b, 0xb3, 0x90, 0x5a, 0xf7, 0x4f, 0x86, 0xc2, 0xd2, 0x11, 0x48,
+ 0x43, 0xff, 0x57, 0xbd, 0x17, 0x5e, 0x81, 0x3f, 0x04, 0x1d, 0x0d, 0xf9, 0xc3, 0x5e, 0x7f, 0xe2,
+ 0x9f, 0xc9, 0x3a, 0xb2, 0x0b, 0x8e, 0xc6, 0x14, 0xd2, 0x9b, 0xf8, 0xc3, 0x17, 0x4e, 0x15, 0x39,
+ 0xd0, 0x2a, 0xa0, 0x9e, 0x66, 0x4d, 0x23, 0xd8, 0x3b, 0xf3, 0xb0, 0x52, 0xdb, 0xde, 0x38, 0xd4,
+ 0xa0, 0x5a, 0xce, 0x2f, 0xa0, 0x53, 0xa2, 0x45, 0xa0, 0x8f, 0x4d, 0xfd, 0xad, 0x96, 0xb3, 0x6d,
+ 0x49, 0xcd, 0x94, 0xe0, 0xaf, 0x6b, 0xb0, 0x7d, 0xca, 0x78, 0x86, 0xde, 0x87, 0xfa, 0x82, 0xf1,
+ 0x2c, 0x48, 0x99, 0x4a, 0x10, 0x6d, 0x6c, 0xc9, 0xe1, 0x90, 0xa1, 0x5d, 0xa8, 0xc5, 0xe1, 0x39,
+ 0x89, 0xf3, 0x2c, 0xa1, 0x07, 0xe8, 0xc3, 0xbc, 0x32, 0x6f, 0xa9, 0x9b, 0xba, 0xc9, 0xe8, 0x8c,
+ 0x67, 0xea, 0x4f, 0xa1, 0x2e, 0xff, 0x1c, 0x9a, 0x61, 0x94, 0xd0, 0xb4, 0x94, 0x2a, 0xdc, 0xc3,
+ 0xbc, 0x7f, 0xeb, 0x49, 0x91, 0xa2, 0xf0, 0x50, 0xb5, 0x0f, 0x18, 0xc2, 0x35, 0x22, 0x4d, 0xd9,
+ 0x82, 0x70, 0x65, 0xb9, 0x14, 0x2a, 0x2b, 0x14, 0x4c, 0x47, 0x0b, 0xc2, 0xc7, 0x4a, 0x62, 0x4c,
+ 0xd9, 0x1a, 0x91, 0x61, 0xa0, 0x1b, 0xcc, 0x20, 0x4f, 0xa4, 0x36, 0x6e, 0x68, 0xc0, 0x8f, 0x24,
+ 0x45, 0x0b, 0x42, 0xb8, 0x70, 0x1b, 0x37, 0x0a, 0x92, 0x5a, 0x3e, 0x21, 0x5c, 0x7e, 0x60, 0xad,
+ 0x23, 0x2b, 0x36, 0xbf, 0x0e, 0x16, 0xe1, 0xec, 0x15, 0xc9, 0x84, 0x8a, 0x7e, 0x0b, 0xdb, 0xfc,
+ 0xfa, 0x54, 0x03, 0x32, 0x61, 0xf3, 0xeb, 0x3c, 0x1d, 0x81, 0x12, 0xd6, 0xf9, 0xb5, 0x4e, 0x43,
+ 0x7b, 0x60, 0xf3, 0xeb, 0x80, 0x70, 0xce, 0xb8, 0x50, 0x21, 0x6f, 0xe1, 0x06, 0xbf, 0xf6, 0xd4,
+ 0x58, 0xba, 0xcd, 0x36, 0x6e, 0x5b, 0xda, 0x6d, 0x56, 0x74, 0x9b, 0x19, 0xb7, 0x6d, 0xed, 0x36,
+ 0xdb, 0xb8, 0xcd, 0xd6, 0x6e, 0x3b, 0xda, 0x6d, 0x66, 0xdc, 0x3e, 0x81, 0x06, 0x9b, 0x2f, 0x02,
+ 0x79, 0x78, 0xee, 0xce, 0xc3, 0x8a, 0xda, 0x5d, 0xb1, 0xe9, 0x35, 0x42, 0x5c, 0x67, 0xf3, 0x85,
+ 0xdc, 0xe6, 0xfd, 0x67, 0xd0, 0x30, 0x5b, 0x2e, 0xb3, 0x56, 0xb9, 0xc1, 0x5a, 0xe1, 0x8a, 0x54,
+ 0x8b, 0x57, 0xa4, 0x2b, 0xa0, 0x61, 0xce, 0x5c, 0x76, 0x47, 0x9b, 0x08, 0x70, 0xa0, 0xe5, 0x4d,
+ 0x5e, 0x7a, 0x78, 0xe8, 0x4d, 0x82, 0xe1, 0xd0, 0x77, 0x2a, 0x25, 0x64, 0x3a, 0xf4, 0x75, 0x3b,
+ 0x75, 0x3a, 0x1a, 0x06, 0xa3, 0x93, 0x89, 0xb3, 0xb5, 0x1e, 0x0c, 0xa7, 0x3a, 0xf0, 0xce, 0x3c,
+ 0xa9, 0x28, 0x65, 0xb5, 0xc2, 0x70, 0x38, 0x75, 0xac, 0xee, 0xc7, 0x50, 0x93, 0x93, 0x0a, 0xd4,
+ 0x2d, 0xf7, 0x9b, 0xad, 0xe2, 0x61, 0x9a, 0x6b, 0xfe, 0x97, 0x26, 0x58, 0xba, 0xff, 0x44, 0x77,
+ 0x37, 0x45, 0xd0, 0xb4, 0x2b, 0xb2, 0x16, 0xde, 0x2b, 0xb4, 0x9a, 0x6b, 0x81, 0xbe, 0xc0, 0xf7,
+ 0x60, 0x9b, 0x33, 0x96, 0x95, 0x3b, 0x21, 0x05, 0xa1, 0x2e, 0xd8, 0x8b, 0x90, 0x93, 0x34, 0x93,
+ 0x7c, 0x6d, 0x17, 0x4d, 0x1b, 0x1a, 0x57, 0x97, 0xad, 0x93, 0xeb, 0x18, 0xf6, 0x76, 0x25, 0x7b,
+ 0xeb, 0x5e, 0x49, 0x0b, 0x4f, 0x75, 0xb4, 0xed, 0x83, 0xa5, 0xdf, 0x0f, 0xfa, 0xad, 0x61, 0x94,
+ 0x72, 0x10, 0xed, 0x41, 0x2d, 0x61, 0x11, 0x89, 0x75, 0x81, 0x34, 0x52, 0x8d, 0xa1, 0x27, 0xe0,
+ 0x5c, 0x86, 0x3c, 0xba, 0x0a, 0xf9, 0xa6, 0x90, 0xd6, 0x8b, 0x7a, 0x3b, 0x46, 0x6c, 0x4a, 0xea,
+ 0x13, 0x70, 0xe6, 0x94, 0x27, 0x25, 0x8b, 0x46, 0xc9, 0xc2, 0x88, 0x8d, 0xc5, 0x63, 0xb0, 0x54,
+ 0xad, 0xd1, 0x81, 0xd0, 0xfc, 0xa4, 0x53, 0xca, 0x2e, 0x62, 0xbd, 0x5e, 0xad, 0x24, 0xdb, 0x44,
+ 0x41, 0x38, 0x0d, 0xe3, 0x20, 0x5d, 0x26, 0xe7, 0x84, 0xab, 0x08, 0x59, 0x7b, 0x6f, 0x69, 0xd9,
+ 0x50, 0x89, 0x24, 0x97, 0x9b, 0x97, 0x96, 0x5b, 0xe2, 0x72, 0xfd, 0xe0, 0x7a, 0xb0, 0x79, 0x51,
+ 0x35, 0x8b, 0x1a, 0xeb, 0x87, 0x15, 0x82, 0xed, 0x55, 0x1c, 0xa6, 0x2a, 0x9e, 0xda, 0x58, 0x7d,
+ 0xcb, 0xd2, 0x9c, 0x84, 0x33, 0xf9, 0x5e, 0xe2, 0x44, 0xe8, 0x68, 0xb2, 0x31, 0x24, 0xe1, 0xac,
+ 0xa7, 0x11, 0xf4, 0x08, 0x5a, 0x74, 0xb1, 0xfa, 0xd9, 0x5a, 0x43, 0xc6, 0x94, 0xfd, 0xf2, 0x16,
+ 0x6e, 0x4a, 0xb4, 0xac, 0xf4, 0xe9, 0x5a, 0x69, 0xa7, 0xa0, 0xf4, 0xa9, 0x51, 0xfa, 0x00, 0xda,
+ 0x97, 0x4c, 0x64, 0x41, 0x98, 0x46, 0x3a, 0x04, 0xef, 0x1a, 0x2d, 0x09, 0xf7, 0xd2, 0x48, 0x45,
+ 0xd9, 0x3e, 0x00, 0xb9, 0xce, 0x78, 0x18, 0x84, 0xfc, 0x42, 0xb8, 0xef, 0xeb, 0x27, 0x82, 0x42,
+ 0x7a, 0xfc, 0x42, 0xa0, 0x67, 0xd0, 0x5e, 0x70, 0x76, 0xfd, 0x66, 0x3d, 0xd5, 0x1d, 0x45, 0xf5,
+ 0x5e, 0xf9, 0x21, 0x75, 0x78, 0x2a, 0x75, 0xf2, 0x89, 0x71, 0x6b, 0x51, 0x18, 0xdd, 0x4c, 0xb9,
+ 0xce, 0xff, 0x91, 0x72, 0x9f, 0x95, 0x53, 0xee, 0xed, 0x77, 0xa7, 0x5c, 0xc3, 0x7f, 0x31, 0xf3,
+ 0xee, 0xaf, 0x9b, 0xaf, 0xf7, 0x4a, 0x57, 0x38, 0xef, 0xa8, 0x7c, 0xe8, 0xcc, 0x58, 0x9a, 0xca,
+ 0x47, 0x67, 0x3e, 0x07, 0x52, 0x73, 0xec, 0x99, 0x39, 0xfa, 0x5a, 0xfa, 0x5d, 0xd3, 0xb4, 0x67,
+ 0x45, 0x19, 0xfa, 0x09, 0x58, 0xb3, 0xa5, 0xc8, 0x58, 0xe2, 0x3e, 0x53, 0x0c, 0xed, 0x1e, 0xea,
+ 0x5f, 0x0f, 0x0e, 0xcd, 0xaf, 0x07, 0x87, 0xbd, 0xf4, 0x0d, 0xce, 0x75, 0xd0, 0xe7, 0x00, 0x8b,
+ 0x24, 0xef, 0xcf, 0x84, 0xfb, 0x55, 0x45, 0x99, 0xdc, 0xbe, 0xf9, 0xb6, 0x10, 0xc7, 0xb5, 0x7f,
+ 0x7e, 0xfb, 0xcd, 0xfe, 0x2d, 0x6c, 0x2f, 0xd6, 0x0f, 0xa8, 0x13, 0xd8, 0xd1, 0xdd, 0x99, 0xe9,
+ 0x33, 0x85, 0xfb, 0x87, 0xca, 0x3b, 0x8a, 0xeb, 0x71, 0x53, 0xba, 0xb0, 0x74, 0x77, 0x8d, 0x3b,
+ 0xb4, 0x54, 0x9f, 0xef, 0x7f, 0x55, 0x85, 0x56, 0xf1, 0xec, 0xde, 0x9d, 0x74, 0x1f, 0x40, 0x33,
+ 0x17, 0x6e, 0xd2, 0x13, 0x86, 0x68, 0xf3, 0x83, 0xc5, 0x3e, 0xc0, 0xec, 0x32, 0x4c, 0x53, 0x12,
+ 0x4b, 0xf3, 0x2d, 0xfd, 0xa0, 0xcc, 0x11, 0x3f, 0x42, 0x07, 0xe0, 0x18, 0xb1, 0x7e, 0x77, 0xe6,
+ 0x89, 0xaa, 0x8d, 0x3b, 0x39, 0xae, 0xde, 0x60, 0x7e, 0x84, 0x8e, 0xe0, 0x8e, 0xd1, 0xcc, 0x08,
+ 0x4f, 0x68, 0x1a, 0xca, 0xf6, 0x36, 0xff, 0xcd, 0x03, 0xe5, 0xa2, 0xc9, 0x46, 0x82, 0xee, 0x82,
+ 0xc5, 0xd2, 0xa5, 0x74, 0x68, 0x29, 0x87, 0x35, 0x96, 0x2e, 0xfd, 0x08, 0x7d, 0x00, 0x1d, 0x09,
+ 0x0b, 0x22, 0x64, 0xc6, 0x30, 0xe5, 0xb7, 0x8d, 0x5b, 0x2c, 0x5d, 0x8e, 0x35, 0xe8, 0x47, 0xc7,
+ 0xb6, 0x8c, 0x64, 0xb5, 0xff, 0xee, 0x11, 0xd4, 0xf5, 0x95, 0x96, 0xf1, 0x53, 0xca, 0xe5, 0x9d,
+ 0xf2, 0x95, 0x37, 0xd9, 0xfc, 0xaf, 0x5b, 0xb0, 0x3b, 0xa6, 0xc9, 0x32, 0x0e, 0x33, 0xd2, 0x8b,
+ 0x43, 0x9e, 0x60, 0xf2, 0x7a, 0x49, 0x44, 0xf6, 0xd6, 0x03, 0xe7, 0x07, 0x60, 0xd3, 0x34, 0xa2,
+ 0xb3, 0x30, 0x63, 0xe6, 0x27, 0x98, 0x0d, 0x20, 0xeb, 0x19, 0x4d, 0xb3, 0xb9, 0xa1, 0xcd, 0xc6,
+ 0x96, 0x1c, 0xea, 0x1d, 0xa8, 0x54, 0x2d, 0x19, 0xd7, 0xcf, 0x78, 0xfd, 0xd8, 0x6b, 0x2d, 0xf2,
+ 0x2a, 0xa7, 0x5e, 0xf2, 0x5d, 0x68, 0xcb, 0x7d, 0x6e, 0x8e, 0x4e, 0x33, 0xd5, 0x64, 0xe9, 0x72,
+ 0x60, 0x4e, 0xef, 0x29, 0xbc, 0x47, 0x53, 0x99, 0x59, 0x49, 0x70, 0x4e, 0x33, 0x5d, 0xb3, 0x03,
+ 0x2e, 0x63, 0x52, 0x52, 0x56, 0xc3, 0x77, 0x72, 0xe9, 0x31, 0xcd, 0x54, 0xfd, 0xc6, 0xba, 0x1b,
+ 0xaf, 0x45, 0x9c, 0xce, 0x33, 0xc5, 0x5b, 0x0d, 0xeb, 0x81, 0x5c, 0x6d, 0x4a, 0xae, 0x02, 0xf2,
+ 0x3a, 0x52, 0x29, 0xba, 0x86, 0xad, 0x94, 0x5c, 0x79, 0xaf, 0xe5, 0x53, 0xfc, 0xb6, 0xe6, 0xbb,
+ 0x98, 0x67, 0xf5, 0x23, 0x65, 0x47, 0x51, 0x5e, 0xc8, 0xb1, 0x2f, 0xc1, 0x96, 0x91, 0xaa, 0x4f,
+ 0x16, 0x54, 0xdc, 0x7d, 0x64, 0x38, 0xfe, 0x2e, 0x46, 0x55, 0xc0, 0x2b, 0x6d, 0xd5, 0xd0, 0x6d,
+ 0x8c, 0xbb, 0x3f, 0x82, 0x76, 0x49, 0x86, 0x6c, 0xa8, 0xe1, 0x9e, 0x3f, 0xf6, 0xf4, 0xef, 0x26,
+ 0xfd, 0x13, 0xaf, 0x87, 0x9d, 0xca, 0xf1, 0x18, 0xee, 0x30, 0x7e, 0xa1, 0x3a, 0x90, 0x19, 0xe3,
+ 0x51, 0x3e, 0xd7, 0x71, 0xeb, 0x4c, 0xfd, 0xd7, 0x3c, 0xfd, 0xee, 0xf0, 0x82, 0x66, 0x97, 0xcb,
+ 0x73, 0x99, 0x00, 0x8e, 0x8c, 0xe6, 0x91, 0xd6, 0x7c, 0x9c, 0xff, 0x6e, 0xb7, 0x7a, 0x7a, 0x74,
+ 0xc1, 0x72, 0xec, 0xdc, 0x52, 0xe0, 0xd3, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x1d, 0x9a,
+ 0xe9, 0x51, 0x14, 0x00, 0x00,
}
diff --git a/vendor/github.com/opencord/voltha-protos/v3/go/voltha/logical_device.pb.go b/vendor/github.com/opencord/voltha-protos/v3/go/voltha/logical_device.pb.go
index 8ebaa02..7aef243 100644
--- a/vendor/github.com/opencord/voltha-protos/v3/go/voltha/logical_device.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v3/go/voltha/logical_device.pb.go
@@ -200,18 +200,10 @@
// device features
SwitchFeatures *openflow_13.OfpSwitchFeatures `protobuf:"bytes,4,opt,name=switch_features,json=switchFeatures,proto3" json:"switch_features,omitempty"`
// name of the root device anchoring logical device
- RootDeviceId string `protobuf:"bytes,5,opt,name=root_device_id,json=rootDeviceId,proto3" json:"root_device_id,omitempty"`
- // logical device ports
- Ports []*LogicalPort `protobuf:"bytes,128,rep,name=ports,proto3" json:"ports,omitempty"`
- // flows configured on the logical device
- Flows *openflow_13.Flows `protobuf:"bytes,129,opt,name=flows,proto3" json:"flows,omitempty"`
- // flow groups configured on the logical device
- FlowGroups *openflow_13.FlowGroups `protobuf:"bytes,130,opt,name=flow_groups,json=flowGroups,proto3" json:"flow_groups,omitempty"`
- // meters configured on the logical device
- Meters *openflow_13.Meters `protobuf:"bytes,131,opt,name=meters,proto3" json:"meters,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ RootDeviceId string `protobuf:"bytes,5,opt,name=root_device_id,json=rootDeviceId,proto3" json:"root_device_id,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}
func (m *LogicalDevice) Reset() { *m = LogicalDevice{} }
@@ -274,34 +266,6 @@
return ""
}
-func (m *LogicalDevice) GetPorts() []*LogicalPort {
- if m != nil {
- return m.Ports
- }
- return nil
-}
-
-func (m *LogicalDevice) GetFlows() *openflow_13.Flows {
- if m != nil {
- return m.Flows
- }
- return nil
-}
-
-func (m *LogicalDevice) GetFlowGroups() *openflow_13.FlowGroups {
- if m != nil {
- return m.FlowGroups
- }
- return nil
-}
-
-func (m *LogicalDevice) GetMeters() *openflow_13.Meters {
- if m != nil {
- return m.Meters
- }
- return nil
-}
-
type LogicalDevices struct {
Items []*LogicalDevice `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@@ -352,40 +316,34 @@
func init() { proto.RegisterFile("voltha_protos/logical_device.proto", fileDescriptor_caf139ab3abc8240) }
var fileDescriptor_caf139ab3abc8240 = []byte{
- // 550 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x93, 0xcf, 0x6a, 0xdb, 0x40,
- 0x10, 0xc6, 0xab, 0xd8, 0x72, 0xec, 0x91, 0xe3, 0xc0, 0x9a, 0x10, 0x91, 0xb4, 0xc4, 0x88, 0x1e,
- 0x1c, 0x4a, 0xa5, 0xd4, 0xa6, 0xd0, 0x1e, 0x0a, 0xad, 0x09, 0x2e, 0x86, 0xfe, 0x63, 0x0b, 0x3d,
- 0xf4, 0x22, 0x36, 0xd2, 0x5a, 0x16, 0xd8, 0x1a, 0xa1, 0x5d, 0x3b, 0xd7, 0xfe, 0x79, 0xad, 0xbe,
- 0x42, 0x5f, 0xa2, 0x8f, 0xd0, 0x43, 0xcf, 0x65, 0x77, 0xa5, 0xd4, 0x8a, 0xd3, 0xa3, 0xbe, 0xf9,
- 0x7d, 0x33, 0xb3, 0xdf, 0x20, 0xf0, 0x36, 0xb8, 0x94, 0x0b, 0x16, 0xe6, 0x05, 0x4a, 0x14, 0xc1,
- 0x12, 0x93, 0x34, 0x62, 0xcb, 0x30, 0xe6, 0x9b, 0x34, 0xe2, 0xbe, 0x56, 0x49, 0xcb, 0x30, 0x27,
- 0xf7, 0x13, 0xc4, 0x64, 0xc9, 0x03, 0x96, 0xa7, 0x01, 0xcb, 0x32, 0x94, 0x4c, 0xa6, 0x98, 0x09,
- 0x43, 0x9d, 0xb8, 0xf5, 0x4e, 0x2b, 0x2e, 0x59, 0x59, 0x39, 0xab, 0x57, 0x30, 0xe7, 0xd9, 0x7c,
- 0x89, 0xd7, 0xe1, 0x93, 0xb1, 0x01, 0xbc, 0x67, 0x70, 0xf0, 0xc6, 0x0c, 0xfe, 0x80, 0x85, 0x9c,
- 0xc5, 0xa4, 0x07, 0x7b, 0x69, 0xec, 0x5a, 0x03, 0x6b, 0xd8, 0xa1, 0x7b, 0x69, 0x4c, 0x8e, 0x61,
- 0x3f, 0xc7, 0x42, 0x86, 0x69, 0xec, 0xee, 0x69, 0xb1, 0x95, 0x6b, 0xd0, 0xfb, 0x6d, 0x81, 0xb3,
- 0x65, 0xdd, 0x31, 0x5e, 0x40, 0x1b, 0xe7, 0x79, 0xa8, 0x68, 0xed, 0x74, 0x46, 0x47, 0xfe, 0xf6,
- 0xfc, 0xaa, 0x48, 0xf7, 0x71, 0x9e, 0xeb, 0x0e, 0xa7, 0xd0, 0x31, 0x8f, 0x57, 0xc3, 0x1a, 0xba,
- 0x51, 0xdb, 0x08, 0xb3, 0x98, 0x3c, 0x84, 0x5e, 0x59, 0xd4, 0xeb, 0x64, 0xe8, 0x36, 0x07, 0xd6,
- 0xf0, 0x80, 0x76, 0x8d, 0xaa, 0x1a, 0xbc, 0x43, 0xd5, 0xa2, 0x40, 0x94, 0x66, 0xaa, 0x3d, 0xb0,
- 0x86, 0x6d, 0xda, 0x56, 0x82, 0xee, 0xff, 0x0a, 0x7a, 0xd5, 0xd0, 0x50, 0x48, 0x26, 0x85, 0xdb,
- 0xd2, 0x7b, 0x9d, 0xde, 0xb9, 0x97, 0x41, 0x68, 0xb7, 0xdc, 0xee, 0xa3, 0xfa, 0xf2, 0x9e, 0x43,
- 0x77, 0xeb, 0xcd, 0x82, 0x9c, 0x83, 0x9d, 0x4a, 0xbe, 0x12, 0xae, 0x35, 0x68, 0x0c, 0x9d, 0x51,
- 0xdf, 0x37, 0x79, 0xfb, 0x5b, 0x10, 0x35, 0x84, 0xf7, 0xa3, 0x71, 0x13, 0xf5, 0xa5, 0x5e, 0x79,
- 0x27, 0xb1, 0x33, 0x70, 0x62, 0x26, 0x59, 0xce, 0xe4, 0xa2, 0x8a, 0xbb, 0x49, 0xa1, 0x92, 0x66,
- 0x31, 0x39, 0x87, 0x66, 0xcc, 0x45, 0xa4, 0xb3, 0xb9, 0x2b, 0x4e, 0x55, 0xa4, 0x1a, 0x21, 0x33,
- 0x38, 0x14, 0xd7, 0xa9, 0x8c, 0x16, 0xe1, 0x9c, 0x33, 0xb9, 0x2e, 0xb8, 0xd0, 0x79, 0x39, 0xa3,
- 0xc1, 0x8e, 0xeb, 0x16, 0x47, 0x7b, 0x46, 0x98, 0x96, 0xdf, 0x2a, 0x79, 0x9d, 0xe9, 0xbf, 0xdb,
- 0xd8, 0x7a, 0xe5, 0xae, 0x52, 0x2f, 0xab, 0xfb, 0x3c, 0x05, 0x5b, 0xa5, 0x26, 0xdc, 0x2f, 0xff,
- 0x8f, 0x62, 0xd2, 0xf9, 0xf5, 0xe7, 0xe7, 0x83, 0xa6, 0x7a, 0x36, 0x35, 0x34, 0xb9, 0x00, 0x5b,
- 0xed, 0x22, 0xdc, 0xaf, 0x96, 0x5e, 0x8f, 0xd4, 0xd6, 0x9b, 0xaa, 0xd2, 0xc4, 0x56, 0xae, 0x7b,
- 0xd4, 0x80, 0xe4, 0x25, 0x38, 0xba, 0x9c, 0x14, 0xb8, 0xce, 0x85, 0xfb, 0xcd, 0xf8, 0x8e, 0x77,
- 0x7c, 0xaf, 0x75, 0xbd, 0x32, 0xc3, 0xfc, 0x46, 0x22, 0x63, 0x68, 0xad, 0xb8, 0xe4, 0x85, 0x70,
- 0xbf, 0x1b, 0x73, 0xbf, 0x66, 0x7e, 0xab, 0x6b, 0x95, 0xb1, 0x44, 0xbd, 0x17, 0xd0, 0xab, 0x5d,
- 0x4f, 0x90, 0x47, 0xf5, 0xdb, 0x1f, 0xdd, 0x7a, 0xb0, 0xc1, 0xca, 0xeb, 0x4f, 0x3e, 0x41, 0x1f,
- 0x8b, 0x44, 0xcf, 0x89, 0xb0, 0x88, 0x4b, 0x76, 0x72, 0xf8, 0x7e, 0x5a, 0xc3, 0x3f, 0xfb, 0x49,
- 0x2a, 0x17, 0xeb, 0x2b, 0x3f, 0xc2, 0x55, 0x50, 0xc1, 0x81, 0x81, 0x1f, 0x97, 0x3f, 0xf1, 0x66,
- 0x1c, 0x24, 0x58, 0x6a, 0x57, 0x2d, 0x2d, 0x8e, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xdd, 0xad,
- 0x36, 0xdf, 0x4d, 0x04, 0x00, 0x00,
+ // 456 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xc1, 0x6a, 0xdb, 0x40,
+ 0x10, 0x86, 0x91, 0x63, 0x3b, 0xce, 0xca, 0x51, 0x40, 0x21, 0x54, 0x24, 0x85, 0x08, 0xd1, 0x83,
+ 0x43, 0xa9, 0xd4, 0xda, 0x97, 0xf6, 0xd0, 0x43, 0x43, 0x08, 0x18, 0x4a, 0x5b, 0xb6, 0xd0, 0x43,
+ 0x2f, 0x62, 0xa3, 0x5d, 0xcb, 0x0b, 0xb2, 0x46, 0x68, 0x37, 0xce, 0xcb, 0xf6, 0x29, 0xfa, 0x04,
+ 0x65, 0x67, 0x57, 0x8d, 0x15, 0xfb, 0xa8, 0x7f, 0xbe, 0x99, 0xf9, 0xe7, 0x5f, 0x91, 0x64, 0x0b,
+ 0x95, 0x5e, 0xb3, 0xbc, 0x69, 0x41, 0x83, 0xca, 0x2a, 0x28, 0x65, 0xc1, 0xaa, 0x9c, 0x8b, 0xad,
+ 0x2c, 0x44, 0x8a, 0x6a, 0x38, 0xb6, 0xcc, 0xe5, 0xeb, 0x12, 0xa0, 0xac, 0x44, 0xc6, 0x1a, 0x99,
+ 0xb1, 0xba, 0x06, 0xcd, 0xb4, 0x84, 0x5a, 0x59, 0xea, 0x32, 0xea, 0x4f, 0xda, 0x08, 0xcd, 0x5c,
+ 0xe5, 0xba, 0x5f, 0x81, 0x46, 0xd4, 0xab, 0x0a, 0x9e, 0xf2, 0x0f, 0x0b, 0x0b, 0x24, 0x1f, 0xc9,
+ 0xe9, 0x57, 0xbb, 0xf8, 0x07, 0xb4, 0x7a, 0xc9, 0xc3, 0x80, 0x0c, 0x24, 0x8f, 0xbc, 0xd8, 0x9b,
+ 0x9d, 0xd0, 0x81, 0xe4, 0xe1, 0x2b, 0x72, 0xdc, 0x40, 0xab, 0x73, 0xc9, 0xa3, 0x01, 0x8a, 0xe3,
+ 0x06, 0xc1, 0xe4, 0xaf, 0x47, 0xfc, 0x9d, 0xd6, 0xbd, 0xc6, 0xf7, 0x64, 0x02, 0xab, 0x26, 0x37,
+ 0x34, 0x76, 0xfa, 0xf3, 0x8b, 0x74, 0x77, 0x7f, 0x57, 0xa4, 0xc7, 0xb0, 0x6a, 0x70, 0xc2, 0x15,
+ 0x39, 0xb1, 0xc7, 0x9b, 0x65, 0x47, 0x38, 0x68, 0x62, 0x85, 0x25, 0x0f, 0xdf, 0x90, 0xc0, 0x15,
+ 0xd1, 0x4e, 0x0d, 0xd1, 0x30, 0xf6, 0x66, 0xa7, 0x74, 0x6a, 0x55, 0x33, 0xe0, 0x1b, 0x98, 0x11,
+ 0x2d, 0x80, 0xb6, 0x5b, 0x47, 0xb1, 0x37, 0x9b, 0xd0, 0x89, 0x11, 0x70, 0xfe, 0x17, 0x12, 0x74,
+ 0x4b, 0x73, 0xa5, 0x99, 0x56, 0xd1, 0x18, 0x7d, 0x5d, 0x1d, 0xf4, 0x65, 0x11, 0x3a, 0x75, 0xee,
+ 0x7e, 0x9a, 0xaf, 0xe4, 0x13, 0x99, 0xee, 0xdc, 0xac, 0xc2, 0x1b, 0x32, 0x92, 0x5a, 0x6c, 0x54,
+ 0xe4, 0xc5, 0x47, 0x33, 0x7f, 0x7e, 0x9e, 0xda, 0xbc, 0xd3, 0x1d, 0x88, 0x5a, 0x22, 0xf9, 0xe3,
+ 0xfd, 0x8f, 0xfa, 0x0e, 0x2d, 0xef, 0x25, 0x76, 0x4d, 0x7c, 0xce, 0x34, 0x6b, 0x98, 0x5e, 0x77,
+ 0x71, 0x0f, 0x29, 0xe9, 0xa4, 0x25, 0x0f, 0x6f, 0xc8, 0x90, 0x0b, 0x55, 0x60, 0x36, 0x87, 0xe2,
+ 0x34, 0x45, 0x8a, 0x48, 0xb8, 0x24, 0x67, 0xea, 0x49, 0xea, 0x62, 0x9d, 0xaf, 0x04, 0xd3, 0x8f,
+ 0xad, 0x50, 0x98, 0x97, 0x3f, 0x8f, 0xf7, 0xba, 0x5e, 0x70, 0x34, 0xb0, 0xc2, 0xbd, 0xfb, 0x36,
+ 0xc9, 0x63, 0xa6, 0xcf, 0x6f, 0x33, 0x42, 0xcb, 0x53, 0xa3, 0xde, 0xb9, 0xf7, 0x49, 0x3e, 0x93,
+ 0xa0, 0x77, 0x9d, 0x0a, 0xdf, 0xf6, 0xb3, 0xb9, 0x78, 0x91, 0x8d, 0xc5, 0x5c, 0x3a, 0xb7, 0xbf,
+ 0xc8, 0x39, 0xb4, 0x25, 0x7a, 0x2b, 0xa0, 0xe5, 0x8e, 0xbd, 0x3d, 0xfb, 0x7e, 0xdf, 0xc3, 0x7f,
+ 0xa7, 0xa5, 0xd4, 0xeb, 0xc7, 0x87, 0xb4, 0x80, 0x4d, 0xd6, 0xc1, 0x99, 0x85, 0xdf, 0xb9, 0x9f,
+ 0x7c, 0xbb, 0xc8, 0x4a, 0x70, 0xda, 0xc3, 0x18, 0xc5, 0xc5, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0x91, 0x0c, 0xf4, 0xf2, 0x6d, 0x03, 0x00, 0x00,
}