Adding healthcheck endpoint for sms 49/45949/1
authorKiran Kamineni <kiran.k.kamineni@intel.com>
Thu, 3 May 2018 18:27:59 +0000 (11:27 -0700)
committerKiran Kamineni <kiran.k.kamineni@intel.com>
Thu, 3 May 2018 18:28:04 +0000 (11:28 -0700)
Added a new url endpoint for healthcheck
/v1/sms/healthcheck which will run a simple
operation on the backend and return OK or error

Issue-ID: AAF-263
Change-Id: Idbfaeff50e6a8c36fa25c081a3b1c6169535ea36
Signed-off-by: Kiran Kamineni <kiran.k.kamineni@intel.com>
sms-service/src/sms/handler/handler.go
sms-service/src/sms/handler/handler_test.go
sms-service/src/sms/log/logger.go

index 7ce9e01..805f7a8 100644 (file)
@@ -21,6 +21,7 @@ import (
        "github.com/gorilla/mux"
        "net/http"
 
+       uuid "github.com/hashicorp/go-uuid"
        smsbackend "sms/backend"
        smslogger "sms/log"
 )
@@ -210,6 +211,7 @@ func (h handler) unsealHandler(w http.ResponseWriter, r *http.Request) {
 // with their PGP public keys that are then used by sms for backend
 // initialization
 func (h handler) registerHandler(w http.ResponseWriter, r *http.Request) {
+
        // Get shards to be used for unseal
        type registerStruct struct {
                PGPKey   string `json:"pgpkey"`
@@ -246,6 +248,39 @@ func (h handler) registerHandler(w http.ResponseWriter, r *http.Request) {
        }
 }
 
+// healthCheckHandler runs a few commands on the backend and returns
+// OK or not depending on the status of the backend
+func (h handler) healthCheckHandler(w http.ResponseWriter, r *http.Request) {
+
+       sealed, err := h.secretBackend.GetStatus()
+       if smslogger.CheckError(err, "HealthCheck") != nil {
+               http.Error(w, err.Error(), http.StatusInternalServerError)
+               return
+       }
+
+       // backend is sealed
+       if sealed == true {
+               http.Error(w, "Secret Backend is not ready for operations", http.StatusInternalServerError)
+               return
+       }
+
+       // backend is not sealed
+       dname, _ := uuid.GenerateUUID()
+       _, err = h.secretBackend.CreateSecretDomain(dname)
+       if smslogger.CheckError(err, "HealthCheck Create Domain") != nil {
+               http.Error(w, err.Error(), http.StatusInternalServerError)
+               return
+       }
+
+       err = h.secretBackend.DeleteSecretDomain(dname)
+       if smslogger.CheckError(err, "HealthCheck Delete Domain") != nil {
+               http.Error(w, err.Error(), http.StatusInternalServerError)
+               return
+       }
+
+       w.WriteHeader(http.StatusOK)
+}
+
 // CreateRouter returns an http.Handler for the registered URLs
 // Takes an interface implementation as input
 func CreateRouter(b smsbackend.SecretBackend) http.Handler {
@@ -262,6 +297,7 @@ func CreateRouter(b smsbackend.SecretBackend) http.Handler {
        router.HandleFunc("/v1/sms/quorum/unseal", h.unsealHandler).Methods("POST")
        router.HandleFunc("/v1/sms/quorum/register", h.registerHandler).Methods("POST")
 
+       router.HandleFunc("/v1/sms/healthcheck", h.healthCheckHandler).Methods("GET")
        router.HandleFunc("/v1/sms/domain", h.createSecretDomainHandler).Methods("POST")
        router.HandleFunc("/v1/sms/domain/{domName}", h.deleteSecretDomainHandler).Methods("DELETE")
 
index c1e55ed..58d687d 100644 (file)
@@ -40,7 +40,7 @@ func (b *TestBackend) Init() error {
 }
 
 func (b *TestBackend) GetStatus() (bool, error) {
-       return true, nil
+       return false, nil
 }
 
 func (b *TestBackend) Unseal(shard string) error {
@@ -111,19 +111,21 @@ func TestStatusHandler(t *testing.T) {
                        ret, http.StatusOK)
        }
 
+       //Check returned body
        expected := struct {
                Seal bool `json:"sealstatus"`
        }{}
        got := struct {
                Seal bool `json:"sealstatus"`
        }{}
-       expectedStr := strings.NewReader(`{"sealstatus":true}`)
+       gotstr := rr.Body.String()
+       expectedStr := strings.NewReader(`{"sealstatus":false}`)
        json.NewDecoder(expectedStr).Decode(&expected)
        json.NewDecoder(rr.Body).Decode(&got)
 
        if reflect.DeepEqual(expected, got) == false {
-               t.Errorf("statusHandler returned unexpected body: got %v vs %v",
-                       rr.Body.String(), expectedStr)
+               t.Errorf("statusHandler returned unexpected body: got %s vs %v",
+                       gotstr, expectedStr)
        }
 }
 
@@ -149,6 +151,7 @@ func TestRegisterHandler(t *testing.T) {
                        ret, http.StatusOK)
        }
 
+       //Check returned body
        expected := struct {
                Shard string `json:"shard"`
        }{
@@ -202,6 +205,7 @@ func TestCreateSecretDomainHandler(t *testing.T) {
                t.Errorf("Expected statusCreated return code. Got: %v", rr.Code)
        }
 
+       //Check returned body
        expected := smsbackend.SecretDomain{
                UUID: "123e4567-e89b-12d3-a456-426655440000",
                Name: "testdomain",
@@ -285,6 +289,7 @@ func TestGetSecretHandler(t *testing.T) {
                t.Errorf("Expected statusCreated return code. Got: %v", rr.Code)
        }
 
+       //Check returned body
        expected := smsbackend.Secret{
                Name: "testsecret",
                Values: map[string]interface{}{
@@ -316,6 +321,7 @@ func TestListSecretHandler(t *testing.T) {
                t.Errorf("Expected statusCreated return code. Got: %v", rr.Code)
        }
 
+       //Check returned body
        var expected = struct {
                SecretNames []string `json:"secretnames"`
        }{
@@ -333,3 +339,22 @@ func TestListSecretHandler(t *testing.T) {
                        " expected: %v", got, expected)
        }
 }
+
+func TestHealthCheckHandler(t *testing.T) {
+       req, err := http.NewRequest("GET", "/v1/sms/healthcheck", nil)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       rr := httptest.NewRecorder()
+       hr := http.HandlerFunc(h.healthCheckHandler)
+
+       hr.ServeHTTP(rr, req)
+
+       ret := rr.Code
+       if ret != http.StatusOK {
+               t.Errorf("healthCheckHandler returned wrong status code: %v vs %v",
+                       ret, http.StatusOK)
+               t.Errorf("%s", rr.Body.String())
+       }
+}
index 660f1ce..15207fe 100644 (file)
@@ -82,7 +82,7 @@ func WriteInfo(msg string) {
 }
 
 //CheckError is a helper function to reduce
-//repitition of error checkign blocks of code
+//repetition of error checking blocks of code
 func CheckError(err error, topic string) error {
        if err != nil {
                msg := topic + ": " + err.Error()