Example #1
0
// 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
}
Example #2
0
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
}