Passed
Pull Request — master (#1064)
by
unknown
02:13
created

servers.*SchemaServer.List   A

Complexity

Conditions 3

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 17
nop 2
dl 0
loc 22
rs 9.55
c 0
b 0
f 0
1
package servers
2
3
import (
4
	"log/slog"
5
6
	"github.com/rs/xid"
7
	"google.golang.org/grpc/status"
8
9
	otelCodes "go.opentelemetry.io/otel/codes"
10
	"golang.org/x/net/context"
11
12
	"github.com/Permify/permify/internal/storage"
13
	"github.com/Permify/permify/pkg/database"
14
	"github.com/Permify/permify/pkg/dsl/compiler"
15
	"github.com/Permify/permify/pkg/dsl/parser"
16
	v1 "github.com/Permify/permify/pkg/pb/base/v1"
17
)
18
19
// SchemaServer - Structure for Schema Server
20
type SchemaServer struct {
21
	v1.UnimplementedSchemaServer
22
23
	sw storage.SchemaWriter
24
	sr storage.SchemaReader
25
}
26
27
// NewSchemaServer - Creates new Schema Server
28
func NewSchemaServer(sw storage.SchemaWriter, sr storage.SchemaReader) *SchemaServer {
29
	return &SchemaServer{
30
		sw: sw,
31
		sr: sr,
32
	}
33
}
34
35
// Write - Configure new Permify Schema to Permify
36
func (r *SchemaServer) Write(ctx context.Context, request *v1.SchemaWriteRequest) (*v1.SchemaWriteResponse, error) {
37
	ctx, span := tracer.Start(ctx, "schemas.write")
38
	defer span.End()
39
40
	sch, err := parser.NewParser(request.GetSchema()).Parse()
41
	if err != nil {
42
		span.RecordError(err)
43
		span.SetStatus(otelCodes.Error, err.Error())
44
		return nil, status.Error(GetStatus(err), err.Error())
45
	}
46
47
	_, _, err = compiler.NewCompiler(true, sch).Compile()
48
	if err != nil {
49
		span.RecordError(err)
50
		span.SetStatus(otelCodes.Error, err.Error())
51
		return nil, status.Error(GetStatus(err), err.Error())
52
	}
53
54
	version := xid.New().String()
55
56
	cnf := make([]storage.SchemaDefinition, 0, len(sch.Statements))
57
	for _, st := range sch.Statements {
58
		cnf = append(cnf, storage.SchemaDefinition{
59
			TenantID:             request.GetTenantId(),
60
			Version:              version,
61
			Name:                 st.GetName(),
62
			SerializedDefinition: []byte(st.String()),
63
		})
64
	}
65
66
	err = r.sw.WriteSchema(ctx, cnf)
67
	if err != nil {
68
		span.RecordError(err)
69
		span.SetStatus(otelCodes.Error, err.Error())
70
		slog.Error(err.Error())
71
		return nil, status.Error(GetStatus(err), err.Error())
72
	}
73
74
	return &v1.SchemaWriteResponse{
75
		SchemaVersion: version,
76
	}, nil
77
}
78
79
// Read - Read created Schema
80
func (r *SchemaServer) Read(ctx context.Context, request *v1.SchemaReadRequest) (*v1.SchemaReadResponse, error) {
81
	ctx, span := tracer.Start(ctx, "schemas.read")
82
	defer span.End()
83
84
	version := request.GetMetadata().GetSchemaVersion()
85
	if version == "" {
86
		ver, err := r.sr.HeadVersion(ctx, request.GetTenantId())
87
		if err != nil {
88
			return nil, status.Error(GetStatus(err), err.Error())
89
		}
90
		version = ver
91
	}
92
93
	response, err := r.sr.ReadSchema(ctx, request.GetTenantId(), version)
94
	if err != nil {
95
		span.RecordError(err)
96
		span.SetStatus(otelCodes.Error, err.Error())
97
		slog.Error(err.Error())
98
		return nil, status.Error(GetStatus(err), err.Error())
99
	}
100
101
	return &v1.SchemaReadResponse{
102
		Schema: response,
103
	}, nil
104
}
105
106
// List - List Schemas
107
func (r *SchemaServer) List(ctx context.Context, request *v1.SchemaListRequest) (*v1.SchemaListResponse, error) {
108
	ctx, span := tracer.Start(ctx, "schemas.list")
109
	defer span.End()
110
111
	schemas, ct, err := r.sr.ListSchemas(ctx, request.GetTenantId(), database.NewPagination(database.Size(request.GetPageSize()), database.Token(request.GetContinuousToken())))
112
	if err != nil {
113
		span.RecordError(err)
114
		span.SetStatus(otelCodes.Error, err.Error())
115
		slog.Error(err.Error())
116
		return nil, status.Error(GetStatus(err), err.Error())
117
	}
118
119
	head, err := r.sr.HeadVersion(ctx, request.GetTenantId())
120
	if err != nil {
121
		return nil, status.Error(GetStatus(err), err.Error())
122
	}
123
124
	return &v1.SchemaListResponse{
125
		Head: head,
126
		Schemas: schemas,
127
		ContinuousToken: ct.String(),
128
	}, nil
129
}