func()

in pkg/resmgr/respool/respoolsvc/handler.go [395:508]


func (h *ServiceHandler) UpdateResourcePool(
	ctx context.Context,
	req *respool.UpdateRequest) (
	*respool.UpdateResponse,
	error) {

	h.Lock()
	defer h.Unlock()

	h.metrics.APIUpdateResourcePool.Inc(1)
	log.WithField(
		"request",
		req,
	).Info("UpdateResourcePool called")

	resPoolID := req.GetId()
	resPoolConfig := req.GetConfig()

	if !req.GetForce() {
		resourcePoolConfigData := res.ResourcePoolConfigData{
			ID:                 resPoolID,
			ResourcePoolConfig: resPoolConfig,
		}
		// perform validation on resource pool resPoolConfig.
		err := h.resPoolConfigValidator.Validate(resourcePoolConfigData)
		if err != nil {
			h.metrics.UpdateResourcePoolFail.Inc(1)
			log.WithError(
				err,
			).WithField(
				"respool_id", resPoolID.GetValue()).
				Info(
					"Error validating resource pool:")
			return &respool.UpdateResponse{
				Error: &respool.UpdateResponse_Error{
					InvalidResourcePoolConfig: &respool.InvalidResourcePoolConfig{
						Id:      resPoolID,
						Message: err.Error(),
					},
				},
			}, nil
		}
	}

	// needed for rollback.
	existingResPool, err := h.resPoolTree.Get(resPoolID)
	if err != nil {
		h.metrics.UpdateResourcePoolFail.Inc(1)
		log.WithError(
			err,
		).Infof(
			"Error fetching respoolID: %s",
			resPoolID.Value,
		)
		return &respool.UpdateResponse{
			Error: &respool.UpdateResponse_Error{
				// TODO  differentiate between n/w errors vs other data errors
				NotFound: &respool.ResourcePoolNotFound{
					Id:      resPoolID,
					Message: err.Error(),
				},
			},
		}, nil
	}

	// update persistent store.
	if err := h.resPoolOps.Update(ctx, resPoolID, resPoolConfig); err != nil {
		h.metrics.UpdateResourcePoolFail.Inc(1)
		log.WithError(
			err,
		).Infof(
			"Error updating respoolID: %s in store",
			resPoolID.Value,
		)
		return &respool.UpdateResponse{
			Error: &respool.UpdateResponse_Error{
				// TODO  differentiate between n/w errors
				// vs other data errors
				NotFound: &respool.ResourcePoolNotFound{
					Id:      resPoolID,
					Message: err.Error(),
				},
			},
		}, nil
	}

	// update the in-memory data structure.
	if err := h.resPoolTree.Upsert(resPoolID, resPoolConfig); err != nil {
		// rollback to a previous version if any errors.
		h.metrics.UpdateResourcePoolFail.Inc(1)
		log.WithError(
			err,
		).Infof(
			"Error updating respoolID: %s in memory tree",
			resPoolID.Value,
		)

		// update with existing.
		if err := h.resPoolOps.Update(
			ctx,
			resPoolID,
			existingResPool.ResourcePoolConfig(),
		); err != nil {
			log.WithError(err).
				Infof("Error rolling back respoolID: %s in store",
					resPoolID.Value)
			h.metrics.UpdateResourcePoolRollbackFail.Inc(1)
			return &respool.UpdateResponse{}, err
		}
	}

	h.metrics.UpdateResourcePoolSuccess.Inc(1)
	return &respool.UpdateResponse{}, nil
}