// current implementation of Delete blows away the record completely if Change.ChangeSet.Data is not supplied func (c *Config) Delete(ctx context.Context, req *proto.DeleteRequest, rsp *proto.DeleteResponse) error { if req.Change == nil { return errors.BadRequest("go.micro.srv.config.Update", "invalid change") } if len(req.Change.Id) == 0 { return errors.BadRequest("go.micro.srv.config.Update", "invalid id") } if req.Change.ChangeSet == nil { req.Change.ChangeSet = &proto2.ChangeSet{} } if req.Change.Timestamp == 0 { req.Change.Timestamp = time.Now().Unix() } if req.Change.ChangeSet.Timestamp == 0 { req.Change.ChangeSet.Timestamp = time.Now().Unix() } // We're going to delete the record as we have no path and no data if len(req.Change.Path) == 0 { if err := db.Delete(req.Change); err != nil { return errors.InternalServerError("go.micro.srv.config.Delete", err.Error()) } return nil } // We've got a path. Let's update the required path // Get the current change set ch, err := db.Read(req.Change.Id) if err != nil { return errors.InternalServerError("go.micro.srv.config.Delete", err.Error()) } // Get the current config as values values, err := config.Values(&conf.ChangeSet{ Timestamp: time.Unix(ch.ChangeSet.Timestamp, 0), Data: []byte(ch.ChangeSet.Data), Checksum: ch.ChangeSet.Checksum, Source: ch.ChangeSet.Source, }) if err != nil { return errors.InternalServerError("go.micro.srv.config.Delete", err.Error()) } // Delete at the given path values.Del(strings.Split(req.Change.Path, config.PathSplitter)...) // Create a change record from the values change, err := config.Parse(&conf.ChangeSet{Data: values.Bytes()}) if err != nil { return errors.InternalServerError("go.micro.srv.config.Delete", err.Error()) } // Update change set req.Change.ChangeSet = &proto2.ChangeSet{ Timestamp: change.Timestamp.Unix(), Data: string(change.Data), Checksum: change.Checksum, Source: change.Source, } if err := db.Update(req.Change); err != nil { return errors.InternalServerError("go.micro.srv.config.Delete", err.Error()) } config.Publish(ctx, &proto.WatchResponse{Id: req.Change.Id, ChangeSet: req.Change.ChangeSet}) return nil }
func (c *Config) Create(ctx context.Context, req *proto.CreateRequest, rsp *proto.CreateResponse) error { if req.Change == nil || req.Change.ChangeSet == nil { return errors.BadRequest("go.micro.srv.config.Create", "invalid change") } if len(req.Change.Id) == 0 { return errors.BadRequest("go.micro.srv.config.Create", "invalid id") } if req.Change.Timestamp == 0 { req.Change.Timestamp = time.Now().Unix() } if req.Change.ChangeSet.Timestamp == 0 { req.Change.ChangeSet.Timestamp = time.Now().Unix() } // Set the change at a particular path // Since its a create request we have to build the path if len(req.Change.Path) > 0 { // Unpack the data as a go type var data interface{} vals, err := config.Values(&conf.ChangeSet{Data: []byte(req.Change.ChangeSet.Data)}) if err != nil { return errors.InternalServerError("go.micro.srv.config.Create", err.Error()) } if err := vals.Get().Scan(&data); err != nil { return errors.InternalServerError("go.micro.srv.config.Create", err.Error()) } // Since it's a create request, make new base value values, err := config.Values(&conf.ChangeSet{Data: []byte(`{}`)}) if err != nil { return errors.InternalServerError("go.micro.srv.config.Create", err.Error()) } // Set the data at path values.Set(data, strings.Split(req.Change.Path, config.PathSplitter)...) // Create the new change newChange, err := config.Parse(&conf.ChangeSet{Data: values.Bytes()}) if err != nil { return errors.InternalServerError("go.micro.srv.config.Create", err.Error()) } req.Change.ChangeSet = &proto2.ChangeSet{ Timestamp: newChange.Timestamp.Unix(), Data: string(newChange.Data), Checksum: newChange.Checksum, Source: newChange.Source, } } if err := db.Create(req.Change); err != nil { return errors.InternalServerError("go.micro.srv.config.Create", err.Error()) } config.Publish(ctx, &proto.WatchResponse{Id: req.Change.Id, ChangeSet: req.Change.ChangeSet}) return nil }
func (c *Config) Update(ctx context.Context, req *proto.UpdateRequest, rsp *proto.UpdateResponse) error { if req.Change == nil || req.Change.ChangeSet == nil { return errors.BadRequest("go.micro.srv.config.Update", "invalid change") } if len(req.Change.Id) == 0 { return errors.BadRequest("go.micro.srv.config.Update", "invalid id") } if req.Change.Timestamp == 0 { req.Change.Timestamp = time.Now().Unix() } if req.Change.ChangeSet.Timestamp == 0 { req.Change.ChangeSet.Timestamp = time.Now().Unix() } // Get the current change set ch, err := db.Read(req.Change.Id) if err != nil { return errors.InternalServerError("go.micro.srv.config.Update", err.Error()) } change := &conf.ChangeSet{ Timestamp: time.Unix(ch.ChangeSet.Timestamp, 0), Data: []byte(ch.ChangeSet.Data), Checksum: ch.ChangeSet.Checksum, Source: ch.ChangeSet.Source, } var newChange *conf.ChangeSet // Set the change at a particular path if len(req.Change.Path) > 0 { // Unpack the data as a go type var data interface{} vals, err := config.Values(&conf.ChangeSet{Data: []byte(req.Change.ChangeSet.Data)}) if err != nil { return errors.InternalServerError("go.micro.srv.config.Create", err.Error()) } if err := vals.Get().Scan(&data); err != nil { return errors.InternalServerError("go.micro.srv.config.Create", err.Error()) } // Get values from existing change values, err := config.Values(change) if err != nil { return errors.InternalServerError("go.micro.srv.config.Update", err.Error()) } // Apply the data to the existing change values.Set(data, strings.Split(req.Change.Path, config.PathSplitter)...) // Create a new change newChange, err = config.Parse(&conf.ChangeSet{Data: values.Bytes()}) if err != nil { return errors.InternalServerError("go.micro.srv.config.Update", err.Error()) } } else { // No path specified, business as usual newChange, err = config.Parse(change, &conf.ChangeSet{ Timestamp: time.Unix(req.Change.ChangeSet.Timestamp, 0), Data: []byte(req.Change.ChangeSet.Data), Checksum: req.Change.ChangeSet.Checksum, Source: req.Change.ChangeSet.Source, }) if err != nil { return errors.InternalServerError("go.micro.srv.config.Update", err.Error()) } } // update change set req.Change.ChangeSet = &proto2.ChangeSet{ Timestamp: newChange.Timestamp.Unix(), Data: string(newChange.Data), Checksum: newChange.Checksum, Source: newChange.Source, } if err := db.Update(req.Change); err != nil { return errors.InternalServerError("go.micro.srv.config.Update", err.Error()) } config.Publish(ctx, &proto.WatchResponse{Id: req.Change.Id, ChangeSet: req.Change.ChangeSet}) return nil }