Skip to content

Commit e17d4d8

Browse files
authored
Added FecthAllByDomainId, fixed handler sync check (#37)
1 parent 0133ccf commit e17d4d8

File tree

8 files changed

+136
-36
lines changed

8 files changed

+136
-36
lines changed

src/controller/account.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func NewAccountController(repo repository.AccountRepository, coreHandler *core.C
3333
func (controller *AccountController) RegisterRoutes(r *mux.Router) http.Handler {
3434
r.NewRoute().Path(controller.RouteAccountPath).Name("CreateAccount").HandlerFunc(controller.CreateAccountHandler).Methods(http.MethodPost)
3535
r.NewRoute().Path(controller.RouteAccountPath).Name("UpdateAccount").HandlerFunc(controller.UpdateAccountHandler).Methods(http.MethodPut)
36+
r.NewRoute().Path(controller.RouteAccountPath + "/{domainId}").Name("GelAllAccountsByDomainId").HandlerFunc(controller.FetchAllAccountsByDomainIdHandler).Methods(http.MethodGet)
3637
r.NewRoute().Path(controller.RouteAccountPath + "/{domainId}/{enviroment}").Name("GetAccount").HandlerFunc(controller.FetchAccountHandler).Methods(http.MethodGet)
3738
r.NewRoute().Path(controller.RouteAccountPath + "/{domainId}/{enviroment}").Name("DeleteAccount").HandlerFunc(controller.DeleteAccountHandler).Methods(http.MethodDelete)
3839

@@ -80,6 +81,19 @@ func (controller *AccountController) FetchAccountHandler(w http.ResponseWriter,
8081
utils.ResponseJSON(w, account, http.StatusOK)
8182
}
8283

84+
func (controller *AccountController) FetchAllAccountsByDomainIdHandler(w http.ResponseWriter, r *http.Request) {
85+
domainId := mux.Vars(r)["domainId"]
86+
87+
accounts := controller.AccountRepository.FetchAllByDomainId(domainId)
88+
if accounts == nil {
89+
utils.Log(utils.LogLevelError, "Not found accounts for domain: %s", domainId)
90+
utils.ResponseJSON(w, ErrorResponse{Error: "Not found accounts for domain: " + domainId}, http.StatusNotFound)
91+
return
92+
}
93+
94+
utils.ResponseJSON(w, accounts, http.StatusOK)
95+
}
96+
8397
func (controller *AccountController) UpdateAccountHandler(w http.ResponseWriter, r *http.Request) {
8498
var accountRequest model.Account
8599
err := json.NewDecoder(r.Body).Decode(&accountRequest)

src/controller/account_test.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,53 @@ func TestFetchAccountHandler(t *testing.T) {
9090
assert.Equal(t, http.StatusNotFound, response.Code)
9191
assert.Equal(t, "{\"error\":\"Account not found\"}", response.Body.String())
9292
})
93+
94+
t.Run("Should fetch all accounts by domain ID", func(t *testing.T) {
95+
// Create an account
96+
accountV1.Domain.ID = "123-controller-fetch-all-accounts"
97+
accountController.CreateAccountHandler(givenAccountRequest(accountV1))
98+
accountV1.Environment = "staging"
99+
accountController.CreateAccountHandler(givenAccountRequest(accountV1))
100+
101+
// Test
102+
payload := []byte("")
103+
req, _ := http.NewRequest(http.MethodGet, accountController.RouteAccountPath+"/"+accountV1.Domain.ID, bytes.NewBuffer(payload))
104+
response := executeRequest(req)
105+
106+
// Assert
107+
var accountsResponse []model.Account
108+
err := json.NewDecoder(response.Body).Decode(&accountsResponse)
109+
110+
assert.Equal(t, http.StatusOK, response.Code)
111+
assert.Nil(t, err)
112+
assert.Equal(t, 2, len(accountsResponse))
113+
})
114+
115+
t.Run("Should not fetch all accounts by domain ID - not found", func(t *testing.T) {
116+
// Test
117+
payload := []byte("")
118+
req, _ := http.NewRequest(http.MethodGet, accountController.RouteAccountPath+"/not-found", bytes.NewBuffer(payload))
119+
response := executeRequest(req)
120+
121+
// Assert
122+
assert.Equal(t, http.StatusNotFound, response.Code)
123+
assert.Equal(t, "{\"error\":\"Not found accounts for domain: not-found\"}", response.Body.String())
124+
})
93125
}
94126

95127
func TestUpdateAccountHandler(t *testing.T) {
96128
t.Run("Should update an account", func(t *testing.T) {
97129
// Create an account
98130
accountV1.Domain.ID = "123-controller-update-account"
131+
accountV1.Environment = "default"
99132
accountController.CreateAccountHandler(givenAccountRequest(accountV1))
100133

101-
// Test
102-
accountV2.Domain.ID = accountV1.Domain.ID
134+
// Update the account
135+
accountV2.Domain.ID = "123-controller-update-account"
136+
accountV2.Environment = "default"
103137
accountV2.Domain.Message = "Updated successfully"
138+
139+
// Test
104140
payload, _ := json.Marshal(accountV2)
105141
req, _ := http.NewRequest(http.MethodPut, accountController.RouteAccountPath, bytes.NewBuffer(payload))
106142
response := executeRequest(req)

src/core/handler.go

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func NewCoreHandler(accountRepository repository.AccountRepository, apiService I
2929
}
3030
}
3131

32-
func (c *CoreHandler) InitCoreHandlerCoroutine() (int, error) {
32+
func (c *CoreHandler) InitCoreHandlerGoroutine() (int, error) {
3333
// Check if core handler is already running
3434
if c.Status == CoreHandlerStatusRunning {
3535
return c.Status, nil
@@ -39,7 +39,7 @@ func (c *CoreHandler) InitCoreHandlerCoroutine() (int, error) {
3939
c.Status = CoreHandlerStatusInit
4040

4141
// Load all accounts
42-
accounts, _ := c.AccountRepository.FetchAllActiveAccounts()
42+
accounts := c.AccountRepository.FetchAllActiveAccounts()
4343

4444
// Iterate over accounts and start account handlers
4545
for _, account := range accounts {
@@ -70,7 +70,9 @@ func (c *CoreHandler) StartAccountHandler(accountId string, gitService IGitServi
7070

7171
// Wait for account to be active
7272
if !account.Settings.Active {
73-
utils.Log(utils.LogLevelInfo, "[%s - %s] Account is not active, waiting for activation", accountId, account.Domain.Name)
73+
utils.Log(utils.LogLevelInfo, "[%s - %s (%s)] Account is not active, waiting for activation",
74+
accountId, account.Domain.Name, account.Environment)
75+
7476
c.updateDomainStatus(*account, model.StatusPending, "Account was deactivated")
7577
time.Sleep(1 * time.Minute)
7678
continue
@@ -83,7 +85,9 @@ func (c *CoreHandler) StartAccountHandler(accountId string, gitService IGitServi
8385
repositoryData, err := gitService.GetRepositoryData(account.Environment)
8486

8587
if err != nil {
86-
utils.Log(utils.LogLevelError, "[%s - %s] Failed to fetch repository data - %s", accountId, account.Domain.Name, err.Error())
88+
utils.Log(utils.LogLevelError, "[%s - %s (%s)] Failed to fetch repository data - %s",
89+
accountId, account.Domain.Name, account.Environment, err.Error())
90+
8791
c.updateDomainStatus(*account, model.StatusError, "Failed to fetch repository data - "+err.Error())
8892
time.Sleep(1 * time.Minute)
8993
continue
@@ -93,7 +97,9 @@ func (c *CoreHandler) StartAccountHandler(accountId string, gitService IGitServi
9397
snapshotVersionPayload, err := c.ApiService.FetchSnapshotVersion(account.Domain.ID, account.Environment)
9498

9599
if err != nil {
96-
utils.Log(utils.LogLevelError, "[%s - %s] Failed to fetch snapshot version - %s", accountId, account.Domain.Name, err.Error())
100+
utils.Log(utils.LogLevelError, "[%s - %s (%s)] Failed to fetch snapshot version - %s",
101+
accountId, account.Domain.Name, account.Environment, err.Error())
102+
97103
c.updateDomainStatus(*account, model.StatusError, "Failed to fetch snapshot version - "+err.Error())
98104
time.Sleep(1 * time.Minute)
99105
continue
@@ -111,9 +117,11 @@ func (c *CoreHandler) StartAccountHandler(accountId string, gitService IGitServi
111117
}
112118

113119
func (c *CoreHandler) syncUp(account model.Account, repositoryData *model.RepositoryData, gitService IGitService) {
114-
utils.Log(utils.LogLevelInfo, "[%s - %s] Syncing up", account.ID.Hex(), account.Domain.Name)
120+
utils.Log(utils.LogLevelInfo, "[%s - %s (%s)] Syncing up", account.ID.Hex(), account.Domain.Name, account.Environment)
115121

116122
// Update account status: Out of sync
123+
account.Domain.LastCommit = repositoryData.CommitHash
124+
account.Domain.LastDate = repositoryData.CommitDate
117125
c.updateDomainStatus(account, model.StatusOutSync, model.MessageSyncingUp)
118126

119127
// Check for changes
@@ -124,17 +132,19 @@ func (c *CoreHandler) syncUp(account model.Account, repositoryData *model.Reposi
124132
return
125133
}
126134

127-
utils.Log(utils.LogLevelDebug, "[%s - %s] SnapshotAPI version: %s - SnapshotRepo version: %s",
128-
account.ID.Hex(), account.Domain.Name, fmt.Sprint(snapshotApi.Domain.Version), fmt.Sprint(account.Domain.Version))
135+
utils.Log(utils.LogLevelDebug, "[%s - %s (%s)] SnapshotAPI version: %s - SnapshotRepo version: %s",
136+
account.ID.Hex(), account.Domain.Name, account.Environment, fmt.Sprint(snapshotApi.Domain.Version), fmt.Sprint(account.Domain.Version))
129137

130138
// Apply changes
131139
changeSource := ""
132140
if snapshotApi.Domain.Version > account.Domain.Version {
133141
changeSource = "Repository"
134-
if c.isRepositoryOutSync(account, repositoryData, diff) {
142+
if c.isRepositoryOutSync(repositoryData, diff) {
135143
account, err = c.applyChangesToRepository(account, snapshotApi, gitService)
136144
} else {
137-
utils.Log(utils.LogLevelInfo, "[%s - %s] Repository is up to date", account.ID.Hex(), account.Domain.Name)
145+
utils.Log(utils.LogLevelInfo, "[%s - %s (%s)] Repository is up to date",
146+
account.ID.Hex(), account.Domain.Name, account.Environment)
147+
138148
account.Domain.Version = snapshotApi.Domain.Version
139149
account.Domain.LastCommit = repositoryData.CommitHash
140150
}
@@ -144,7 +154,9 @@ func (c *CoreHandler) syncUp(account model.Account, repositoryData *model.Reposi
144154
}
145155

146156
if err != nil {
147-
utils.Log(utils.LogLevelError, "[%s - %s] Failed to apply changes [%s] - %s", account.ID.Hex(), account.Domain.Name, changeSource, err.Error())
157+
utils.Log(utils.LogLevelError, "[%s - %s (%s)] Failed to apply changes [%s] - %s",
158+
account.ID.Hex(), account.Domain.Name, account.Environment, changeSource, err.Error())
159+
148160
c.updateDomainStatus(account, model.StatusError, "Failed to apply changes ["+changeSource+"] - "+err.Error())
149161
return
150162
}
@@ -178,7 +190,7 @@ func (c *CoreHandler) checkForChanges(account model.Account, content string) (mo
178190
}
179191

180192
func (c *CoreHandler) applyChangesToAPI(account model.Account, repositoryData *model.RepositoryData, diff model.DiffResult) model.Account {
181-
utils.Log(utils.LogLevelInfo, "[%s - %s] Pushing changes to API", account.ID.Hex(), account.Domain.Name)
193+
utils.Log(utils.LogLevelInfo, "[%s - %s (%s)] Pushing changes to API", account.ID.Hex(), account.Domain.Name, account.Environment)
182194

183195
// Removed deleted if force prune is disabled
184196
if !account.Settings.ForcePrune {
@@ -195,7 +207,7 @@ func (c *CoreHandler) applyChangesToAPI(account model.Account, repositoryData *m
195207
}
196208

197209
func (c *CoreHandler) applyChangesToRepository(account model.Account, snapshot model.Snapshot, gitService IGitService) (model.Account, error) {
198-
utils.Log(utils.LogLevelInfo, "[%s - %s] Pushing changes to repository", account.ID.Hex(), account.Domain.Name)
210+
utils.Log(utils.LogLevelInfo, "[%s - %s (%s)] Pushing changes to repository", account.ID.Hex(), account.Domain.Name, account.Environment)
199211

200212
// Remove version from domain
201213
snapshotContent := snapshot
@@ -217,17 +229,16 @@ func (c *CoreHandler) applyChangesToRepository(account model.Account, snapshot m
217229
func (c *CoreHandler) isOutSync(account model.Account, lastCommit string, snapshotVersionPayload string) bool {
218230
snapshotVersion := c.ApiService.NewDataFromJson([]byte(snapshotVersionPayload)).Snapshot.Domain.Version
219231

220-
utils.Log(utils.LogLevelDebug, "[%s - %s] Checking account - Last commit: %s - Domain Version: %d - Snapshot Version: %d",
221-
account.ID.Hex(), account.Domain.Name, account.Domain.LastCommit, account.Domain.Version, snapshotVersion)
232+
utils.Log(utils.LogLevelDebug, "[%s - %s (%s)] Checking account - Last commit: %s - Domain Version: %d - Snapshot Version: %d",
233+
account.ID.Hex(), account.Domain.Name, account.Environment, account.Domain.LastCommit, account.Domain.Version, snapshotVersion)
222234

223235
return account.Domain.LastCommit == "" || // First sync
224236
account.Domain.LastCommit != lastCommit || // Repository out of sync
225237
account.Domain.Version != snapshotVersion // API out of sync
226238
}
227239

228-
func (c *CoreHandler) isRepositoryOutSync(account model.Account, repositoryData *model.RepositoryData, diff model.DiffResult) bool {
229-
return account.Domain.Version == 0 || // First/Force-push sync
230-
len(repositoryData.Content) <= 1 || // File is empty
240+
func (c *CoreHandler) isRepositoryOutSync(repositoryData *model.RepositoryData, diff model.DiffResult) bool {
241+
return len(repositoryData.Content) <= 1 || // File is empty
231242
len(diff.Changes) > 0 // Changes detected
232243
}
233244

src/core/handler_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/switcherapi/switcher-gitops/src/model"
1313
)
1414

15-
func TestInitCoreHandlerCoroutine(t *testing.T) {
15+
func TestInitCoreHandlerGoroutine(t *testing.T) {
1616
t.Run("Should start account handlers for all active accounts", func(t *testing.T) {
1717
// Given
1818
fakeApiService := NewFakeApiService()
@@ -23,7 +23,7 @@ func TestInitCoreHandlerCoroutine(t *testing.T) {
2323
accountCreated, _ := coreHandler.AccountRepository.Create(&account)
2424

2525
// Test
26-
status, err := coreHandler.InitCoreHandlerCoroutine()
26+
status, err := coreHandler.InitCoreHandlerGoroutine()
2727

2828
// Terminate the goroutine
2929
coreHandler.AccountRepository.DeleteByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
@@ -46,8 +46,8 @@ func TestInitCoreHandlerCoroutine(t *testing.T) {
4646
accountCreated, _ := coreHandler.AccountRepository.Create(&account)
4747

4848
// Test
49-
coreHandler.InitCoreHandlerCoroutine()
50-
status, _ := coreHandler.InitCoreHandlerCoroutine()
49+
coreHandler.InitCoreHandlerGoroutine()
50+
status, _ := coreHandler.InitCoreHandlerGoroutine()
5151

5252
// Terminate the goroutine
5353
coreHandler.AccountRepository.DeleteByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
@@ -211,7 +211,6 @@ func TestStartAccountHandler(t *testing.T) {
211211

212212
account := givenAccount()
213213
account.Domain.ID = "123-up-to-date-not-synced"
214-
account.Domain.Version = -1 // Different from the API version
215214
accountCreated, _ := coreHandler.AccountRepository.Create(&account)
216215

217216
// Test
@@ -350,7 +349,7 @@ func TestStartAccountHandler(t *testing.T) {
350349
accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainIdEnvironment(accountCreated.Domain.ID, accountCreated.Environment)
351350
assert.Equal(t, model.StatusError, accountFromDb.Domain.Status)
352351
assert.Contains(t, accountFromDb.Domain.Message, "Failed to check for changes")
353-
assert.Equal(t, "", accountFromDb.Domain.LastCommit)
352+
assert.Equal(t, "123", accountFromDb.Domain.LastCommit)
354353
assert.NotEqual(t, "", accountFromDb.Domain.LastDate)
355354

356355
tearDown()
@@ -379,7 +378,7 @@ func TestStartAccountHandler(t *testing.T) {
379378
assert.Equal(t, model.StatusError, accountFromDb.Domain.Status)
380379
assert.Contains(t, accountFromDb.Domain.Message, "authorization failed")
381380
assert.Contains(t, accountFromDb.Domain.Message, "Failed to apply changes [Repository]")
382-
assert.Equal(t, "", accountFromDb.Domain.LastCommit)
381+
assert.Equal(t, "123", accountFromDb.Domain.LastCommit)
383382
assert.NotEqual(t, "", accountFromDb.Domain.LastDate)
384383

385384
tearDown()

src/repository/account.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ type AccountRepository interface {
1717
Create(account *model.Account) (*model.Account, error)
1818
FetchByAccountId(accountId string) (*model.Account, error)
1919
FetchByDomainIdEnvironment(domainId string, environment string) (*model.Account, error)
20-
FetchAllActiveAccounts() ([]model.Account, error)
20+
FetchAllByDomainId(domainId string) []model.Account
21+
FetchAllActiveAccounts() []model.Account
2122
Update(account *model.Account) (*model.Account, error)
2223
DeleteByAccountId(accountId string) error
2324
DeleteByDomainIdEnvironment(domainId string, environment string) error
@@ -69,7 +70,7 @@ func (repo *AccountRepositoryMongo) FetchByDomainIdEnvironment(domainId string,
6970
defer cancel()
7071

7172
var account model.Account
72-
filter := primitive.M{domainIdFilter: domainId}
73+
filter := primitive.M{domainIdFilter: domainId, environmentFilter: environment}
7374
err := collection.FindOne(ctx, filter).Decode(&account)
7475
if err != nil {
7576
return nil, err
@@ -78,7 +79,26 @@ func (repo *AccountRepositoryMongo) FetchByDomainIdEnvironment(domainId string,
7879
return &account, nil
7980
}
8081

81-
func (repo *AccountRepositoryMongo) FetchAllActiveAccounts() ([]model.Account, error) {
82+
func (repo *AccountRepositoryMongo) FetchAllByDomainId(domainId string) []model.Account {
83+
collection, ctx, cancel := getDbContext(repo)
84+
defer cancel()
85+
86+
filter := primitive.M{domainIdFilter: domainId}
87+
cursor, _ := collection.Find(ctx, filter)
88+
89+
var accounts []model.Account
90+
for cursor.Next(ctx) {
91+
var account model.Account
92+
err := cursor.Decode(&account)
93+
if err == nil {
94+
accounts = append(accounts, account)
95+
}
96+
}
97+
98+
return accounts
99+
}
100+
101+
func (repo *AccountRepositoryMongo) FetchAllActiveAccounts() []model.Account {
82102
collection, ctx, cancel := getDbContext(repo)
83103
defer cancel()
84104

@@ -94,7 +114,7 @@ func (repo *AccountRepositoryMongo) FetchAllActiveAccounts() ([]model.Account, e
94114
}
95115
}
96116

97-
return accounts, nil
117+
return accounts
98118
}
99119

100120
func (repo *AccountRepositoryMongo) Update(account *model.Account) (*model.Account, error) {

src/repository/account_test.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,33 @@ func TestFetchAccount(t *testing.T) {
115115
accountRepository.Create(&account2)
116116

117117
// Test
118-
accounts, err := accountRepository.FetchAllActiveAccounts()
118+
accounts := accountRepository.FetchAllActiveAccounts()
119119

120120
// Assert
121-
assert.Nil(t, err)
121+
assert.NotNil(t, accounts)
122122
assert.Equal(t, 1, len(accounts))
123123
})
124+
125+
t.Run("Should fetch all accounts by domain ID", func(t *testing.T) {
126+
// Drop collection
127+
mongoDb.Collection("accounts").Drop(context.Background())
128+
129+
// Given
130+
account1 := givenAccount(true)
131+
account1.Domain.ID = "123-fetch-all-accounts-by-domain-id"
132+
account2 := givenAccount(true)
133+
account2.Domain.ID = "123-fetch-all-accounts-by-domain-id"
134+
135+
accountRepository.Create(&account1)
136+
accountRepository.Create(&account2)
137+
138+
// Test
139+
accounts := accountRepository.FetchAllByDomainId(account1.Domain.ID)
140+
141+
// Assert
142+
assert.NotNil(t, accounts)
143+
assert.Equal(t, 2, len(accounts))
144+
})
124145
}
125146

126147
func TestUpdateAccount(t *testing.T) {

src/server/app.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func initCoreHandler(db *mongo.Database) *core.CoreHandler {
8282
)
8383

8484
coreHandler := core.NewCoreHandler(accountRepository, apiService, comparatorService)
85-
coreHandler.InitCoreHandlerCoroutine()
85+
coreHandler.InitCoreHandlerGoroutine()
8686

8787
return coreHandler
8888
}

src/utils/http.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package utils
22

33
import (
44
"encoding/json"
5-
"fmt"
65
"net/http"
76
)
87

@@ -12,7 +11,7 @@ func ResponseJSON(w http.ResponseWriter, data interface{}, status int) {
1211

1312
encodedData, err := json.Marshal(data)
1413
if err != nil {
15-
fmt.Println("Error encoding JSON:", err)
14+
Log(LogLevelError, "Error encoding JSON: %s", err.Error())
1615
return
1716
}
1817

0 commit comments

Comments
 (0)