-
Notifications
You must be signed in to change notification settings - Fork 19
/
spec.go
88 lines (77 loc) · 3.39 KB
/
spec.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright 2024 Fraunhofer AISEC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// $$\ $$\ $$\ $$\
// $$ | $$ |\__| $$ |
// $$$$$$$\ $$ | $$$$$$\ $$\ $$\ $$$$$$$ |$$\ $$$$$$\ $$$$$$\ $$$$$$\
// $$ _____|$$ |$$ __$$\ $$ | $$ |$$ __$$ |$$ |\_$$ _| $$ __$$\ $$ __$$\
// $$ / $$ |$$ / $$ |$$ | $$ |$$ / $$ |$$ | $$ | $$ / $$ |$$ | \__|
// $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$\ $$ | $$ |$$ |
// \$$$$$$\ $$ |\$$$$$ |\$$$$$ |\$$$$$$ |$$ | \$$$ |\$$$$$ |$$ |
// \_______|\__| \______/ \______/ \_______|\__| \____/ \______/ \__|
//
// This file is part of Clouditor Community Edition.
package launcher
import (
"clouditor.io/clouditor/v2/persistence"
"clouditor.io/clouditor/v2/server"
"clouditor.io/clouditor/v2/service"
)
// spec is a struct that implements [ServiceSpec]. We want to keep it unexported, because it needs to be generic to the
// type T, in order for the initialization and creation functions to work. But if we want to have a list of different
// specs, we cannot mix the generics, therefore we need to have the [ServiceSpec] interface.
type spec[T service.Service] struct {
// nsf is mandatory and contains the function to create the service.
nsf NewServiceFunc[T]
// wsf contains an optional [WithStorageFunc] that the service can use to use a persistance layer.
wsf WithStorageFunc[T]
// init contains an optional [ServiceInitFunc] that the service can use to initialize its self and return additional
// [server.StartGRPCServerOption] objects.
init ServiceInitFunc[T]
// opts contains additional [service.Option] options.
opts []service.Option[T]
}
func (s spec[T]) newService(db persistence.Storage) (svc T, grpcOpts []server.StartGRPCServerOption, err error) {
var opts = s.opts
// Append the WithStorageFunc (if its non-nil) to the specified service options.
if s.wsf != nil {
opts = append(opts, s.wsf(db))
}
// Create the service with the NewServiceFunc using the supplied server options
svc = s.nsf(opts...)
// Initialize the service using the ServiceInitFunc (if its non-nil). This returns a possible list of
// StartGRPCServerOptions that we need to return
if s.init != nil {
grpcOpts, err = s.init(svc)
}
if err != nil {
return *new(T), nil, err
}
return
}
func (s spec[T]) NewService(db persistence.Storage) (svc service.Service, grpcOpts []server.StartGRPCServerOption, err error) {
return s.newService(db)
}
// ServiceSpec is an interface we need because of generics foo.
type ServiceSpec interface {
NewService(db persistence.Storage) (svc service.Service, grpcOpts []server.StartGRPCServerOption, err error)
}
func NewServiceSpec[T service.Service](nsf NewServiceFunc[T], wsf WithStorageFunc[T], init ServiceInitFunc[T], opts ...service.Option[T]) ServiceSpec {
return &spec[T]{
nsf: nsf,
wsf: wsf,
init: init,
opts: opts,
}
}