diff --git a/api.go b/api.go index 195db202..d23b83bf 100644 --- a/api.go +++ b/api.go @@ -16,52 +16,15 @@ package brokerapi import ( - "encoding/json" - "errors" - "fmt" "net/http" "code.cloudfoundry.org/lager" "github.com/gorilla/mux" "github.com/pivotal-cf/brokerapi/auth" - "github.com/pivotal-cf/brokerapi/domain" - "github.com/pivotal-cf/brokerapi/domain/apiresponses" "github.com/pivotal-cf/brokerapi/handlers" "github.com/pivotal-cf/brokerapi/middlewares" ) -const ( - provisionLogKey = "provision" - deprovisionLogKey = "deprovision" - bindLogKey = "bind" - getBindLogKey = "getBinding" - getInstanceLogKey = "getInstance" - unbindLogKey = "unbind" - updateLogKey = "update" - lastOperationLogKey = "lastOperation" - lastBindingOperationLogKey = "lastBindingOperation" - - instanceIDLogKey = "instance-id" - instanceDetailsLogKey = "instance-details" - - bindingIDLogKey = "binding-id" - invalidServiceDetailsErrorKey = "invalid-service-details" - - unknownErrorKey = "unknown-error" - apiVersionInvalidKey = "broker-api-version-invalid" - serviceIdMissingKey = "service-id-missing" - planIdMissingKey = "plan-id-missing" - invalidServiceID = "invalid-service-id" - invalidPlanID = "invalid-plan-id" -) - -var ( - serviceIdError = errors.New("service_id missing") - planIdError = errors.New("plan_id missing") - invalidServiceIDError = errors.New("service-id not in the catalog") - invalidPlanIDError = errors.New("plan-id not in the catalog") -) - type BrokerCredentials struct { Username string Password string @@ -83,15 +46,13 @@ func New(serviceBroker ServiceBroker, logger lager.Logger, brokerCredentials Bro } func AttachRoutes(router *mux.Router, serviceBroker ServiceBroker, logger lager.Logger) { - handler := serviceBrokerHandler{serviceBroker: serviceBroker, logger: logger} - apiHandler := handlers.APIHandler{serviceBroker, logger} router.HandleFunc("/v2/catalog", apiHandler.Catalog).Methods("GET") router.HandleFunc("/v2/service_instances/{instance_id}", apiHandler.GetInstance).Methods("GET") router.HandleFunc("/v2/service_instances/{instance_id}", apiHandler.Provision).Methods("PUT") router.HandleFunc("/v2/service_instances/{instance_id}", apiHandler.Deprovision).Methods("DELETE") - router.HandleFunc("/v2/service_instances/{instance_id}/last_operation", handler.lastOperation).Methods("GET") + router.HandleFunc("/v2/service_instances/{instance_id}/last_operation", apiHandler.LastOperation).Methods("GET") router.HandleFunc("/v2/service_instances/{instance_id}", apiHandler.Update).Methods("PATCH") router.HandleFunc("/v2/service_instances/{instance_id}/service_bindings/{binding_id}", apiHandler.GetBinding).Methods("GET") @@ -100,74 +61,3 @@ func AttachRoutes(router *mux.Router, serviceBroker ServiceBroker, logger lager. router.HandleFunc("/v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation", apiHandler.LastBindingOperation).Methods("GET") } - -type serviceBrokerHandler struct { - serviceBroker domain.ServiceBroker - logger lager.Logger -} - -func (h serviceBrokerHandler) lastOperation(w http.ResponseWriter, req *http.Request) { - vars := mux.Vars(req) - instanceID := vars["instance_id"] - pollDetails := domain.PollDetails{ - PlanID: req.FormValue("plan_id"), - ServiceID: req.FormValue("service_id"), - OperationData: req.FormValue("operation"), - } - - logger := h.logger.Session(lastOperationLogKey, lager.Data{ - instanceIDLogKey: instanceID, - }) - - logger.Info("starting-check-for-operation") - - lastOperation, err := h.serviceBroker.LastOperation(req.Context(), instanceID, pollDetails) - - if err != nil { - switch err := err.(type) { - case *apiresponses.FailureResponse: - logger.Error(err.LoggerAction(), err) - h.respond(w, err.ValidatedStatusCode(logger), err.ErrorResponse()) - default: - logger.Error(unknownErrorKey, err) - h.respond(w, http.StatusInternalServerError, apiresponses.ErrorResponse{ - Description: err.Error(), - }) - } - return - } - - logger.WithData(lager.Data{"state": lastOperation.State}).Info("done-check-for-operation") - - lastOperationResponse := apiresponses.LastOperationResponse{ - State: lastOperation.State, - Description: lastOperation.Description, - } - - h.respond(w, http.StatusOK, lastOperationResponse) -} - -func (h serviceBrokerHandler) respond(w http.ResponseWriter, status int, response interface{}) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(status) - - encoder := json.NewEncoder(w) - err := encoder.Encode(response) - if err != nil { - h.logger.Error("encoding response", err, lager.Data{"status": status, "response": response}) - } -} - -type brokerVersion struct { - Major int - Minor int -} - -func getAPIVersion(req *http.Request) brokerVersion { - var version brokerVersion - apiVersion := req.Header.Get("X-Broker-API-Version") - - fmt.Sscanf(apiVersion, "%d.%d", &version.Major, &version.Minor) - - return version -} diff --git a/handlers/api_handler.go b/handlers/api_handler.go index cbf23983..2d47ac3a 100644 --- a/handlers/api_handler.go +++ b/handlers/api_handler.go @@ -19,8 +19,6 @@ const ( apiVersionInvalidKey = "broker-api-version-invalid" bindingIDLogKey = "binding-id" - - lastOperationLogKey = "lastOperation" ) var ( diff --git a/handlers/last_operation.go b/handlers/last_operation.go new file mode 100644 index 00000000..6fcc4b91 --- /dev/null +++ b/handlers/last_operation.go @@ -0,0 +1,53 @@ +package handlers + +import ( + "net/http" + + "code.cloudfoundry.org/lager" + "github.com/gorilla/mux" + "github.com/pivotal-cf/brokerapi/domain" + "github.com/pivotal-cf/brokerapi/domain/apiresponses" +) + +const lastOperationLogKey = "lastOperation" + +func (h APIHandler) LastOperation(w http.ResponseWriter, req *http.Request) { + vars := mux.Vars(req) + instanceID := vars["instance_id"] + pollDetails := domain.PollDetails{ + PlanID: req.FormValue("plan_id"), + ServiceID: req.FormValue("service_id"), + OperationData: req.FormValue("operation"), + } + + logger := h.Logger.Session(lastOperationLogKey, lager.Data{ + instanceIDLogKey: instanceID, + }) + + logger.Info("starting-check-for-operation") + + lastOperation, err := h.ServiceBroker.LastOperation(req.Context(), instanceID, pollDetails) + + if err != nil { + switch err := err.(type) { + case *apiresponses.FailureResponse: + logger.Error(err.LoggerAction(), err) + h.respond(w, err.ValidatedStatusCode(logger), err.ErrorResponse()) + default: + logger.Error(unknownErrorKey, err) + h.respond(w, http.StatusInternalServerError, apiresponses.ErrorResponse{ + Description: err.Error(), + }) + } + return + } + + logger.WithData(lager.Data{"state": lastOperation.State}).Info("done-check-for-operation") + + lastOperationResponse := apiresponses.LastOperationResponse{ + State: lastOperation.State, + Description: lastOperation.Description, + } + + h.respond(w, http.StatusOK, lastOperationResponse) +}