Skip to content
This repository has been archived by the owner on Sep 16, 2024. It is now read-only.

Commit

Permalink
refactor: clarify init steps
Browse files Browse the repository at this point in the history
Signed-off-by: thxCode <[email protected]>
  • Loading branch information
thxCode authored and alexcodelf committed Aug 15, 2023
1 parent 40dd761 commit d53a6ef
Show file tree
Hide file tree
Showing 15 changed files with 131 additions and 52 deletions.
59 changes: 35 additions & 24 deletions pkg/server/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ import (
"context"
"database/sql"
"fmt"
"path/filepath"
"reflect"
"runtime"
"strings"

"k8s.io/client-go/rest"

"github.com/seal-io/seal/pkg/cache"
"github.com/seal-io/seal/pkg/dao/migration"
"github.com/seal-io/seal/pkg/dao/model"
"github.com/seal-io/seal/utils/strs"
)

type initOptions struct {
Expand All @@ -28,39 +33,45 @@ func (r *Server) init(ctx context.Context, opts initOptions) error {
return fmt.Errorf("error creating model schemas: %w", err)
}

// Initialize critical resources.
type initor struct {
name string
init func(context.Context, initOptions) error
// Initialize data for system.
inits := []initiation{
r.setupSettings,
r.initConfigs,
r.configureModelClient,
r.registerMetricCollectors,
r.registerHealthCheckers,
r.startBackgroundJobs,
r.setupBusSubscribers,
}

inits := []initor{
{name: "settings", init: r.initSettings},
{name: "configs", init: r.initConfigs},
{name: "dispatches", init: r.initDispatches},
{name: "metrics", init: r.initMetrics},
{name: "healthCheckers", init: r.initHealthCheckers},
{name: "backgroundJobs", init: r.initBackgroundJobs},
{name: "subscribers", init: r.initSubscribers},
{name: "rbac", init: r.initRbac},
}
inits = append(inits,
initor{name: "catalog", init: r.initCatalog},
initor{name: "perspective", init: r.initPerspectives},
initor{name: "projects", init: r.initProjects},
)

if r.EnableAuthn {
inits = append(inits,
initor{name: "casdoor", init: r.initCasdoor},
r.configureCasdoor,
)
}

// Initialize data for user.
inits = append(inits,
r.createBuiltinRbac,
r.createBuiltinCatalogs,
r.createBuiltinPerspectives,
r.createBuiltinProjects,
)

for i := range inits {
if err = inits[i].init(ctx, opts); err != nil {
return fmt.Errorf("%s: %w", inits[i].name, err)
if err = inits[i](ctx, opts); err != nil {
return fmt.Errorf("failed to %s: %w",
loadInitiationName(inits[i]), err)
}
}

return nil
}

type initiation func(context.Context, initOptions) error

func loadInitiationName(i initiation) string {
n := runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
n = strings.TrimPrefix(strings.TrimSuffix(filepath.Ext(n), "-fm"), ".")

return strs.Decamelize(n, true)
}
3 changes: 2 additions & 1 deletion pkg/server/init_background_jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import (
"github.com/seal-io/seal/pkg/settings"
)

func (r *Server) initBackgroundJobs(ctx context.Context, opts initOptions) error {
// startBackgroundJobs starts the background jobs by Cron Expression to do something periodically.
func (r *Server) startBackgroundJobs(ctx context.Context, opts initOptions) error {
cs := cron.JobCreators{
settings.ConnectorCostCollectCronExpr.Name(): buildConnectorCostCollectJobCreator(opts.ModelClient),
settings.ConnectorStatusSyncCronExpr.Name(): buildConnectorStatusSyncJobCreator(opts.ModelClient),
Expand Down
14 changes: 14 additions & 0 deletions pkg/server/init_bus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package server

import (
"context"

"github.com/seal-io/seal/pkg/bus"
)

// setupBusSubscribers launches the synchronous subscribers provided by the bus.
func (r *Server) setupBusSubscribers(ctx context.Context, opts initOptions) error {
return bus.Setup(ctx, bus.SetupOptions{
ModelClient: opts.ModelClient,
})
}
7 changes: 4 additions & 3 deletions pkg/server/init_casdoor.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
"github.com/seal-io/seal/utils/strs"
)

func (r *Server) initCasdoor(ctx context.Context, opts initOptions) error {
// configureCasdoor initializes the builtin Casdoor application and builtin admin user.
func (r *Server) configureCasdoor(ctx context.Context, opts initOptions) error {
// Short circuit for none first-login.
var cred casdoor.ApplicationCredential
if err := settings.CasdoorCred.ValueJSONUnmarshal(ctx, opts.ModelClient, &cred); err != nil {
Expand Down Expand Up @@ -50,7 +51,7 @@ func (r *Server) initCasdoor(ctx context.Context, opts initOptions) error {

defer func() {
// NB(thxCode): revert the token if occurs error,
// make the `initCasdoor` idempotent.
// make the `configureCasdoor` idempotent.
if err != nil {
_ = casdoor.DeleteToken(context.Background(), cred.ClientID, cred.ClientSecret,
token.Owner, token.Name)
Expand All @@ -71,7 +72,7 @@ func (r *Server) initCasdoor(ctx context.Context, opts initOptions) error {

defer func() {
// NB(thxCode): revert the password if occurs error,
// make the `initCasdoor` idempotent.
// make the `configureCasdoor` idempotent.
if err != nil {
_ = casdoor.UpdateUserPassword(ctx, cred.ClientID, cred.ClientSecret,
casdoor.BuiltinOrg, casdoor.BuiltinAdmin,
Expand Down
3 changes: 2 additions & 1 deletion pkg/server/init_catalog.go → pkg/server/init_catalogs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
"github.com/seal-io/seal/pkg/dao/types/status"
)

func (r *Server) initCatalog(ctx context.Context, opts initOptions) error {
// createBuiltinCatalogs creates the built-in Catalog resources.
func (r *Server) createBuiltinCatalogs(ctx context.Context, opts initOptions) error {
builtin := pkgcatalog.BuiltinCatalog()

c, err := opts.ModelClient.Catalogs().Query().
Expand Down
2 changes: 2 additions & 0 deletions pkg/server/init_configs.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"github.com/seal-io/seal/utils/strs"
)

// initConfigs configures the system singleton instances at initialization phase,
// like caches, encryption, auths, etc.
func (r *Server) initConfigs(ctx context.Context, opts initOptions) (err error) {
err = configureCaches(ctx, opts.CacheDriver)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion pkg/server/init_health_checkers.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import (
"github.com/seal-io/seal/utils/gopool"
)

func (r *Server) initHealthCheckers(ctx context.Context, opts initOptions) error {
// registerHealthCheckers registers the health checkers into the global health registry.
func (r *Server) registerHealthCheckers(ctx context.Context, opts initOptions) error {
k8sClientSet, err := kubernetes.NewForConfig(opts.K8sConfig)
if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
"github.com/seal-io/seal/utils/gopool"
)

func (r *Server) initMetrics(ctx context.Context, opts initOptions) error {
// registerMetricCollectors registers the metric collectors into the global metric registry.
func (r *Server) registerMetricCollectors(ctx context.Context, opts initOptions) error {
cs := metric.Collectors{
database.NewStatsCollectorWith(opts.DatabaseDriver),
gopool.NewStatsCollector(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
"github.com/seal-io/seal/utils/log"
)

func (r *Server) initDispatches(ctx context.Context, opts initOptions) error {
// configureModelClient enables the mutation hooks or interceptors for the model.Client.
func (r *Server) configureModelClient(ctx context.Context, opts initOptions) error {
opts.ModelClient.Use(
dispatchModelChange,
)
Expand Down
3 changes: 2 additions & 1 deletion pkg/server/init_perspectives.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
"github.com/seal-io/seal/pkg/dao/model"
)

func (r *Server) initPerspectives(ctx context.Context, opts initOptions) error {
// createBuiltinPerspectives creates the built-in Perspective resources.
func (r *Server) createBuiltinPerspectives(ctx context.Context, opts initOptions) error {
builtin := []*model.Perspective{
perspectiveAll(),
perspectiveCluster(),
Expand Down
3 changes: 2 additions & 1 deletion pkg/server/init_projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
"github.com/seal-io/seal/pkg/dao/types"
)

func (r *Server) initProjects(ctx context.Context, opts initOptions) error {
// createBuiltinProjects creates the built-in Project resources.
func (r *Server) createBuiltinProjects(ctx context.Context, opts initOptions) error {
mc := opts.ModelClient

// Get system admin user.
Expand Down
3 changes: 2 additions & 1 deletion pkg/server/init_rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
"github.com/seal-io/seal/pkg/dao/types"
)

func (r *Server) initRbac(ctx context.Context, opts initOptions) (err error) {
// createBuiltinRbac creates the built-in RBAC resources.
func (r *Server) createBuiltinRbac(ctx context.Context, opts initOptions) (err error) {
err = createRoles(ctx, opts.ModelClient)
if err != nil {
return
Expand Down
4 changes: 3 additions & 1 deletion pkg/server/init_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (
"github.com/seal-io/seal/pkg/settings"
)

func (r *Server) initSettings(ctx context.Context, opts initOptions) error {
// setupSettings creates the global settings into the database,
// it must be the first step to be executed at initialization.
func (r *Server) setupSettings(ctx context.Context, opts initOptions) error {
return opts.ModelClient.Settings().CreateBulk().
Set(settings.All()...).
OnConflictColumns(setting.FieldName).
Expand Down
16 changes: 0 additions & 16 deletions pkg/server/init_subscribers.go

This file was deleted.

57 changes: 57 additions & 0 deletions pkg/server/init_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package server

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
)

func privateInitiationName(context.Context, initOptions) error {
panic("test only")
}

func PublicInitiationName(context.Context, initOptions) error {
panic("test only")
}

type _X struct{}

func (_X) StructInitiationName(context.Context, initOptions) error {
panic("test only")
}

func Test_loadInitiationName(t *testing.T) {
anonymityInitiationName := func(context.Context, initOptions) error {
panic("test only")
}

testCases := []struct {
given initiation
expected string
}{
{
given: privateInitiationName,
expected: "private initiation name",
},
{
given: PublicInitiationName,
expected: "public initiation name",
},
{
given: _X{}.StructInitiationName,
expected: "struct initiation name",
},
{
given: anonymityInitiationName,
expected: "func1",
},
}

for _, tc := range testCases {
t.Run(tc.expected, func(t *testing.T) {
actual := loadInitiationName(tc.given)
assert.Equal(t, tc.expected, actual)
})
}
}

0 comments on commit d53a6ef

Please sign in to comment.