diff --git a/handler/handler.go b/handler/handler.go index 824e1b073810dcba040ccc83e02cfda816ddb2da..91f278d24a42d44eddc0ef5254827a48d95c605e 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -19,23 +19,23 @@ type Config struct { } func (c *Config) Lock() { - logrus.Debug("Lock config") c.mu.Lock() + logrus.Debug("Lock config") } func (c *Config) Unlock() { - logrus.Debug("Unlock config") c.mu.Unlock() + logrus.Debug("Unlock config") } func (c *Config) RLock() { - logrus.Debug("RLock config") c.mu.RLock() + logrus.Debug("RLock config") } func (c *Config) RUnlock() { - logrus.Debug("RUnlock config") c.mu.RUnlock() + logrus.Debug("RUnlock config") } // PathHandler handles configuration changes and adjusts the targets config diff --git a/internal/gnmiserver/server.go b/internal/gnmiserver/server.go index 86b816aa2c79878d6f9689f78d729c719edf11b9..423265267e4ae83e160ceeb30ea4fd48dd6a05d1 100644 --- a/internal/gnmiserver/server.go +++ b/internal/gnmiserver/server.go @@ -337,22 +337,26 @@ func (s *Server) doReplaceOrUpdate(jsonTree map[string]interface{}, op pb.Update switch node := curNode.(type) { case map[string]interface{}: // Set node value. - if i == len(fullPath.Elem)-1 { - if elem.GetKey() == nil { - if grpcStatusError := setPathWithoutAttribute(op, node, elem, nodeVal); grpcStatusError != nil { + if node != nil { + if i == len(fullPath.Elem)-1 { + if elem.GetKey() == nil { + if grpcStatusError := setPathWithoutAttribute(op, node, elem, nodeVal); grpcStatusError != nil { + return nil, grpcStatusError + } + break + } + if grpcStatusError := setPathWithAttribute(op, node, elem, nodeVal); grpcStatusError != nil { return nil, grpcStatusError } break } - if grpcStatusError := setPathWithAttribute(op, node, elem, nodeVal); grpcStatusError != nil { - return nil, grpcStatusError - } - break - } - logrus.Info("doReplaceOrUpdate, node: ", node) - if curNode, schema = getChildNode(node, schema, elem, true); curNode == nil { - return nil, status.Errorf(codes.NotFound, "path elem not found: %v", elem) + logrus.Debug("doReplaceOrUpdate, node: ", node) + if curNode, schema = getChildNode(node, schema, elem, true); curNode == nil { + return nil, status.Errorf(codes.NotFound, "path elem not found: %v", elem) + } + } else { + logrus.Debugf("node is nil for path elem: %s", elem.String()) } case []interface{}: return nil, status.Errorf(codes.NotFound, "incompatible path elem: %v", elem) @@ -687,6 +691,7 @@ func (s *Server) Set(ctx context.Context, req *pb.SetRequest) (*pb.SetResponse, s.config.Lock() defer s.config.Unlock() + logrus.Debug("Current data: ", s.config.Data) // Obtain current configuration as JSON jsonTree, err := ygot.ConstructIETFJSON(s.config.Data, &ygot.RFC7951JSONConfig{}) if err != nil { diff --git a/internal/gnmiserver/subscribe.go b/internal/gnmiserver/subscribe.go index 9a15c9a70edcbb5ced10aaa478daa418fe9be960..96693f5dddadb70d11bc0900b9b42b478f88d595 100644 --- a/internal/gnmiserver/subscribe.go +++ b/internal/gnmiserver/subscribe.go @@ -37,9 +37,12 @@ func (s *Server) Subscribe(stream gnmi.GNMI_SubscribeServer) error { // NOTE: Using ytypes.GetNode might not be the best solution to // check if a given path exists. Since we do not really care about // the node at all in this case. + s.config.RLock() if _, err := ytypes.GetNode(s.model.schemaTreeRoot, s.config.Data, sub.GetPath()); err != nil { + s.config.RUnlock() return status.Error(codes.Internal, fmt.Sprintf("The provided path: %s, does not exist, subscribe not possible.", path.String())) } + s.config.RUnlock() // Print the path a subscription is requested for. log.Infof("Received subscribe for gnmi path %s with mode %s", path.String(), subscriptions.GetMode().String()) @@ -112,11 +115,14 @@ func (s *Server) streamOnChangeSubscriptionHandler(notificationSubscriber *notif log.Error(err) return } + s.config.RLock() node, err := ytypes.GetNode(s.model.schemaTreeRoot, s.config.Data, path) if err != nil { + s.config.RUnlock() log.Error(err) return } + s.config.RUnlock() var notifications []*gnmi.Notification if node[0].Schema.IsLeaf() {