Skip to content

Commit

Permalink
Add correlation id middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
ataleksandrov authored and FelisiaM committed Sep 24, 2019
1 parent 7f17218 commit cf3240c
Show file tree
Hide file tree
Showing 16 changed files with 188 additions and 22 deletions.
9 changes: 9 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func New(serviceBroker ServiceBroker, logger lager.Logger, brokerCredentials Bro
authMiddleware := auth.NewWrapper(brokerCredentials.Username, brokerCredentials.Password).Wrap
apiVersionMiddleware := middlewares.APIVersionMiddleware{LoggerFactory: logger}

router.Use(middlewares.AddCorrelationIDToContext)
router.Use(authMiddleware)
router.Use(middlewares.AddOriginatingIdentityToContext)
router.Use(apiVersionMiddleware.ValidateAPIVersionHdr)
Expand Down
59 changes: 59 additions & 0 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"net/url"
"strings"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"code.cloudfoundry.org/lager/lagertest"
"github.com/drewolson/testflight"
Expand Down Expand Up @@ -109,6 +111,13 @@ var _ = Describe("Service Broker API", func() {
return recorder
}

It("has a X-Correlation-ID header", func() {
response := makeRequest()

header := response.Header().Get("X-Correlation-ID")
Expect(header).Should(Not(BeNil()))
})

It("has a Content-Type header", func() {
response := makeRequest()

Expand Down Expand Up @@ -2326,4 +2335,54 @@ var _ = Describe("Service Broker API", func() {
})
})
})

Describe("CorrelationIDHeader", func() {

var (
fakeServiceBroker *fakes.AutoFakeServiceBroker
req *http.Request
testServer *httptest.Server
)

BeforeEach(func() {
fakeServiceBroker = new(fakes.AutoFakeServiceBroker)
brokerAPI = brokerapi.New(fakeServiceBroker, brokerLogger, credentials)

testServer = httptest.NewServer(brokerAPI)
var err error
req, err = http.NewRequest("GET", testServer.URL+"/v2/catalog", nil)
Expect(err).NotTo(HaveOccurred())
req.Header.Add("X-Broker-API-Version", "2.14")
req.SetBasicAuth(credentials.Username, credentials.Password)
})

AfterEach(func() {
testServer.Close()
})

When("X-Correlation-ID is passed", func() {
It("Adds correlation id to the context", func() {
const correlationID = "fake-correlation-id"
req.Header.Add("X-Correlation-ID", correlationID)

_, err := http.DefaultClient.Do(req)
Expect(err).NotTo(HaveOccurred())

Expect(fakeServiceBroker.ServicesCallCount()).To(Equal(1), "Services was not called")
ctx := fakeServiceBroker.ServicesArgsForCall(0)
Expect(ctx.Value(middlewares.CorrelationIDKey)).To(Equal(correlationID))

})
})
When("X-Correlation-ID is not passed", func() {
It("Generates correlation id and adds it to the context", func() {
_, err := http.DefaultClient.Do(req)
Expect(err).NotTo(HaveOccurred())

Expect(fakeServiceBroker.ServicesCallCount()).To(Equal(1), "Services was not called")
ctx := fakeServiceBroker.ServicesArgsForCall(0)
Expect(ctx.Value(middlewares.CorrelationIDKey)).To(Not(BeNil()))
})
})
})
})
1 change: 0 additions & 1 deletion handlers/api_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const (
serviceIdMissingKey = "service-id-missing"
planIdMissingKey = "plan-id-missing"
unknownErrorKey = "unknown-error"
apiVersionInvalidKey = "broker-api-version-invalid"

bindingIDLogKey = "binding-id"
)
Expand Down
9 changes: 7 additions & 2 deletions handlers/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"net/http"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain"
Expand All @@ -20,9 +22,12 @@ func (h APIHandler) Bind(w http.ResponseWriter, req *http.Request) {
instanceID := vars["instance_id"]
bindingID := vars["binding_id"]

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(bindLogKey, lager.Data{
instanceIDLogKey: instanceID,
bindingIDLogKey: bindingID,
instanceIDLogKey: instanceID,
bindingIDLogKey: bindingID,
middlewares.CorrelationIDKey: correlationID,
})

version := getAPIVersion(req)
Expand Down
8 changes: 7 additions & 1 deletion handlers/deprovision.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package handlers
import (
"net/http"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain"
Expand All @@ -14,8 +16,12 @@ const deprovisionLogKey = "deprovision"
func (h APIHandler) Deprovision(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
instanceID := vars["instance_id"]

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(deprovisionLogKey, lager.Data{
instanceIDLogKey: instanceID,
instanceIDLogKey: instanceID,
middlewares.CorrelationIDKey: correlationID,
})

details := domain.DeprovisionDetails{
Expand Down
11 changes: 8 additions & 3 deletions handlers/get_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"errors"
"net/http"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain/apiresponses"
Expand All @@ -16,9 +18,12 @@ func (h APIHandler) GetBinding(w http.ResponseWriter, req *http.Request) {
instanceID := vars["instance_id"]
bindingID := vars["binding_id"]

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(getBindLogKey, lager.Data{
instanceIDLogKey: instanceID,
bindingIDLogKey: bindingID,
instanceIDLogKey: instanceID,
bindingIDLogKey: bindingID,
middlewares.CorrelationIDKey: correlationID,
})

version := getAPIVersion(req)
Expand All @@ -27,7 +32,7 @@ func (h APIHandler) GetBinding(w http.ResponseWriter, req *http.Request) {
h.respond(w, http.StatusPreconditionFailed, apiresponses.ErrorResponse{
Description: err.Error(),
})
logger.Error(apiVersionInvalidKey, err)
logger.Error(middlewares.ApiVersionInvalidKey, err)
return
}

Expand Down
9 changes: 7 additions & 2 deletions handlers/get_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"errors"
"net/http"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain/apiresponses"
Expand All @@ -15,8 +17,11 @@ func (h APIHandler) GetInstance(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
instanceID := vars["instance_id"]

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(getInstanceLogKey, lager.Data{
instanceIDLogKey: instanceID,
instanceIDLogKey: instanceID,
middlewares.CorrelationIDKey: correlationID,
})

version := getAPIVersion(req)
Expand All @@ -25,7 +30,7 @@ func (h APIHandler) GetInstance(w http.ResponseWriter, req *http.Request) {
h.respond(w, http.StatusPreconditionFailed, apiresponses.ErrorResponse{
Description: err.Error(),
})
logger.Error(apiVersionInvalidKey, err)
logger.Error(middlewares.ApiVersionInvalidKey, err)
return
}

Expand Down
9 changes: 7 additions & 2 deletions handlers/last_binding_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"errors"
"net/http"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain"
Expand All @@ -22,8 +24,11 @@ func (h APIHandler) LastBindingOperation(w http.ResponseWriter, req *http.Reques
OperationData: req.FormValue("operation"),
}

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(lastBindingOperationLogKey, lager.Data{
instanceIDLogKey: instanceID,
instanceIDLogKey: instanceID,
middlewares.CorrelationIDKey: correlationID,
})

version := getAPIVersion(req)
Expand All @@ -32,7 +37,7 @@ func (h APIHandler) LastBindingOperation(w http.ResponseWriter, req *http.Reques
h.respond(w, http.StatusPreconditionFailed, apiresponses.ErrorResponse{
Description: err.Error(),
})
logger.Error(apiVersionInvalidKey, err)
logger.Error(middlewares.ApiVersionInvalidKey, err)
return
}

Expand Down
12 changes: 9 additions & 3 deletions handlers/last_binding_operation_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package handlers_test

import (
"code.cloudfoundry.org/lager"
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand All @@ -13,8 +19,6 @@ import (
"github.com/pivotal-cf/brokerapi/handlers"
"github.com/pivotal-cf/brokerapi/handlers/fakes"
"github.com/pkg/errors"
"net/http"
"net/url"
)

var _ = Describe("LastBindingOperation", func() {
Expand Down Expand Up @@ -135,5 +139,7 @@ func newRequest(instanceID, bindingID, planID, serviceID, operation string) *htt
request.Form.Add("service_id", serviceID)
request.Form.Add("operation", operation)

newCtx := context.WithValue(request.Context(), middlewares.CorrelationIDKey, "fake-correlation-id")
request = request.WithContext(newCtx)
return request
}
7 changes: 6 additions & 1 deletion handlers/last_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package handlers
import (
"net/http"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain"
Expand All @@ -20,8 +22,11 @@ func (h APIHandler) LastOperation(w http.ResponseWriter, req *http.Request) {
OperationData: req.FormValue("operation"),
}

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(lastOperationLogKey, lager.Data{
instanceIDLogKey: instanceID,
instanceIDLogKey: instanceID,
middlewares.CorrelationIDKey: correlationID,
})

logger.Info("starting-check-for-operation")
Expand Down
7 changes: 6 additions & 1 deletion handlers/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"net/http"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain"
Expand All @@ -24,8 +26,11 @@ func (h *APIHandler) Provision(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
instanceID := vars["instance_id"]

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(provisionLogKey, lager.Data{
instanceIDLogKey: instanceID,
instanceIDLogKey: instanceID,
middlewares.CorrelationIDKey: correlationID,
})

var details domain.ProvisionDetails
Expand Down
10 changes: 7 additions & 3 deletions handlers/unbind.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain"
"github.com/pivotal-cf/brokerapi/domain/apiresponses"
"github.com/pivotal-cf/brokerapi/middlewares"
)

const unbindLogKey = "unbind"
Expand All @@ -17,9 +18,12 @@ func (h APIHandler) Unbind(w http.ResponseWriter, req *http.Request) {
instanceID := vars["instance_id"]
bindingID := vars["binding_id"]

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(unbindLogKey, lager.Data{
instanceIDLogKey: instanceID,
bindingIDLogKey: bindingID,
instanceIDLogKey: instanceID,
bindingIDLogKey: bindingID,
middlewares.CorrelationIDKey: correlationID,
})

version := getAPIVersion(req)
Expand All @@ -29,7 +33,7 @@ func (h APIHandler) Unbind(w http.ResponseWriter, req *http.Request) {
h.respond(w, http.StatusUnprocessableEntity, apiresponses.ErrorResponse{
Description: err.Error(),
})
logger.Error(apiVersionInvalidKey, err)
logger.Error(middlewares.ApiVersionInvalidKey, err)
return
}
details := domain.UnbindDetails{
Expand Down
7 changes: 6 additions & 1 deletion handlers/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"net/http"
"strconv"

"github.com/pivotal-cf/brokerapi/middlewares"

"code.cloudfoundry.org/lager"
"github.com/gorilla/mux"
"github.com/pivotal-cf/brokerapi/domain"
Expand All @@ -17,8 +19,11 @@ func (h APIHandler) Update(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
instanceID := vars["instance_id"]

correlationID := req.Context().Value(middlewares.CorrelationIDKey).(string)

logger := h.logger.Session(updateLogKey, lager.Data{
instanceIDLogKey: instanceID,
instanceIDLogKey: instanceID,
middlewares.CorrelationIDKey: correlationID,
})

var details domain.UpdateDetails
Expand Down
Loading

0 comments on commit cf3240c

Please sign in to comment.