From 5c92eba70afa7e060125f054b6bbb6e343c366d9 Mon Sep 17 00:00:00 2001 From: Ahmed Nour Date: Fri, 23 Aug 2024 15:28:21 +0200 Subject: [PATCH] get all apps and releases in one query --- .../pkg/service/commit_deployment.go | 97 ++++++++----------- .../pkg/service/commit_deployment_test.go | 42 -------- 2 files changed, 43 insertions(+), 96 deletions(-) diff --git a/services/cd-service/pkg/service/commit_deployment.go b/services/cd-service/pkg/service/commit_deployment.go index 25cbe5fad..683e5d809 100644 --- a/services/cd-service/pkg/service/commit_deployment.go +++ b/services/cd-service/pkg/service/commit_deployment.go @@ -37,30 +37,36 @@ type CommitDeploymentServer struct { func (s *CommitDeploymentServer) GetCommitDeploymentInfo(ctx context.Context, in *api.GetCommitDeploymentInfoRequest) (*api.GetCommitDeploymentInfoResponse, error) { commitDeploymentStatus := make(map[string]*api.AppCommitDeploymentStatus, 0) - var jsonAllApplicationsMetadata []byte var jsonCommitEventsMetadata []byte var jsonAllEnvironmentsMetadata []byte - + applicationReleases := make(map[string][]byte, 0) + allApplicationReleasesQuery := ` +SELECT + deployments.appname, + deployments.json +FROM ( + SELECT + MAX(eslVersion) AS latest, + appname + FROM + "public"."all_deployments" + GROUP BY + appname) AS latest +JOIN + "public".all_deployments AS deployments +ON + latest.latest=deployments.eslVersion + AND latest.appname=deployments.appname; +` span, _ := tracer.StartSpanFromContext(ctx, "GetCommitDeploymentInfo") defer span.Finish() span.SetTag("commit_id", in.CommitId) err := s.DBHandler.WithTransaction(ctx, true, func(ctx context.Context, transaction *sql.Tx) error { - // Get all applications - query := s.DBHandler.AdaptQuery("SELECT json FROM all_apps ORDER BY version DESC LIMIT 1;") - row := transaction.QueryRow(query) - err := row.Scan(&jsonAllApplicationsMetadata) - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - return fmt.Errorf("No applications found") - } - return err - } - // Get the latest new-release event for the commit - query = s.DBHandler.AdaptQuery("SELECT json FROM commit_events WHERE commithash = ? AND eventtype = ? ORDER BY timestamp DESC LIMIT 1;") - row = transaction.QueryRow(query, in.CommitId, "new-release") - err = row.Scan(&jsonCommitEventsMetadata) + query := s.DBHandler.AdaptQuery("SELECT json FROM commit_events WHERE commithash = ? AND eventtype = ? ORDER BY timestamp DESC LIMIT 1;") + row := transaction.QueryRow(query, in.CommitId, "new-release") + err := row.Scan(&jsonCommitEventsMetadata) if err != nil { if errors.Is(err, sql.ErrNoRows) { return fmt.Errorf("commit \"%s\" could not be found", in.CommitId) @@ -78,16 +84,29 @@ func (s *CommitDeploymentServer) GetCommitDeploymentInfo(ctx context.Context, in } return err } + + // Get latest releases for all apps + rows, err := transaction.QueryContext(ctx, allApplicationReleasesQuery) + if err != nil { + return err + } + defer rows.Close() + + for rows.Next() { + var appName string + var appRelease []byte + err = rows.Scan(&appName, &appRelease) + if err != nil { + return err + } + applicationReleases[appName] = appRelease + } return nil }) if err != nil { return nil, err } - apps, err := getAllApplications(jsonAllApplicationsMetadata) - if err != nil { - return nil, fmt.Errorf("Could not get all applications: %v", err) - } releaseNumber, err := getCommitReleaseNumber(jsonCommitEventsMetadata) if err != nil { return nil, fmt.Errorf("Could not get commit release number from commit_events metadata: %v", err) @@ -97,8 +116,8 @@ func (s *CommitDeploymentServer) GetCommitDeploymentInfo(ctx context.Context, in return nil, fmt.Errorf("Could not get all environments from all_environments metadata: %v", err) } - for _, app := range apps { - commitDeploymentStatusForApp, err := getCommitDeploymentInfoForApp(ctx, s.DBHandler, releaseNumber, app, allEnvironments) + for app, releases := range applicationReleases { + commitDeploymentStatusForApp, err := getCommitDeploymentInfoForApp(ctx, s.DBHandler, releaseNumber, app, allEnvironments, releases) if err != nil { return nil, fmt.Errorf("Could not get commit deployment info for app %s: %v", app, err) } @@ -110,32 +129,13 @@ func (s *CommitDeploymentServer) GetCommitDeploymentInfo(ctx context.Context, in }, nil } -func getCommitDeploymentInfoForApp(ctx context.Context, h *db.DBHandler, commitReleaseNumber uint64, app string, environments []string) (*api.AppCommitDeploymentStatus, error) { - var jsonAllDeploymentsMetadata []byte +func getCommitDeploymentInfoForApp(ctx context.Context, h *db.DBHandler, commitReleaseNumber uint64, app string, environments []string, appDeployments []byte) (*api.AppCommitDeploymentStatus, error) { span, _ := tracer.StartSpanFromContext(ctx, "getCommitDeploymentInfoForApp") defer span.Finish() span.SetTag("app", app) - err := h.WithTransaction(ctx, true, func(ctx context.Context, transaction *sql.Tx) error { - // Get all deployments for the application - query := h.AdaptQuery("SELECT json FROM all_deployments WHERE appname = ? ORDER BY eslversion DESC LIMIT 1;") - row := transaction.QueryRow(query, app) - err := row.Scan(&jsonAllDeploymentsMetadata) - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - return fmt.Errorf("application \"%s\" does not exist or has no deployments yet.", app) - } - return err - } - - return nil - }) - if err != nil { - return nil, err - } - - environmentReleases, err := getEnvironmentReleases(jsonAllDeploymentsMetadata) + environmentReleases, err := getEnvironmentReleases(appDeployments) if err != nil { return nil, fmt.Errorf("Could not get environment releases from all_deployments metadata: %v", err) } @@ -207,14 +207,3 @@ func getEnvironmentReleases(jsonInput []byte) (map[string]uint64, error) { } return releases, nil } - -func getAllApplications(jsonInput []byte) ([]string, error) { - applications := db.AllApplicationsJson{ - Apps: []string{}, - } - err := json.Unmarshal(jsonInput, &applications) - if err != nil { - return nil, err - } - return applications.Apps, nil -} diff --git a/services/cd-service/pkg/service/commit_deployment_test.go b/services/cd-service/pkg/service/commit_deployment_test.go index e61c30107..6192c185f 100644 --- a/services/cd-service/pkg/service/commit_deployment_test.go +++ b/services/cd-service/pkg/service/commit_deployment_test.go @@ -234,45 +234,3 @@ func TestGetCommitStatus(t *testing.T) { }) } } - -func TestGetAllApplications(t *testing.T) { - tcs := []struct { - name string - applicationsJson []byte - expected []string - }{ - { - name: "One application", - applicationsJson: []byte(`{"apps":["app1"]}`), - expected: []string{"app1"}, - }, - { - name: "Multiple applications", - applicationsJson: []byte(`{"apps":["app1","app2","app3"]}`), - expected: []string{"app1", "app2", "app3"}, - }, - { - name: "No applications", - applicationsJson: []byte(`{"apps":[]}`), - expected: []string{}, - }, - } - for _, tc := range tcs { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - applications, err := getAllApplications(tc.applicationsJson) - if err != nil { - t.Fatalf("Error getting all applications: %v", err) - } - if len(applications) != len(tc.expected) { - t.Fatalf("Expected %d applications, got %d", len(tc.expected), len(applications)) - } - for i, env := range applications { - if env != tc.expected[i] { - t.Fatalf("Expected %s, got %s", tc.expected[i], env) - } - } - }) - } -}