server/health: add health check handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
14026d15be
commit
ce4c96ae0a
3
server/generate.go
Normal file
3
server/generate.go
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
//go:generate protoc -I./health -I../ -I/home/vtolstov/.cache/go-path/pkg/mod/github.com/unistack-org/micro-proto@v0.0.1 --micro_out=components=micro|http|server,standalone=false,debug=true,paths=source_relative:./health health/health.proto
|
87
server/health/health.go
Normal file
87
server/health/health.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/unistack-org/micro/v3/codec"
|
||||||
|
"github.com/unistack-org/micro/v3/errors"
|
||||||
|
"github.com/unistack-org/micro/v3/server"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// guard to fail early
|
||||||
|
_ HealthServer = &handler{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type handler struct {
|
||||||
|
server server.Server
|
||||||
|
opts Options
|
||||||
|
}
|
||||||
|
|
||||||
|
type CheckFunc func(context.Context) error
|
||||||
|
|
||||||
|
type Option func(*Options)
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
LiveChecks []CheckFunc
|
||||||
|
ReadyChecks []CheckFunc
|
||||||
|
Version string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func LiveChecks(fns ...CheckFunc) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.LiveChecks = append(o.LiveChecks, fns...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadyChecks(fns ...CheckFunc) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.ReadyChecks = append(o.ReadyChecks, fns...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Name(name string) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Version(version string) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Version = version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHealth(opts ...Option) *handler {
|
||||||
|
options := Options{}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
return &handler{opts: options}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
|
||||||
|
var err error
|
||||||
|
for _, fn := range h.opts.LiveChecks {
|
||||||
|
if err = fn(ctx); err != nil {
|
||||||
|
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
|
||||||
|
var err error
|
||||||
|
for _, fn := range h.opts.ReadyChecks {
|
||||||
|
if err = fn(ctx); err != nil {
|
||||||
|
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
|
||||||
|
rsp.Data = []byte(h.opts.Version)
|
||||||
|
return nil
|
||||||
|
}
|
62
server/health/health.proto
Normal file
62
server/health/health.proto
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package health;
|
||||||
|
option go_package = "github.com/unistack-org/micro/v3/server/health;pb";
|
||||||
|
|
||||||
|
import "api/annotations.proto";
|
||||||
|
import "openapiv2/annotations.proto";
|
||||||
|
import "codec/frame.proto";
|
||||||
|
|
||||||
|
service Health {
|
||||||
|
rpc Live(micro.codec.Frame) returns (micro.codec.Frame) {
|
||||||
|
option (micro.openapiv2.openapiv2_operation) = {
|
||||||
|
operation_id: "Live";
|
||||||
|
responses: {
|
||||||
|
key: "default";
|
||||||
|
value: {
|
||||||
|
description: "Error response";
|
||||||
|
schema: {
|
||||||
|
json_schema: {
|
||||||
|
ref: "micro.codec.Frame";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
option (micro.api.http) = { get: "/live"; };
|
||||||
|
};
|
||||||
|
rpc Ready(micro.codec.Frame) returns (micro.codec.Frame) {
|
||||||
|
option (micro.openapiv2.openapiv2_operation) = {
|
||||||
|
operation_id: "Ready";
|
||||||
|
responses: {
|
||||||
|
key: "default";
|
||||||
|
value: {
|
||||||
|
description: "Error response";
|
||||||
|
schema: {
|
||||||
|
json_schema: {
|
||||||
|
ref: "micro.codec.Frame";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
option (micro.api.http) = { get: "/ready"; };
|
||||||
|
};
|
||||||
|
rpc Version(micro.codec.Frame) returns (micro.codec.Frame) {
|
||||||
|
option (micro.openapiv2.openapiv2_operation) = {
|
||||||
|
operation_id: "Version";
|
||||||
|
responses: {
|
||||||
|
key: "default";
|
||||||
|
value: {
|
||||||
|
description: "Error response";
|
||||||
|
schema: {
|
||||||
|
json_schema: {
|
||||||
|
ref: "micro.codec.Frame";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
option (micro.api.http) = { get: "/version"; };
|
||||||
|
};
|
||||||
|
};
|
38
server/health/health_micro.pb.go
Normal file
38
server/health/health_micro.pb.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Code generated by protoc-gen-micro
|
||||||
|
// source: health.proto
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
api "github.com/unistack-org/micro/v3/api"
|
||||||
|
codec "github.com/unistack-org/micro/v3/codec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewHealthEndpoints() []*api.Endpoint {
|
||||||
|
return []*api.Endpoint{
|
||||||
|
&api.Endpoint{
|
||||||
|
Name: "Health.Live",
|
||||||
|
Path: []string{"/live"},
|
||||||
|
Method: []string{"GET"},
|
||||||
|
Handler: "rpc",
|
||||||
|
},
|
||||||
|
&api.Endpoint{
|
||||||
|
Name: "Health.Ready",
|
||||||
|
Path: []string{"/ready"},
|
||||||
|
Method: []string{"GET"},
|
||||||
|
Handler: "rpc",
|
||||||
|
},
|
||||||
|
&api.Endpoint{
|
||||||
|
Name: "Health.Version",
|
||||||
|
Path: []string{"/version"},
|
||||||
|
Method: []string{"GET"},
|
||||||
|
Handler: "rpc",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HealthServer interface {
|
||||||
|
Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
|
||||||
|
Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
|
||||||
|
Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
|
||||||
|
}
|
43
server/health/health_micro_http.pb.go
Normal file
43
server/health/health_micro_http.pb.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Code generated by protoc-gen-micro
|
||||||
|
// source: health.proto
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
api "github.com/unistack-org/micro/v3/api"
|
||||||
|
codec "github.com/unistack-org/micro/v3/codec"
|
||||||
|
server "github.com/unistack-org/micro/v3/server"
|
||||||
|
)
|
||||||
|
|
||||||
|
type healthServer struct {
|
||||||
|
HealthServer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *healthServer) Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
|
||||||
|
return h.HealthServer.Live(ctx, req, rsp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *healthServer) Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
|
||||||
|
return h.HealthServer.Ready(ctx, req, rsp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *healthServer) Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
|
||||||
|
return h.HealthServer.Version(ctx, req, rsp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterHealthServer(s server.Server, sh HealthServer, opts ...server.HandlerOption) error {
|
||||||
|
type health interface {
|
||||||
|
Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
|
||||||
|
Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
|
||||||
|
Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
|
||||||
|
}
|
||||||
|
type Health struct {
|
||||||
|
health
|
||||||
|
}
|
||||||
|
h := &healthServer{sh}
|
||||||
|
var nopts []server.HandlerOption
|
||||||
|
for _, endpoint := range NewHealthEndpoints() {
|
||||||
|
nopts = append(nopts, api.WithEndpoint(endpoint))
|
||||||
|
}
|
||||||
|
return s.Handle(s.NewHandler(&Health{h}, append(nopts, opts...)...))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user