chore(sqlmigration): drop the rule history and data migrations table (#8181)

This commit is contained in:
Vikrant Gupta 2025-06-09 15:46:22 +05:30 committed by GitHub
parent 0acbcf8322
commit decb660992
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 120 additions and 123 deletions

View File

@ -6,11 +6,7 @@ import { Filters } from 'components/AlertDetailsFilters/Filters';
import NotFound from 'components/NotFound'; import NotFound from 'components/NotFound';
import RouteTab from 'components/RouteTab'; import RouteTab from 'components/RouteTab';
import Spinner from 'components/Spinner'; import Spinner from 'components/Spinner';
import { QueryParams } from 'constants/query';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { useNotifications } from 'hooks/useNotifications';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import history from 'lib/history'; import history from 'lib/history';
import { useEffect, useMemo } from 'react'; import { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -74,9 +70,6 @@ BreadCrumbItem.defaultProps = {
function AlertDetails(): JSX.Element { function AlertDetails(): JSX.Element {
const { pathname } = useLocation(); const { pathname } = useLocation();
const { routes } = useRouteTabUtils(); const { routes } = useRouteTabUtils();
const urlQuery = useUrlQuery();
const { safeNavigate } = useSafeNavigate();
const { notifications } = useNotifications();
const { const {
isLoading, isLoading,
@ -92,27 +85,6 @@ function AlertDetails(): JSX.Element {
document.title = alertTitle || document.title; document.title = alertTitle || document.title;
}, [alertDetailsResponse?.payload?.data.alert, isRefetching]); }, [alertDetailsResponse?.payload?.data.alert, isRefetching]);
useEffect(() => {
if (alertDetailsResponse?.payload?.data?.id) {
const ruleUUID = alertDetailsResponse.payload.data.id;
if (ruleId !== ruleUUID) {
urlQuery.set(QueryParams.ruleId, ruleUUID);
const generatedUrl = `${window.location.pathname}?${urlQuery}`;
notifications.info({
message:
"We're transitioning alert rule IDs from integers to UUIDs.Both old and new alert links will continue to work after this change - existing notifications using integer IDs will remain functional while new alerts will use the UUID format. Please use the updated link in the URL for future references",
});
safeNavigate(generatedUrl);
}
}
}, [
alertDetailsResponse?.payload?.data.id,
notifications,
ruleId,
safeNavigate,
urlQuery,
]);
if ( if (
isError || isError ||
!isValidRuleId || !isValidRuleId ||

View File

@ -660,7 +660,13 @@ func Intersection(a, b []int) (c []int) {
} }
func (aH *APIHandler) getRule(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) getRule(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"] idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
ruleResponse, err := aH.ruleManager.GetRule(r.Context(), id) ruleResponse, err := aH.ruleManager.GetRule(r.Context(), id)
if err != nil { if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil) RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
@ -990,9 +996,15 @@ func (aH *APIHandler) metaForLinks(ctx context.Context, rule *ruletypes.Gettable
} }
func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request) {
ruleID := mux.Vars(r)["id"] idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
params := model.QueryRuleStateHistory{} params := model.QueryRuleStateHistory{}
err := json.NewDecoder(r.Body).Decode(&params) err = json.NewDecoder(r.Body).Decode(&params)
if err != nil { if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil) RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return return
@ -1002,13 +1014,13 @@ func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request
return return
} }
res, err := aH.reader.ReadRuleStateHistoryByRuleID(r.Context(), ruleID, &params) res, err := aH.reader.ReadRuleStateHistoryByRuleID(r.Context(), id.StringValue(), &params)
if err != nil { if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil) RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
return return
} }
rule, err := aH.ruleManager.GetRule(r.Context(), ruleID) rule, err := aH.ruleManager.GetRule(r.Context(), id)
if err == nil { if err == nil {
for idx := range res.Items { for idx := range res.Items {
lbls := make(map[string]string) lbls := make(map[string]string)
@ -1036,21 +1048,27 @@ func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request
} }
func (aH *APIHandler) getRuleStateHistoryTopContributors(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) getRuleStateHistoryTopContributors(w http.ResponseWriter, r *http.Request) {
ruleID := mux.Vars(r)["id"] idStr := mux.Vars(r)["id"]
params := model.QueryRuleStateHistory{} id, err := valuer.NewUUID(idStr)
err := json.NewDecoder(r.Body).Decode(&params)
if err != nil { if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil) RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return return
} }
res, err := aH.reader.ReadRuleStateHistoryTopContributorsByRuleID(r.Context(), ruleID, &params) params := model.QueryRuleStateHistory{}
err = json.NewDecoder(r.Body).Decode(&params)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
res, err := aH.reader.ReadRuleStateHistoryTopContributorsByRuleID(r.Context(), id.StringValue(), &params)
if err != nil { if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil) RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
return return
} }
rule, err := aH.ruleManager.GetRule(r.Context(), ruleID) rule, err := aH.ruleManager.GetRule(r.Context(), id)
if err == nil { if err == nil {
for idx := range res { for idx := range res {
lbls := make(map[string]string) lbls := make(map[string]string)
@ -1330,7 +1348,12 @@ func (aH *APIHandler) deleteRule(w http.ResponseWriter, r *http.Request) {
// patchRule updates only requested changes in the rule // patchRule updates only requested changes in the rule
func (aH *APIHandler) patchRule(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) patchRule(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"] idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
defer r.Body.Close() defer r.Body.Close()
body, err := io.ReadAll(r.Body) body, err := io.ReadAll(r.Body)
@ -1351,7 +1374,12 @@ func (aH *APIHandler) patchRule(w http.ResponseWriter, r *http.Request) {
} }
func (aH *APIHandler) editRule(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) editRule(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"] idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
defer r.Body.Close() defer r.Body.Close()
body, err := io.ReadAll(r.Body) body, err := io.ReadAll(r.Body)

View File

@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"sort" "sort"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -320,7 +319,7 @@ func (m *Manager) Stop(ctx context.Context) {
// EditRuleDefinition writes the rule definition to the // EditRuleDefinition writes the rule definition to the
// datastore and also updates the rule executor // datastore and also updates the rule executor
func (m *Manager) EditRule(ctx context.Context, ruleStr string, idStr string) error { func (m *Manager) EditRule(ctx context.Context, ruleStr string, id valuer.UUID) error {
claims, err := authtypes.ClaimsFromContext(ctx) claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil { if err != nil {
return err return err
@ -330,26 +329,12 @@ func (m *Manager) EditRule(ctx context.Context, ruleStr string, idStr string) er
return err return err
} }
ruleUUID, err := valuer.NewUUID(idStr)
if err != nil {
id, err := strconv.Atoi(idStr)
if err != nil {
return err
}
ruleHistory, err := m.ruleStore.GetRuleUUID(ctx, id)
if err != nil {
return err
}
ruleUUID = ruleHistory.RuleUUID
}
parsedRule, err := ruletypes.ParsePostableRule([]byte(ruleStr)) parsedRule, err := ruletypes.ParsePostableRule([]byte(ruleStr))
if err != nil { if err != nil {
return err return err
} }
existingRule, err := m.ruleStore.GetStoredRule(ctx, ruleUUID) existingRule, err := m.ruleStore.GetStoredRule(ctx, id)
if err != nil { if err != nil {
return err return err
} }
@ -378,7 +363,7 @@ func (m *Manager) EditRule(ctx context.Context, ruleStr string, idStr string) er
preferredChannels = parsedRule.PreferredChannels preferredChannels = parsedRule.PreferredChannels
} }
err = cfg.UpdateRuleIDMatcher(ruleUUID.StringValue(), preferredChannels) err = cfg.UpdateRuleIDMatcher(id.StringValue(), preferredChannels)
if err != nil { if err != nil {
return err return err
} }
@ -826,22 +811,8 @@ func (m *Manager) ListRuleStates(ctx context.Context) (*ruletypes.GettableRules,
return &ruletypes.GettableRules{Rules: resp}, nil return &ruletypes.GettableRules{Rules: resp}, nil
} }
func (m *Manager) GetRule(ctx context.Context, idStr string) (*ruletypes.GettableRule, error) { func (m *Manager) GetRule(ctx context.Context, id valuer.UUID) (*ruletypes.GettableRule, error) {
ruleUUID, err := valuer.NewUUID(idStr) s, err := m.ruleStore.GetStoredRule(ctx, id)
if err != nil {
id, err := strconv.Atoi(idStr)
if err != nil {
return nil, err
}
ruleHistory, err := m.ruleStore.GetRuleUUID(ctx, id)
if err != nil {
return nil, err
}
ruleUUID = ruleHistory.RuleUUID
}
s, err := m.ruleStore.GetStoredRule(ctx, ruleUUID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -849,7 +820,7 @@ func (m *Manager) GetRule(ctx context.Context, idStr string) (*ruletypes.Gettabl
if err := json.Unmarshal([]byte(s.Data), r); err != nil { if err := json.Unmarshal([]byte(s.Data), r); err != nil {
return nil, err return nil, err
} }
r.Id = ruleUUID.StringValue() r.Id = id.StringValue()
// fetch state of rule from memory // fetch state of rule from memory
if rm, ok := m.rules[r.Id]; !ok { if rm, ok := m.rules[r.Id]; !ok {
r.State = model.StateDisabled r.State = model.StateDisabled
@ -899,7 +870,7 @@ func (m *Manager) syncRuleStateWithTask(ctx context.Context, orgID valuer.UUID,
// - over write the patch attributes received in input (ruleStr) // - over write the patch attributes received in input (ruleStr)
// - re-deploy or undeploy task as necessary // - re-deploy or undeploy task as necessary
// - update the patched rule in the DB // - update the patched rule in the DB
func (m *Manager) PatchRule(ctx context.Context, ruleStr string, ruleIdStr string) (*ruletypes.GettableRule, error) { func (m *Manager) PatchRule(ctx context.Context, ruleStr string, id valuer.UUID) (*ruletypes.GettableRule, error) {
claims, err := authtypes.ClaimsFromContext(ctx) claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
@ -910,24 +881,19 @@ func (m *Manager) PatchRule(ctx context.Context, ruleStr string, ruleIdStr strin
return nil, err return nil, err
} }
ruleID, err := valuer.NewUUID(ruleIdStr) taskName := prepareTaskName(id.StringValue())
if err != nil {
return nil, errors.New(err.Error())
}
taskName := prepareTaskName(ruleID.StringValue())
// retrieve rule from DB // retrieve rule from DB
storedJSON, err := m.ruleStore.GetStoredRule(ctx, ruleID) storedJSON, err := m.ruleStore.GetStoredRule(ctx, id)
if err != nil { if err != nil {
zap.L().Error("failed to get stored rule with given id", zap.String("id", ruleID.StringValue()), zap.Error(err)) zap.L().Error("failed to get stored rule with given id", zap.String("id", id.StringValue()), zap.Error(err))
return nil, err return nil, err
} }
// storedRule holds the current stored rule from DB // storedRule holds the current stored rule from DB
storedRule := ruletypes.PostableRule{} storedRule := ruletypes.PostableRule{}
if err := json.Unmarshal([]byte(storedJSON.Data), &storedRule); err != nil { if err := json.Unmarshal([]byte(storedJSON.Data), &storedRule); err != nil {
zap.L().Error("failed to unmarshal stored rule with given id", zap.String("id", ruleID.StringValue()), zap.Error(err)) zap.L().Error("failed to unmarshal stored rule with given id", zap.String("id", id.StringValue()), zap.Error(err))
return nil, err return nil, err
} }
@ -964,12 +930,12 @@ func (m *Manager) PatchRule(ctx context.Context, ruleStr string, ruleIdStr strin
// prepare http response // prepare http response
response := ruletypes.GettableRule{ response := ruletypes.GettableRule{
Id: ruleID.StringValue(), Id: id.StringValue(),
PostableRule: *patchedRule, PostableRule: *patchedRule,
} }
// fetch state of rule from memory // fetch state of rule from memory
if rm, ok := m.rules[ruleID.StringValue()]; !ok { if rm, ok := m.rules[id.StringValue()]; !ok {
response.State = model.StateDisabled response.State = model.StateDisabled
response.Disabled = true response.Disabled = true
} else { } else {

View File

@ -103,17 +103,3 @@ func (r *rule) GetStoredRule(ctx context.Context, id valuer.UUID) (*ruletypes.Ru
} }
return rule, nil return rule, nil
} }
func (r *rule) GetRuleUUID(ctx context.Context, ruleID int) (*ruletypes.RuleHistory, error) {
ruleHistory := new(ruletypes.RuleHistory)
err := r.sqlstore.
BunDB().
NewSelect().
Model(ruleHistory).
Where("rule_id = ?", ruleID).
Scan(ctx)
if err != nil {
return nil, err
}
return ruleHistory, nil
}

View File

@ -91,6 +91,7 @@ func NewSQLMigrationProviderFactories(sqlstore sqlstore.SQLStore) factory.NamedM
sqlmigration.NewAddTraceFunnelsFactory(sqlstore), sqlmigration.NewAddTraceFunnelsFactory(sqlstore),
sqlmigration.NewUpdateDashboardFactory(sqlstore), sqlmigration.NewUpdateDashboardFactory(sqlstore),
sqlmigration.NewDropFeatureSetFactory(), sqlmigration.NewDropFeatureSetFactory(),
sqlmigration.NewDropDeprecatedTablesFactory(),
) )
} }

View File

@ -0,0 +1,66 @@
package sqlmigration
import (
"context"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/uptrace/bun"
"github.com/uptrace/bun/migrate"
)
type dropDeprecatedTables struct{}
func NewDropDeprecatedTablesFactory() factory.ProviderFactory[SQLMigration, Config] {
return factory.NewProviderFactory(factory.MustNewName("drop_deprecated_tables"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newDropDeprecatedTables(ctx, ps, c)
})
}
func newDropDeprecatedTables(_ context.Context, _ factory.ProviderSettings, _ Config) (SQLMigration, error) {
return &dropDeprecatedTables{}, nil
}
func (migration *dropDeprecatedTables) Register(migrations *migrate.Migrations) error {
if err := migrations.Register(migration.Up, migration.Down); err != nil {
return err
}
return nil
}
func (migration *dropDeprecatedTables) Up(ctx context.Context, db *bun.DB) error {
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer func() {
_ = tx.Rollback()
}()
if _, err := tx.
NewDropTable().
IfExists().
Table("rule_history").
Exec(ctx); err != nil {
return err
}
if _, err := tx.
NewDropTable().
IfExists().
Table("data_migrations").
Exec(ctx); err != nil {
return err
}
if err := tx.Commit(); err != nil {
return err
}
return nil
}
func (migration *dropDeprecatedTables) Down(context.Context, *bun.DB) error {
return nil
}

View File

@ -1,15 +0,0 @@
package types
import (
"time"
"github.com/uptrace/bun"
)
type DataMigration struct {
bun.BaseModel `bun:"table:data_migrations"`
ID int `bun:"id,pk,autoincrement"`
Version string `bun:"version,unique,notnull,type:VARCHAR(255)"`
CreatedAt time.Time `bun:"created_at,notnull,default:current_timestamp"`
Succeeded bool `bun:"succeeded,notnull,default:false"`
}

View File

@ -18,17 +18,10 @@ type Rule struct {
OrgID string `bun:"org_id,type:text"` OrgID string `bun:"org_id,type:text"`
} }
type RuleHistory struct {
bun.BaseModel `bun:"table:rule_history"`
RuleID int `bun:"rule_id"`
RuleUUID valuer.UUID `bun:"rule_uuid"`
}
type RuleStore interface { type RuleStore interface {
CreateRule(context.Context, *Rule, func(context.Context, valuer.UUID) error) (valuer.UUID, error) CreateRule(context.Context, *Rule, func(context.Context, valuer.UUID) error) (valuer.UUID, error)
EditRule(context.Context, *Rule, func(context.Context) error) error EditRule(context.Context, *Rule, func(context.Context) error) error
DeleteRule(context.Context, valuer.UUID, func(context.Context) error) error DeleteRule(context.Context, valuer.UUID, func(context.Context) error) error
GetStoredRules(context.Context, string) ([]*Rule, error) GetStoredRules(context.Context, string) ([]*Rule, error)
GetStoredRule(context.Context, valuer.UUID) (*Rule, error) GetStoredRule(context.Context, valuer.UUID) (*Rule, error)
GetRuleUUID(context.Context, int) (*RuleHistory, error)
} }