github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/broker/instance_last_operation.go (about) 1 package broker 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 8 "github.com/kyma-project/kyma-environment-broker/common/orchestration" 9 "github.com/kyma-project/kyma-environment-broker/internal/storage" 10 "github.com/kyma-project/kyma-environment-broker/internal/storage/dberr" 11 "github.com/pivotal-cf/brokerapi/v8/domain" 12 "github.com/pivotal-cf/brokerapi/v8/domain/apiresponses" 13 "github.com/sirupsen/logrus" 14 ) 15 16 type LastOperationEndpoint struct { 17 operationStorage storage.Operations 18 19 log logrus.FieldLogger 20 } 21 22 func NewLastOperation(os storage.Operations, log logrus.FieldLogger) *LastOperationEndpoint { 23 return &LastOperationEndpoint{ 24 operationStorage: os, 25 log: log.WithField("service", "LastOperationEndpoint"), 26 } 27 } 28 29 // LastOperation fetches last operation state for a service instance 30 // 31 // GET /v2/service_instances/{instance_id}/last_operation 32 func (b *LastOperationEndpoint) LastOperation(ctx context.Context, instanceID string, details domain.PollDetails) (domain.LastOperation, error) { 33 logger := b.log.WithField("instanceID", instanceID).WithField("operationID", details.OperationData) 34 35 if details.OperationData == "" { 36 lastOp, err := b.operationStorage.GetLastOperation(instanceID) 37 if err != nil { 38 logger.Errorf("cannot get operation from storage: %s", err) 39 statusCode := http.StatusInternalServerError 40 if dberr.IsNotFound(err) { 41 statusCode = http.StatusNotFound 42 } 43 return domain.LastOperation{}, apiresponses.NewFailureResponse(err, statusCode, 44 fmt.Sprintf("while getting last operation from storage")) 45 } 46 return domain.LastOperation{ 47 State: mapStateToOSBCompliantState(lastOp.State), 48 Description: lastOp.Description, 49 }, nil 50 } 51 52 operation, err := b.operationStorage.GetOperationByID(details.OperationData) 53 if err != nil { 54 logger.Errorf("cannot get operation from storage: %s", err) 55 statusCode := http.StatusInternalServerError 56 if dberr.IsNotFound(err) { 57 statusCode = http.StatusNotFound 58 } 59 return domain.LastOperation{}, apiresponses.NewFailureResponse(err, statusCode, 60 fmt.Sprintf("while getting operation from storage")) 61 } 62 63 if operation.InstanceID != instanceID { 64 err := fmt.Errorf("operation exists, but instanceID is invalid") 65 logger.Errorf("%s", err.Error()) 66 return domain.LastOperation{}, apiresponses.NewFailureResponse(err, http.StatusBadRequest, err.Error()) 67 } 68 69 return domain.LastOperation{ 70 State: mapStateToOSBCompliantState(operation.State), 71 Description: operation.Description, 72 }, nil 73 } 74 75 func mapStateToOSBCompliantState(opState domain.LastOperationState) domain.LastOperationState { 76 switch { 77 case opState == orchestration.Pending || opState == orchestration.Retrying: 78 return domain.InProgress 79 case opState == orchestration.Canceled || opState == orchestration.Canceling: 80 return domain.Succeeded 81 default: 82 return opState 83 } 84 }