Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve the rest api server: #20

Merged
merged 1 commit into from
Aug 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/api_docs/bundle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ paths:
description: generic error response
schema:
$ref: '#/definitions/error'
/flushcache:
get:
tags:
- app
operationId: getFlushCache
description: Flush the Github remote cache
responses:
'200':
description: cache flushed
default:
description: generic error response
schema:
$ref: '#/definitions/error'
definitions:
health:
type: object
Expand Down
7 changes: 7 additions & 0 deletions internal/goliac.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ type Goliac interface {

// to close the clone git repository (if you called LoadAndValidateGoliacOrganization)
Close()

// flush remote cache
FlushCache()
}

type GoliacImpl struct {
Expand Down Expand Up @@ -67,6 +70,10 @@ func NewGoliacImpl() (Goliac, error) {
}, nil
}

func (g *GoliacImpl) FlushCache() {
g.remote.FlushCache()
}

func (g *GoliacImpl) LoadAndValidateGoliacOrganization(repositoryUrl, branch string) error {
var errs []error
var warns []entity.Warning
Expand Down
21 changes: 20 additions & 1 deletion internal/goliac_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/Alayacare/goliac/swagger_gen/models"
"github.com/Alayacare/goliac/swagger_gen/restapi"
"github.com/Alayacare/goliac/swagger_gen/restapi/operations"
"github.com/Alayacare/goliac/swagger_gen/restapi/operations/app"
"github.com/Alayacare/goliac/swagger_gen/restapi/operations/health"
"github.com/go-openapi/loads"
"github.com/go-openapi/runtime/middleware"
Expand All @@ -26,16 +27,20 @@ type GoliacServer interface {
Serve()
GetLiveness(health.GetLivenessParams) middleware.Responder
GetReadiness(health.GetReadinessParams) middleware.Responder
GetFlushCache(app.GetFlushCacheParams) middleware.Responder
}

type GoliacServerImpl struct {
goliac Goliac
applyMutex gosync.Mutex
// when the server has finished to load the local configuration
ready bool
}

func NewGoliacServer(goliac Goliac) GoliacServer {
return &GoliacServerImpl{
goliac: goliac,
ready: false,
}
}

Expand All @@ -44,7 +49,17 @@ func (c *GoliacServerImpl) GetLiveness(params health.GetLivenessParams) middlewa
}

func (c *GoliacServerImpl) GetReadiness(params health.GetReadinessParams) middleware.Responder {
return health.NewGetLivenessOK().WithPayload(&models.Health{Status: "OK"})
if c.ready {
return health.NewGetLivenessOK().WithPayload(&models.Health{Status: "OK"})
} else {
message := "Not yet ready, loading local state"
return health.NewGetLivenessDefault(503).WithPayload(&models.Error{Message: &message})
}
}

func (c *GoliacServerImpl) GetFlushCache(app.GetFlushCacheParams) middleware.Responder {
c.goliac.FlushCache()
return app.NewGetFlushCacheOK()
}

func (g *GoliacServerImpl) Serve() {
Expand Down Expand Up @@ -137,6 +152,10 @@ func (g *GoliacServerImpl) serveApply() error {
if err != nil {
return fmt.Errorf("failed to load and validate: %s", err)
}

// we are ready (to give local state, and to sync with remote)
g.ready = true

u, err := url.Parse(repo)
if err != nil {
return fmt.Errorf("failed to parse %s: %v", repo, err)
Expand Down
115 changes: 67 additions & 48 deletions internal/sync/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,10 @@ func (g *GoliacRemoteImpl) FlushCache() {

func (g *GoliacRemoteImpl) RuleSets() map[string]*GithubRuleSet {
if time.Now().After(g.ttlExpireRulesets) {
err := g.Load()
rulesets, err := g.loadRulesets()
if err == nil {
rulesets, err := g.loadRulesets()
if err == nil {
g.rulesets = rulesets
g.ttlExpireRulesets = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}
g.rulesets = rulesets
g.ttlExpireRulesets = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}
}
return g.rulesets
Expand Down Expand Up @@ -164,6 +161,7 @@ func (g *GoliacRemoteImpl) Teams() map[string]*GithubTeam {
}
return g.teams
}

func (g *GoliacRemoteImpl) Repositories() map[string]*GithubRepository {
if time.Now().After(g.ttlExpireRepositories) {
repositories, repositoriesByRefIds, err := g.loadRepositories()
Expand All @@ -175,12 +173,21 @@ func (g *GoliacRemoteImpl) Repositories() map[string]*GithubRepository {
}
return g.repositories
}

func (g *GoliacRemoteImpl) TeamRepositories() map[string]map[string]*GithubTeamRepo {
if time.Now().After(g.ttlExpireTeamsRepos) {
teamsRepos, err := g.loadTeamReposConcurrently(config.Config.GithubConcurrentThreads)
if err == nil {
g.teamRepos = teamsRepos
g.ttlExpireTeamsRepos = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
if config.Config.GithubConcurrentThreads <= 1 {
teamsrepos, err := g.loadTeamReposNonConcurrently()
if err == nil {
g.teamRepos = teamsrepos
g.ttlExpireTeamsRepos = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}
} else {
teamsrepos, err := g.loadTeamReposConcurrently(config.Config.GithubConcurrentThreads)
if err == nil {
g.teamRepos = teamsrepos
g.ttlExpireTeamsRepos = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}
}
}
return g.teamRepos
Expand Down Expand Up @@ -509,57 +516,69 @@ func (g *GoliacRemoteImpl) loadAppIds() (map[string]int, error) {
}

func (g *GoliacRemoteImpl) Load() error {
users, err := g.loadOrgUsers()
if err != nil {
return err
}
g.users = users
g.ttlExpireUsers = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))

repositories, repositoriesByRefId, err := g.loadRepositories()
if err != nil {
return err
}
g.repositories = repositories
g.repositoriesByRefId = repositoriesByRefId
g.ttlExpireRepositories = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))

teams, teamSlugByName, err := g.loadTeams()
if err != nil {
return err
if time.Now().After(g.ttlExpireUsers) {
users, err := g.loadOrgUsers()
if err != nil {
return err
}
g.users = users
g.ttlExpireUsers = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}
g.teams = teams
g.teamSlugByName = teamSlugByName
g.ttlExpireTeams = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))

appIds, err := g.loadAppIds()
if err != nil {
return err
if time.Now().After(g.ttlExpireRepositories) {
repositories, repositoriesByRefId, err := g.loadRepositories()
if err != nil {
return err
}
g.repositories = repositories
g.repositoriesByRefId = repositoriesByRefId
g.ttlExpireRepositories = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}
g.appIds = appIds
g.ttlExpireAppIds = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))

rulesets, err := g.loadRulesets()
if err != nil {
return err
if time.Now().After(g.ttlExpireTeams) {
teams, teamSlugByName, err := g.loadTeams()
if err != nil {
return err
}
g.teams = teams
g.teamSlugByName = teamSlugByName
g.ttlExpireTeams = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}
g.rulesets = rulesets
g.ttlExpireRulesets = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))

if config.Config.GithubConcurrentThreads <= 1 {
teamsrepos, err := g.loadTeamReposNonConcurrently()
if time.Now().After(g.ttlExpireAppIds) {
appIds, err := g.loadAppIds()
if err != nil {
return err
}
g.teamRepos = teamsrepos
} else {
teamsrepos, err := g.loadTeamReposConcurrently(config.Config.GithubConcurrentThreads)
g.appIds = appIds
g.ttlExpireAppIds = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}

if time.Now().After(g.ttlExpireRulesets) {
rulesets, err := g.loadRulesets()
if err != nil {
return err
}
g.teamRepos = teamsrepos
g.rulesets = rulesets
g.ttlExpireRulesets = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}

if time.Now().After(g.ttlExpireTeamsRepos) {
if config.Config.GithubConcurrentThreads <= 1 {
teamsrepos, err := g.loadTeamReposNonConcurrently()
if err != nil {
return err
}
g.teamRepos = teamsrepos
} else {
teamsrepos, err := g.loadTeamReposConcurrently(config.Config.GithubConcurrentThreads)
if err != nil {
return err
}
g.teamRepos = teamsrepos
}
g.ttlExpireTeamsRepos = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))
}
g.ttlExpireTeamsRepos = time.Now().Add(time.Duration(config.Config.GithubCacheTTL))

logrus.Infof("Nb remote users: %d", len(g.users))
logrus.Infof("Nb remote teams: %d", len(g.teams))
Expand Down
12 changes: 12 additions & 0 deletions swagger/flushcache.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
get:
tags:
- app
operationId: getFlushCache
description: Flush the Github remote cache
responses:
200:
description: cache flushed
default:
description: generic error response
schema:
$ref: "#/definitions/error"
2 changes: 2 additions & 0 deletions swagger/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ paths:
$ref: ./liveness.yaml
/readiness:
$ref: ./readiness.yaml
/flushcache:
$ref: ./flushcache.yaml


definitions:
Expand Down
40 changes: 40 additions & 0 deletions swagger_gen/restapi/embedded_spec.go

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

56 changes: 56 additions & 0 deletions swagger_gen/restapi/operations/app/get_flush_cache.go

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

Loading