Skip to content

Commit

Permalink
Generalize readyz logic
Browse files Browse the repository at this point in the history
Signed-off-by: Jonathan Marcantonio <[email protected]>
  • Loading branch information
lennysgarage committed Jun 26, 2024
1 parent 91b053e commit 9b887a1
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 38 deletions.
3 changes: 2 additions & 1 deletion cmd/kessel-relations/wire_gen.go

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

2 changes: 1 addition & 1 deletion internal/biz/biz.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ import (
)

// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewCreateRelationshipsUsecase, NewReadRelationshipsUsecase, NewDeleteRelationshipsUsecase, NewCheckUsecase, NewGetSubjectsUseCase)
var ProviderSet = wire.NewSet(NewCreateRelationshipsUsecase, NewReadRelationshipsUsecase, NewDeleteRelationshipsUsecase, NewCheckUsecase, NewGetSubjectsUseCase, NewIsBackendAvailableUsecase)
14 changes: 14 additions & 0 deletions internal/biz/relationships.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package biz

import (
"context"

v0 "github.com/project-kessel/relations-api/api/relations/v0"

"github.com/go-kratos/kratos/v2/log"
Expand All @@ -26,6 +27,7 @@ type ZanzibarRepository interface {
ReadRelationships(ctx context.Context, filter *v0.RelationTupleFilter, limit uint32, continuation ContinuationToken) (chan *RelationshipResult, chan error, error)
DeleteRelationships(context.Context, *v0.RelationTupleFilter) error
LookupSubjects(ctx context.Context, subjectType *v0.ObjectType, subject_relation, relation string, resource *v0.ObjectReference, limit uint32, continuation ContinuationToken) (chan *SubjectResult, chan error, error)
IsBackendAvaliable() error
}

type CheckUsecase struct {
Expand All @@ -41,6 +43,18 @@ func (rc *CheckUsecase) Check(ctx context.Context, check *v0.CheckRequest) (*v0.
return rc.repo.Check(ctx, check)
}

type IsBackendAvaliableUsecase struct {
repo ZanzibarRepository
}

func NewIsBackendAvailableUsecase(repo ZanzibarRepository) *IsBackendAvaliableUsecase {
return &IsBackendAvaliableUsecase{repo: repo}
}

func (rc *IsBackendAvaliableUsecase) IsBackendAvailable() error {
return rc.repo.IsBackendAvaliable()
}

type CreateRelationshipsUsecase struct {
repo ZanzibarRepository
log *log.Helper
Expand Down
1 change: 0 additions & 1 deletion internal/conf/conf.pb.go

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

32 changes: 27 additions & 5 deletions internal/data/spicedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@ import (
"context"
"errors"
"fmt"
apiV0 "github.com/project-kessel/relations-api/api/relations/v0"
"github.com/project-kessel/relations-api/internal/biz"
"github.com/project-kessel/relations-api/internal/conf"
"io"
"os"
"strings"
"time"

apiV0 "github.com/project-kessel/relations-api/api/relations/v0"
"github.com/project-kessel/relations-api/internal/biz"
"github.com/project-kessel/relations-api/internal/conf"

v1 "github.com/authzed/authzed-go/proto/authzed/api/v1"
"github.com/authzed/authzed-go/v1"
"github.com/authzed/grpcutil"
"github.com/go-kratos/kratos/v2/log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/health/grpc_health_v1"
)

// SpiceDbRepository .
type SpiceDbRepository struct {
client *authzed.Client
client *authzed.Client
healthClient grpc_health_v1.HealthClient
}

// NewSpiceDbRepository .
Expand Down Expand Up @@ -65,11 +69,21 @@ func NewSpiceDbRepository(c *conf.Data, logger log.Logger) (*SpiceDbRepository,
return nil, nil, fmt.Errorf("error creating spicedb client: %w", err)
}

// Create health client for readyz
conn, err := grpc.NewClient(
c.SpiceDb.Endpoint,
opts...,
)
if err != nil {
return nil, nil, fmt.Errorf("error creating grpc health client: %w", err)
}
healthClient := grpc_health_v1.NewHealthClient(conn)

cleanup := func() {
log.NewHelper(logger).Info("spicedb connection cleanup requested (nothing to clean up)")
}

return &SpiceDbRepository{client}, cleanup, nil
return &SpiceDbRepository{client, healthClient}, cleanup, nil
}

func (s *SpiceDbRepository) LookupSubjects(ctx context.Context, subject_type *apiV0.ObjectType, subject_relation, relation string, object *apiV0.ObjectReference, limit uint32, continuation biz.ContinuationToken) (chan *biz.SubjectResult, chan error, error) {
Expand Down Expand Up @@ -269,6 +283,14 @@ func (s *SpiceDbRepository) Check(ctx context.Context, check *apiV0.CheckRequest
return &apiV0.CheckResponse{Allowed: apiV0.CheckResponse_ALLOWED_FALSE}, nil
}

func (s *SpiceDbRepository) IsBackendAvaliable() error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err := s.healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{})
return err
}

func createSpiceDbRelationshipFilter(filter *apiV0.RelationTupleFilter) *v1.RelationshipFilter {
spiceDbRelationshipFilter := &v1.RelationshipFilter{
ResourceType: filter.GetResourceType(),
Expand Down
40 changes: 10 additions & 30 deletions internal/service/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,30 @@ package service

import (
"context"
"time"

pb "github.com/project-kessel/relations-api/api/health/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/health/grpc_health_v1"
"github.com/project-kessel/relations-api/internal/biz"
)

type HealthService struct {
pb.UnimplementedKesselHealthServer
backendUseCase *biz.IsBackendAvaliableUsecase
}

func NewHealthService() *HealthService {
return &HealthService{}
func NewHealthService(backendUsecase *biz.IsBackendAvaliableUsecase) *HealthService {
return &HealthService{
backendUseCase: backendUsecase,
}
}

func (s *HealthService) GetLivez(ctx context.Context, req *pb.GetLivezRequest) (*pb.GetLivezReply, error) {
return &pb.GetLivezReply{Status: "OK", Code: 200}, nil
}
func (s *HealthService) GetReadyz(ctx context.Context, req *pb.GetReadyzRequest) (*pb.GetReadyzReply, error) {
ready := checkSpiceDBReadyz()
if ready {
return &pb.GetReadyzReply{Status: "OK", Code: 200}, nil
}
return &pb.GetReadyzReply{Status: "Unavailable", Code: 503}, nil
}

func checkSpiceDBReadyz() bool {
conn, err := grpc.NewClient(
"spicedb:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
return false
}

client := grpc_health_v1.NewHealthClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

resp, err := client.Check(ctx, &grpc_health_v1.HealthCheckRequest{})
func (s *HealthService) GetReadyz(ctx context.Context, req *pb.GetReadyzRequest) (*pb.GetReadyzReply, error) {
err := s.backendUseCase.IsBackendAvailable()
if err != nil {
return false
return &pb.GetReadyzReply{Status: "Unavailable", Code: 503}, nil
}

return resp.Status == grpc_health_v1.HealthCheckResponse_SERVING
return &pb.GetReadyzReply{Status: "OK", Code: 200}, nil
}

0 comments on commit 9b887a1

Please sign in to comment.