health check (#115)

* health check

* modify as comment

* bug fix

* fix mispell
diff --git a/pkg/model/kv.go b/pkg/model/kv.go
index 42b1359..b002037 100644
--- a/pkg/model/kv.go
+++ b/pkg/model/kv.go
@@ -86,3 +86,10 @@
 	Data  []*DocResponseSingleKey `json:"data"`
 	Total int64                   `json:"total"`
 }
+
+//DocHealthCheck is response doc
+type DocHealthCheck struct {
+	Version   string `json:"version"`
+	Revision  string `json:"revision"`
+	Timestamp int64  `json:"timestamp"`
+}
diff --git a/server/resource/v1/history_resource.go b/server/resource/v1/history_resource.go
index 024feb7..32376c1 100644
--- a/server/resource/v1/history_resource.go
+++ b/server/resource/v1/history_resource.go
@@ -19,7 +19,10 @@
 
 import (
 	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/go-chassis/go-chassis/pkg/runtime"
 	"net/http"
+	"strconv"
+	"time"
 
 	"github.com/apache/servicecomb-kie/pkg/common"
 	"github.com/apache/servicecomb-kie/server/service"
@@ -72,6 +75,24 @@
 	}
 }
 
+//HealthCheck provider version info and time info
+func (r *HistoryResource) HealthCheck(context *restful.Context) {
+	domain := ReadDomain(context)
+	resp := &model.DocHealthCheck{}
+	latest, err := service.RevisionService.GetRevision(context.Ctx, domain.(string))
+	if err != nil {
+		WriteErrResponse(context, http.StatusInternalServerError, err.Error(), common.ContentTypeText)
+		return
+	}
+	resp.Revision = strconv.FormatInt(latest, 10)
+	resp.Version = runtime.Version
+	resp.Timestamp = time.Now().Unix()
+	err = writeResponse(context, resp)
+	if err != nil {
+		openlogging.Error(err.Error())
+	}
+}
+
 //URLPatterns defined config operations
 func (r *HistoryResource) URLPatterns() []restful.Route {
 	return []restful.Route{
@@ -92,5 +113,20 @@
 			Consumes: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
 			Produces: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
 		},
+		{
+			Method:       http.MethodGet,
+			Path:         "/v1/health",
+			ResourceFunc: r.HealthCheck,
+			FuncDesc:     "health check return version and revision",
+			Parameters:   []*restful.Parameters{},
+			Returns: []*restful.Returns{
+				{
+					Code:  http.StatusOK,
+					Model: model.DocHealthCheck{},
+				},
+			},
+			Consumes: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
+			Produces: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
+		},
 	}
 }
diff --git a/server/resource/v1/history_resource_test.go b/server/resource/v1/history_resource_test.go
index 07004c6..2a05a56 100644
--- a/server/resource/v1/history_resource_test.go
+++ b/server/resource/v1/history_resource_test.go
@@ -21,6 +21,7 @@
 	"encoding/json"
 	"fmt"
 	"github.com/apache/servicecomb-kie/pkg/model"
+	handler2 "github.com/apache/servicecomb-kie/server/handler"
 	v1 "github.com/apache/servicecomb-kie/server/resource/v1"
 	"github.com/apache/servicecomb-kie/server/service"
 	"github.com/go-chassis/go-chassis/core/common"
@@ -83,3 +84,21 @@
 	})
 
 }
+
+func Test_HeathCheck(t *testing.T) {
+	path := fmt.Sprintf("/v1/health")
+	r, _ := http.NewRequest("GET", path, nil)
+	noopH := &handler2.NoopAuthHandler{}
+	revision := &v1.HistoryResource{}
+	chain, _ := handler.CreateChain(common.Provider, "", noopH.Name())
+	c, err := restfultest.New(revision, chain)
+	assert.NoError(t, err)
+	resp := httptest.NewRecorder()
+	c.ServeHTTP(resp, r)
+	body, err := ioutil.ReadAll(resp.Body)
+	assert.NoError(t, err)
+	data := &model.DocHealthCheck{}
+	err = json.Unmarshal(body, &data)
+	assert.NoError(t, err)
+	assert.NotEmpty(t, data)
+}