fix: fix modules and handler (#7737)

* fix: fix modules and handler

* fix: fix sqlmigration package

* fix: fix other fmt issues

* fix: fix tests

* fix: fix tests
This commit is contained in:
Vibhu Pandey 2025-04-27 16:38:34 +05:30 committed by GitHub
parent 9e449e2858
commit 5bceffbeaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
39 changed files with 614 additions and 553 deletions

View File

@ -13,9 +13,6 @@ import (
"github.com/SigNoz/signoz/pkg/alertmanager" "github.com/SigNoz/signoz/pkg/alertmanager"
"github.com/SigNoz/signoz/pkg/apis/fields" "github.com/SigNoz/signoz/pkg/apis/fields"
"github.com/SigNoz/signoz/pkg/http/middleware" "github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/modules/organization/implorganization"
"github.com/SigNoz/signoz/pkg/modules/preference"
preferencecore "github.com/SigNoz/signoz/pkg/modules/preference/core"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app" baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations" "github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations" "github.com/SigNoz/signoz/pkg/query-service/app/integrations"
@ -26,7 +23,6 @@ import (
rules "github.com/SigNoz/signoz/pkg/query-service/rules" rules "github.com/SigNoz/signoz/pkg/query-service/rules"
"github.com/SigNoz/signoz/pkg/signoz" "github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/types/authtypes" "github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
"github.com/SigNoz/signoz/pkg/version" "github.com/SigNoz/signoz/pkg/version"
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )
@ -60,10 +56,6 @@ type APIHandler struct {
// NewAPIHandler returns an APIHandler // NewAPIHandler returns an APIHandler
func NewAPIHandler(opts APIHandlerOptions, signoz *signoz.SigNoz) (*APIHandler, error) { func NewAPIHandler(opts APIHandlerOptions, signoz *signoz.SigNoz) (*APIHandler, error) {
preference := preference.NewAPI(preferencecore.NewPreference(preferencecore.NewStore(signoz.SQLStore), preferencetypes.NewDefaultPreferenceMap()))
organizationAPI := implorganization.NewAPI(implorganization.NewModule(implorganization.NewStore(signoz.SQLStore)))
organizationModule := implorganization.NewModule(implorganization.NewStore(signoz.SQLStore))
baseHandler, err := baseapp.NewAPIHandler(baseapp.APIHandlerOpts{ baseHandler, err := baseapp.NewAPIHandler(baseapp.APIHandlerOpts{
Reader: opts.DataConnector, Reader: opts.DataConnector,
SkipConfig: opts.SkipConfig, SkipConfig: opts.SkipConfig,
@ -81,9 +73,6 @@ func NewAPIHandler(opts APIHandlerOptions, signoz *signoz.SigNoz) (*APIHandler,
AlertmanagerAPI: alertmanager.NewAPI(signoz.Alertmanager), AlertmanagerAPI: alertmanager.NewAPI(signoz.Alertmanager),
FieldsAPI: fields.NewAPI(signoz.TelemetryStore), FieldsAPI: fields.NewAPI(signoz.TelemetryStore),
Signoz: signoz, Signoz: signoz,
Preference: preference,
OrganizationAPI: organizationAPI,
OrganizationModule: organizationModule,
}) })
if err != nil { if err != nil {

View File

@ -134,7 +134,7 @@ func (ah *APIHandler) registerUser(w http.ResponseWriter, r *http.Request) {
return return
} }
_, registerError := baseauth.Register(ctx, req, ah.Signoz.Alertmanager, ah.OrganizationModule) _, registerError := baseauth.Register(ctx, req, ah.Signoz.Alertmanager, ah.Signoz.Modules.Organization)
if !registerError.IsNil() { if !registerError.IsNil() {
RespondError(w, apierr, nil) RespondError(w, apierr, nil)
return return
@ -152,7 +152,7 @@ func (ah *APIHandler) getInvite(w http.ResponseWriter, r *http.Request) {
token := mux.Vars(r)["token"] token := mux.Vars(r)["token"]
sourceUrl := r.URL.Query().Get("ref") sourceUrl := r.URL.Query().Get("ref")
inviteObject, err := baseauth.GetInvite(r.Context(), token, ah.OrganizationModule) inviteObject, err := baseauth.GetInvite(r.Context(), token, ah.Signoz.Modules.Organization)
if err != nil { if err != nil {
RespondError(w, model.BadRequest(err), nil) RespondError(w, model.BadRequest(err), nil)
return return

View File

@ -194,7 +194,7 @@ func (dialect *dialect) RenameColumn(ctx context.Context, bun bun.IDB, table str
} }
if !oldColumnExists { if !oldColumnExists {
return false, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("old column: %s doesn't exist", oldColumnName)) return false, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "old column: %s doesn't exist", oldColumnName)
} }
_, err = bun. _, err = bun.

View File

@ -4,8 +4,10 @@ import (
"context" "context"
"database/sql" "database/sql"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/pgxpool"
"github.com/jackc/pgx/v5/stdlib" "github.com/jackc/pgx/v5/stdlib"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
@ -87,3 +89,20 @@ func (provider *provider) BunDBCtx(ctx context.Context) bun.IDB {
func (provider *provider) RunInTxCtx(ctx context.Context, opts *sql.TxOptions, cb func(ctx context.Context) error) error { func (provider *provider) RunInTxCtx(ctx context.Context, opts *sql.TxOptions, cb func(ctx context.Context) error) error {
return provider.bundb.RunInTxCtx(ctx, opts, cb) return provider.bundb.RunInTxCtx(ctx, opts, cb)
} }
func (provider *provider) WrapNotFoundErrf(err error, code errors.Code, format string, args ...any) error {
if err == sql.ErrNoRows {
return errors.Wrapf(err, errors.TypeNotFound, code, format, args...)
}
return err
}
func (provider *provider) WrapAlreadyExistsErrf(err error, code errors.Code, format string, args ...any) error {
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) && pgErr.Code == "23505" {
return errors.Wrapf(err, errors.TypeAlreadyExists, code, format, args...)
}
return err
}

View File

@ -6,31 +6,31 @@ import (
) )
var ( var (
CodeInvalidInput code = code{"invalid_input"} CodeInvalidInput Code = Code{"invalid_input"}
CodeInternal = code{"internal"} CodeInternal = Code{"internal"}
CodeUnsupported = code{"unsupported"} CodeUnsupported = Code{"unsupported"}
CodeNotFound = code{"not_found"} CodeNotFound = Code{"not_found"}
CodeMethodNotAllowed = code{"method_not_allowed"} CodeMethodNotAllowed = Code{"method_not_allowed"}
CodeAlreadyExists = code{"already_exists"} CodeAlreadyExists = Code{"already_exists"}
CodeUnauthenticated = code{"unauthenticated"} CodeUnauthenticated = Code{"unauthenticated"}
CodeForbidden = code{"forbidden"} CodeForbidden = Code{"forbidden"}
) )
var ( var (
codeRegex = regexp.MustCompile(`^[a-z_]+$`) codeRegex = regexp.MustCompile(`^[a-z_]+$`)
) )
type code struct{ s string } type Code struct{ s string }
func NewCode(s string) (code, error) { func NewCode(s string) (Code, error) {
if !codeRegex.MatchString(s) { if !codeRegex.MatchString(s) {
return code{}, fmt.Errorf("invalid code: %v", s) return Code{}, fmt.Errorf("invalid code: %v", s)
} }
return code{s: s}, nil return Code{s: s}, nil
} }
func MustNewCode(s string) code { func MustNewCode(s string) Code {
code, err := NewCode(s) code, err := NewCode(s)
if err != nil { if err != nil {
panic(err) panic(err)
@ -39,6 +39,6 @@ func MustNewCode(s string) code {
return code return code
} }
func (c code) String() string { func (c Code) String() string {
return c.s return c.s
} }

View File

@ -7,7 +7,7 @@ import (
) )
var ( var (
codeUnknown code = MustNewCode("unknown") codeUnknown Code = MustNewCode("unknown")
) )
// base is the fundamental struct that implements the error interface. // base is the fundamental struct that implements the error interface.
@ -16,7 +16,7 @@ type base struct {
// t denotes the custom type of the error. // t denotes the custom type of the error.
t typ t typ
// c denotes the short code for the error message. // c denotes the short code for the error message.
c code c Code
// m contains error message passed through errors.New. // m contains error message passed through errors.New.
m string m string
// e is the actual error being wrapped. // e is the actual error being wrapped.
@ -47,7 +47,7 @@ func (b *base) Error() string {
} }
// New returns a base error. It requires type, code and message as input. // New returns a base error. It requires type, code and message as input.
func New(t typ, code code, message string) *base { func New(t typ, code Code, message string) *base {
return &base{ return &base{
t: t, t: t,
c: code, c: code,
@ -59,7 +59,7 @@ func New(t typ, code code, message string) *base {
} }
// Newf returns a new base by formatting the error message with the supplied format specifier. // Newf returns a new base by formatting the error message with the supplied format specifier.
func Newf(t typ, code code, format string, args ...interface{}) *base { func Newf(t typ, code Code, format string, args ...interface{}) *base {
return &base{ return &base{
t: t, t: t,
c: code, c: code,
@ -70,7 +70,7 @@ func Newf(t typ, code code, format string, args ...interface{}) *base {
// Wrapf returns a new error by formatting the error message with the supplied format specifier // Wrapf returns a new error by formatting the error message with the supplied format specifier
// and wrapping another error with base. // and wrapping another error with base.
func Wrapf(cause error, t typ, code code, format string, args ...interface{}) *base { func Wrapf(cause error, t typ, code Code, format string, args ...interface{}) *base {
return &base{ return &base{
t: t, t: t,
c: code, c: code,
@ -110,7 +110,7 @@ func (b *base) WithAdditional(a ...string) *base {
// and the error itself. // and the error itself.
// //
//lint:ignore ST1008 we want to return arguments in the 'TCMEUA' order of the struct //lint:ignore ST1008 we want to return arguments in the 'TCMEUA' order of the struct
func Unwrapb(cause error) (typ, code, string, error, string, []string) { func Unwrapb(cause error) (typ, Code, string, error, string, []string) {
base, ok := cause.(*base) base, ok := cause.(*base)
if ok { if ok {
return base.t, base.c, base.m, base.e, base.u, base.a return base.t, base.c, base.m, base.e, base.u, base.a
@ -127,7 +127,7 @@ func Ast(cause error, typ typ) bool {
} }
// Ast checks if the provided error matches the specified custom error code. // Ast checks if the provided error matches the specified custom error code.
func Asc(cause error, code code) bool { func Asc(cause error, code Code) bool {
_, c, _, _, _, _ := Unwrapb(cause) _, c, _, _, _, _ := Unwrapb(cause)
return c.s == code.s return c.s == code.s
@ -137,3 +137,7 @@ func Asc(cause error, code code) bool {
func Join(errs ...error) error { func Join(errs ...error) error {
return errors.Join(errs...) return errors.Join(errs...)
} }
func As(err error, target any) bool {
return errors.As(err, target)
}

View File

@ -1,8 +1,10 @@
package implorganization package implorganization
import ( import (
"context"
"encoding/json" "encoding/json"
"net/http" "net/http"
"time"
"github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/http/render" "github.com/SigNoz/signoz/pkg/http/render"
@ -12,16 +14,19 @@ import (
"github.com/SigNoz/signoz/pkg/valuer" "github.com/SigNoz/signoz/pkg/valuer"
) )
type organizationAPI struct { type handler struct {
module organization.Module module organization.Module
} }
func NewAPI(module organization.Module) organization.API { func NewHandler(module organization.Module) organization.Handler {
return &organizationAPI{module: module} return &handler{module: module}
} }
func (api *organizationAPI) Get(rw http.ResponseWriter, r *http.Request) { func (handler *handler) Get(rw http.ResponseWriter, r *http.Request) {
claims, err := authtypes.ClaimsFromContext(r.Context()) ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil { if err != nil {
render.Error(rw, err) render.Error(rw, err)
return return
@ -29,11 +34,11 @@ func (api *organizationAPI) Get(rw http.ResponseWriter, r *http.Request) {
orgID, err := valuer.NewUUID(claims.OrgID) orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil { if err != nil {
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "invalid org id")) render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "orgId is invalid"))
return return
} }
organization, err := api.module.Get(r.Context(), orgID) organization, err := handler.module.Get(ctx, orgID)
if err != nil { if err != nil {
render.Error(rw, err) render.Error(rw, err)
return return
@ -42,18 +47,11 @@ func (api *organizationAPI) Get(rw http.ResponseWriter, r *http.Request) {
render.Success(rw, http.StatusOK, organization) render.Success(rw, http.StatusOK, organization)
} }
func (api *organizationAPI) GetAll(rw http.ResponseWriter, r *http.Request) { func (handler *handler) Update(rw http.ResponseWriter, r *http.Request) {
organizations, err := api.module.GetAll(r.Context()) ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
if err != nil { defer cancel()
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, organizations) claims, err := authtypes.ClaimsFromContext(ctx)
}
func (api *organizationAPI) Update(rw http.ResponseWriter, r *http.Request) {
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil { if err != nil {
render.Error(rw, err) render.Error(rw, err)
return return
@ -72,7 +70,7 @@ func (api *organizationAPI) Update(rw http.ResponseWriter, r *http.Request) {
} }
req.ID = orgID req.ID = orgID
err = api.module.Update(r.Context(), req) err = handler.module.Update(ctx, req)
if err != nil { if err != nil {
render.Error(rw, err) render.Error(rw, err)
return return

View File

@ -8,26 +8,26 @@ import (
"github.com/SigNoz/signoz/pkg/valuer" "github.com/SigNoz/signoz/pkg/valuer"
) )
type organizationModule struct { type module struct {
store types.OrganizationStore store types.OrganizationStore
} }
func NewModule(organizationStore types.OrganizationStore) organization.Module { func NewModule(organizationStore types.OrganizationStore) organization.Module {
return &organizationModule{store: organizationStore} return &module{store: organizationStore}
} }
func (o *organizationModule) Create(ctx context.Context, organization *types.Organization) error { func (module *module) Create(ctx context.Context, organization *types.Organization) error {
return o.store.Create(ctx, organization) return module.store.Create(ctx, organization)
} }
func (o *organizationModule) Get(ctx context.Context, id valuer.UUID) (*types.Organization, error) { func (module *module) Get(ctx context.Context, id valuer.UUID) (*types.Organization, error) {
return o.store.Get(ctx, id) return module.store.Get(ctx, id)
} }
func (o *organizationModule) GetAll(ctx context.Context) ([]*types.Organization, error) { func (module *module) GetAll(ctx context.Context) ([]*types.Organization, error) {
return o.store.GetAll(ctx) return module.store.GetAll(ctx)
} }
func (o *organizationModule) Update(ctx context.Context, updatedOrganization *types.Organization) error { func (module *module) Update(ctx context.Context, updatedOrganization *types.Organization) error {
return o.store.Update(ctx, updatedOrganization) return module.store.Update(ctx, updatedOrganization)
} }

View File

@ -2,77 +2,69 @@ package implorganization
import ( import (
"context" "context"
"database/sql"
"time" "time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/valuer" "github.com/SigNoz/signoz/pkg/valuer"
) )
type store struct { type store struct {
store sqlstore.SQLStore sqlstore sqlstore.SQLStore
} }
func NewStore(db sqlstore.SQLStore) types.OrganizationStore { func NewStore(sqlstore sqlstore.SQLStore) types.OrganizationStore {
return &store{store: db} return &store{sqlstore: sqlstore}
} }
func (s *store) Create(ctx context.Context, organization *types.Organization) error { func (store *store) Create(ctx context.Context, organization *types.Organization) error {
_, err := s. _, err := store.
store. sqlstore.
BunDB(). BunDB().
NewInsert(). NewInsert().
Model(organization). Model(organization).
Exec(ctx) Exec(ctx)
if err != nil { if err != nil {
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to create organization") return store.sqlstore.WrapAlreadyExistsErrf(err, types.ErrOrganizationAlreadyExists, "organization with name: %s already exists", organization.Name)
} }
return nil return nil
} }
func (s *store) Get(ctx context.Context, id valuer.UUID) (*types.Organization, error) { func (store *store) Get(ctx context.Context, id valuer.UUID) (*types.Organization, error) {
organization := new(types.Organization) organization := new(types.Organization)
err := s. err := store.
store. sqlstore.
BunDB(). BunDB().
NewSelect(). NewSelect().
Model(organization). Model(organization).
Where("id = ?", id.StringValue()). Where("id = ?", id.StringValue()).
Scan(ctx) Scan(ctx)
if err != nil { if err != nil {
if err == sql.ErrNoRows { return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrOrganizationNotFound, "organization with id: %s does not exist", id.StringValue())
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "no organization found with id: %s", id.StringValue())
}
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to get organization with id: %s", id.StringValue())
} }
return organization, nil return organization, nil
} }
func (s *store) GetAll(ctx context.Context) ([]*types.Organization, error) { func (store *store) GetAll(ctx context.Context) ([]*types.Organization, error) {
organizations := make([]*types.Organization, 0) organizations := make([]*types.Organization, 0)
err := s. err := store.
store. sqlstore.
BunDB(). BunDB().
NewSelect(). NewSelect().
Model(&organizations). Model(&organizations).
Scan(ctx) Scan(ctx)
if err != nil { if err != nil {
if err == sql.ErrNoRows { return nil, err
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "no organizations found")
}
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to get all organizations")
} }
return organizations, nil return organizations, nil
} }
func (s *store) Update(ctx context.Context, organization *types.Organization) error { func (store *store) Update(ctx context.Context, organization *types.Organization) error {
_, err := s. _, err := store.
store. sqlstore.
BunDB(). BunDB().
NewUpdate(). NewUpdate().
Model(organization). Model(organization).
@ -81,21 +73,21 @@ func (s *store) Update(ctx context.Context, organization *types.Organization) er
Where("id = ?", organization.ID.StringValue()). Where("id = ?", organization.ID.StringValue()).
Exec(ctx) Exec(ctx)
if err != nil { if err != nil {
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to update organization with id: %s", organization.ID.StringValue()) return store.sqlstore.WrapAlreadyExistsErrf(err, types.ErrOrganizationAlreadyExists, "organization already exists")
} }
return nil return nil
} }
func (s *store) Delete(ctx context.Context, id valuer.UUID) error { func (store *store) Delete(ctx context.Context, id valuer.UUID) error {
_, err := s. _, err := store.
store. sqlstore.
BunDB(). BunDB().
NewDelete(). NewDelete().
Model(new(types.Organization)). Model(new(types.Organization)).
Where("id = ?", id.StringValue()). Where("id = ?", id.StringValue()).
Exec(ctx) Exec(ctx)
if err != nil { if err != nil {
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to delete organization with id: %s", id.StringValue()) return err
} }
return nil return nil

View File

@ -22,13 +22,10 @@ type Module interface {
Update(context.Context, *types.Organization) error Update(context.Context, *types.Organization) error
} }
type API interface { type Handler interface {
// Get gets the organization based on the id in claims // Get gets the organization based on the id in claims
Get(http.ResponseWriter, *http.Request) Get(http.ResponseWriter, *http.Request)
// GetAll gets all the organizations
GetAll(http.ResponseWriter, *http.Request)
// Update updates the organization based on the id in claims // Update updates the organization based on the id in claims
Update(http.ResponseWriter, *http.Request) Update(http.ResponseWriter, *http.Request)
} }

View File

@ -1,147 +0,0 @@
package preference
import (
"encoding/json"
"net/http"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
"github.com/gorilla/mux"
)
type API interface {
GetOrgPreference(http.ResponseWriter, *http.Request)
UpdateOrgPreference(http.ResponseWriter, *http.Request)
GetAllOrgPreferences(http.ResponseWriter, *http.Request)
GetUserPreference(http.ResponseWriter, *http.Request)
UpdateUserPreference(http.ResponseWriter, *http.Request)
GetAllUserPreferences(http.ResponseWriter, *http.Request)
}
type preferenceAPI struct {
usecase Usecase
}
func NewAPI(usecase Usecase) API {
return &preferenceAPI{usecase: usecase}
}
func (p *preferenceAPI) GetOrgPreference(rw http.ResponseWriter, r *http.Request) {
preferenceId := mux.Vars(r)["preferenceId"]
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(rw, err)
return
}
preference, err := p.usecase.GetOrgPreference(
r.Context(), preferenceId, claims.OrgID,
)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, preference)
}
func (p *preferenceAPI) UpdateOrgPreference(rw http.ResponseWriter, r *http.Request) {
preferenceId := mux.Vars(r)["preferenceId"]
req := preferencetypes.UpdatablePreference{}
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(rw, err)
return
}
err = json.NewDecoder(r.Body).Decode(&req)
if err != nil {
render.Error(rw, err)
return
}
err = p.usecase.UpdateOrgPreference(r.Context(), preferenceId, req.PreferenceValue, claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusNoContent, nil)
}
func (p *preferenceAPI) GetAllOrgPreferences(rw http.ResponseWriter, r *http.Request) {
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(rw, err)
return
}
preferences, err := p.usecase.GetAllOrgPreferences(
r.Context(), claims.OrgID,
)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, preferences)
}
func (p *preferenceAPI) GetUserPreference(rw http.ResponseWriter, r *http.Request) {
preferenceId := mux.Vars(r)["preferenceId"]
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(rw, err)
return
}
preference, err := p.usecase.GetUserPreference(
r.Context(), preferenceId, claims.OrgID, claims.UserID,
)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, preference)
}
func (p *preferenceAPI) UpdateUserPreference(rw http.ResponseWriter, r *http.Request) {
preferenceId := mux.Vars(r)["preferenceId"]
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(rw, err)
return
}
req := preferencetypes.UpdatablePreference{}
err = json.NewDecoder(r.Body).Decode(&req)
if err != nil {
render.Error(rw, err)
return
}
err = p.usecase.UpdateUserPreference(r.Context(), preferenceId, req.PreferenceValue, claims.UserID)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusNoContent, nil)
}
func (p *preferenceAPI) GetAllUserPreferences(rw http.ResponseWriter, r *http.Request) {
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(rw, err)
return
}
preferences, err := p.usecase.GetAllUserPreferences(
r.Context(), claims.OrgID, claims.UserID,
)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, preferences)
}

View File

@ -0,0 +1,176 @@
package implpreference
import (
"context"
"encoding/json"
"net/http"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/modules/preference"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
"github.com/gorilla/mux"
)
type handler struct {
module preference.Module
}
func NewHandler(module preference.Module) preference.Handler {
return &handler{module: module}
}
func (handler *handler) GetOrg(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
id, ok := mux.Vars(r)["preferenceId"]
if !ok {
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
return
}
preference, err := handler.module.GetOrg(ctx, id, claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, preference)
}
func (handler *handler) UpdateOrg(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
id, ok := mux.Vars(r)["preferenceId"]
if !ok {
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
return
}
req := new(preferencetypes.UpdatablePreference)
err = json.NewDecoder(r.Body).Decode(req)
if err != nil {
render.Error(rw, err)
return
}
err = handler.module.UpdateOrg(ctx, id, req.PreferenceValue, claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusNoContent, nil)
}
func (handler *handler) GetAllOrg(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
preferences, err := handler.module.GetAllOrg(ctx, claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, preferences)
}
func (handler *handler) GetUser(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
id, ok := mux.Vars(r)["preferenceId"]
if !ok {
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
return
}
preference, err := handler.module.GetUser(ctx, id, claims.OrgID, claims.UserID)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, preference)
}
func (handler *handler) UpdateUser(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
id, ok := mux.Vars(r)["preferenceId"]
if !ok {
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
return
}
req := new(preferencetypes.UpdatablePreference)
err = json.NewDecoder(r.Body).Decode(req)
if err != nil {
render.Error(rw, err)
return
}
err = handler.module.UpdateUser(ctx, id, req.PreferenceValue, claims.UserID)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusNoContent, nil)
}
func (handler *handler) GetAllUser(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
preferences, err := handler.module.GetAllUser(ctx, claims.OrgID, claims.UserID)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, preferences)
}

View File

@ -1,10 +1,9 @@
package core package implpreference
import ( import (
"context" "context"
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt"
"github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/modules/preference" "github.com/SigNoz/signoz/pkg/modules/preference"
@ -12,27 +11,28 @@ import (
"github.com/SigNoz/signoz/pkg/valuer" "github.com/SigNoz/signoz/pkg/valuer"
) )
type usecase struct { // Do not take inspiration from this code, it is a work in progress. See Organization module for a better implementation.
store preferencetypes.PreferenceStore type module struct {
store preferencetypes.Store
defaultMap map[string]preferencetypes.Preference defaultMap map[string]preferencetypes.Preference
} }
func NewPreference(store preferencetypes.PreferenceStore, defaultMap map[string]preferencetypes.Preference) preference.Usecase { func NewModule(store preferencetypes.Store, defaultMap map[string]preferencetypes.Preference) preference.Module {
return &usecase{store: store, defaultMap: defaultMap} return &module{store: store, defaultMap: defaultMap}
} }
func (usecase *usecase) GetOrgPreference(ctx context.Context, preferenceID string, orgID string) (*preferencetypes.GettablePreference, error) { func (module *module) GetOrg(ctx context.Context, preferenceID string, orgID string) (*preferencetypes.GettablePreference, error) {
preference, seen := usecase.defaultMap[preferenceID] preference, seen := module.defaultMap[preferenceID]
if !seen { if !seen {
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("no such preferenceID exists: %s", preferenceID)) return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID)
} }
isPreferenceEnabled := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) isEnabled := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope)
if !isPreferenceEnabled { if !isEnabled {
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("preference is not enabled at org scope: %s", preferenceID)) return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at org scope: %s", preferenceID)
} }
orgPreference, err := usecase.store.GetOrgPreference(ctx, orgID, preferenceID) org, err := module.store.GetOrg(ctx, orgID, preferenceID)
if err != nil { if err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return &preferencetypes.GettablePreference{ return &preferencetypes.GettablePreference{
@ -40,24 +40,24 @@ func (usecase *usecase) GetOrgPreference(ctx context.Context, preferenceID strin
PreferenceValue: preference.DefaultValue, PreferenceValue: preference.DefaultValue,
}, nil }, nil
} }
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, fmt.Sprintf("error in fetching the org preference: %s", preferenceID)) return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in fetching the org preference: %s", preferenceID)
} }
return &preferencetypes.GettablePreference{ return &preferencetypes.GettablePreference{
PreferenceID: preferenceID, PreferenceID: preferenceID,
PreferenceValue: preference.SanitizeValue(orgPreference.PreferenceValue), PreferenceValue: preference.SanitizeValue(org.PreferenceValue),
}, nil }, nil
} }
func (usecase *usecase) UpdateOrgPreference(ctx context.Context, preferenceID string, preferenceValue interface{}, orgID string) error { func (module *module) UpdateOrg(ctx context.Context, preferenceID string, preferenceValue interface{}, orgID string) error {
preference, seen := usecase.defaultMap[preferenceID] preference, seen := module.defaultMap[preferenceID]
if !seen { if !seen {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("no such preferenceID exists: %s", preferenceID)) return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID)
} }
isPreferenceEnabled := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) isEnabled := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope)
if !isPreferenceEnabled { if !isEnabled {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("preference is not enabled at org scope: %s", preferenceID)) return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at org scope: %s", preferenceID)
} }
err := preference.IsValidValue(preferenceValue) err := preference.IsValidValue(preferenceValue)
@ -65,26 +65,26 @@ func (usecase *usecase) UpdateOrgPreference(ctx context.Context, preferenceID st
return err return err
} }
storablePreferenceValue, encodeErr := json.Marshal(preferenceValue) storableValue, encodeErr := json.Marshal(preferenceValue)
if encodeErr != nil { if encodeErr != nil {
return errors.Wrapf(encodeErr, errors.TypeInvalidInput, errors.CodeInvalidInput, "error in encoding the preference value") return errors.Wrapf(encodeErr, errors.TypeInvalidInput, errors.CodeInvalidInput, "error in encoding the preference value")
} }
orgPreference, dberr := usecase.store.GetOrgPreference(ctx, orgID, preferenceID) org, dberr := module.store.GetOrg(ctx, orgID, preferenceID)
if dberr != nil && dberr != sql.ErrNoRows { if dberr != nil && dberr != sql.ErrNoRows {
return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in getting the preference value") return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in getting the preference value")
} }
if dberr != nil { if dberr != nil {
orgPreference.ID = valuer.GenerateUUID() org.ID = valuer.GenerateUUID()
orgPreference.PreferenceID = preferenceID org.PreferenceID = preferenceID
orgPreference.PreferenceValue = string(storablePreferenceValue) org.PreferenceValue = string(storableValue)
orgPreference.OrgID = orgID org.OrgID = orgID
} else { } else {
orgPreference.PreferenceValue = string(storablePreferenceValue) org.PreferenceValue = string(storableValue)
} }
dberr = usecase.store.UpsertOrgPreference(ctx, orgPreference) dberr = module.store.UpsertOrg(ctx, org)
if dberr != nil { if dberr != nil {
return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in setting the preference value") return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in setting the preference value")
} }
@ -92,19 +92,19 @@ func (usecase *usecase) UpdateOrgPreference(ctx context.Context, preferenceID st
return nil return nil
} }
func (usecase *usecase) GetAllOrgPreferences(ctx context.Context, orgID string) ([]*preferencetypes.PreferenceWithValue, error) { func (module *module) GetAllOrg(ctx context.Context, orgID string) ([]*preferencetypes.PreferenceWithValue, error) {
allOrgPreferences := []*preferencetypes.PreferenceWithValue{} allOrgs := []*preferencetypes.PreferenceWithValue{}
orgPreferences, err := usecase.store.GetAllOrgPreferences(ctx, orgID) orgs, err := module.store.GetAllOrg(ctx, orgID)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all org preference values") return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all org preference values")
} }
preferenceValueMap := map[string]interface{}{} preferenceValueMap := map[string]interface{}{}
for _, preferenceValue := range orgPreferences { for _, preferenceValue := range orgs {
preferenceValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue preferenceValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue
} }
for _, preference := range usecase.defaultMap { for _, preference := range module.defaultMap {
isEnabledForOrgScope := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) isEnabledForOrgScope := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope)
if isEnabledForOrgScope { if isEnabledForOrgScope {
preferenceWithValue := &preferencetypes.PreferenceWithValue{} preferenceWithValue := &preferencetypes.PreferenceWithValue{}
@ -126,16 +126,16 @@ func (usecase *usecase) GetAllOrgPreferences(ctx context.Context, orgID string)
} }
preferenceWithValue.Value = preference.SanitizeValue(preferenceWithValue.Value) preferenceWithValue.Value = preference.SanitizeValue(preferenceWithValue.Value)
allOrgPreferences = append(allOrgPreferences, preferenceWithValue) allOrgs = append(allOrgs, preferenceWithValue)
} }
} }
return allOrgPreferences, nil return allOrgs, nil
} }
func (usecase *usecase) GetUserPreference(ctx context.Context, preferenceID string, orgID string, userID string) (*preferencetypes.GettablePreference, error) { func (module *module) GetUser(ctx context.Context, preferenceID string, orgID string, userID string) (*preferencetypes.GettablePreference, error) {
preference, seen := usecase.defaultMap[preferenceID] preference, seen := module.defaultMap[preferenceID]
if !seen { if !seen {
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("no such preferenceID exists: %s", preferenceID)) return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID)
} }
preferenceValue := preferencetypes.GettablePreference{ preferenceValue := preferencetypes.GettablePreference{
@ -143,29 +143,29 @@ func (usecase *usecase) GetUserPreference(ctx context.Context, preferenceID stri
PreferenceValue: preference.DefaultValue, PreferenceValue: preference.DefaultValue,
} }
isPreferenceEnabledAtUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope) isEnabledAtUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope)
if !isPreferenceEnabledAtUserScope { if !isEnabledAtUserScope {
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("preference is not enabled at user scope: %s", preferenceID)) return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at user scope: %s", preferenceID)
} }
isPreferenceEnabledAtOrgScope := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) isEnabledAtOrgScope := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope)
if isPreferenceEnabledAtOrgScope { if isEnabledAtOrgScope {
orgPreference, err := usecase.store.GetOrgPreference(ctx, orgID, preferenceID) org, err := module.store.GetOrg(ctx, orgID, preferenceID)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, fmt.Sprintf("error in fetching the org preference: %s", preferenceID)) return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in fetching the org preference: %s", preferenceID)
} }
if err == nil { if err == nil {
preferenceValue.PreferenceValue = orgPreference.PreferenceValue preferenceValue.PreferenceValue = org.PreferenceValue
} }
} }
userPreference, err := usecase.store.GetUserPreference(ctx, userID, preferenceID) user, err := module.store.GetUser(ctx, userID, preferenceID)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, fmt.Sprintf("error in fetching the user preference: %s", preferenceID)) return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in fetching the user preference: %s", preferenceID)
} }
if err == nil { if err == nil {
preferenceValue.PreferenceValue = userPreference.PreferenceValue preferenceValue.PreferenceValue = user.PreferenceValue
} }
return &preferencetypes.GettablePreference{ return &preferencetypes.GettablePreference{
@ -174,15 +174,15 @@ func (usecase *usecase) GetUserPreference(ctx context.Context, preferenceID stri
}, nil }, nil
} }
func (usecase *usecase) UpdateUserPreference(ctx context.Context, preferenceID string, preferenceValue interface{}, userID string) error { func (module *module) UpdateUser(ctx context.Context, preferenceID string, preferenceValue interface{}, userID string) error {
preference, seen := usecase.defaultMap[preferenceID] preference, seen := module.defaultMap[preferenceID]
if !seen { if !seen {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("no such preferenceID exists: %s", preferenceID)) return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID)
} }
isPreferenceEnabledAtUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope) isEnabledAtUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope)
if !isPreferenceEnabledAtUserScope { if !isEnabledAtUserScope {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("preference is not enabled at user scope: %s", preferenceID)) return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at user scope: %s", preferenceID)
} }
err := preference.IsValidValue(preferenceValue) err := preference.IsValidValue(preferenceValue)
@ -190,26 +190,26 @@ func (usecase *usecase) UpdateUserPreference(ctx context.Context, preferenceID s
return err return err
} }
storablePreferenceValue, encodeErr := json.Marshal(preferenceValue) storableValue, encodeErr := json.Marshal(preferenceValue)
if encodeErr != nil { if encodeErr != nil {
return errors.Wrapf(encodeErr, errors.TypeInvalidInput, errors.CodeInvalidInput, "error in encoding the preference value") return errors.Wrapf(encodeErr, errors.TypeInvalidInput, errors.CodeInvalidInput, "error in encoding the preference value")
} }
userPreference, dberr := usecase.store.GetUserPreference(ctx, userID, preferenceID) user, dberr := module.store.GetUser(ctx, userID, preferenceID)
if dberr != nil && dberr != sql.ErrNoRows { if dberr != nil && dberr != sql.ErrNoRows {
return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in getting the preference value") return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in getting the preference value")
} }
if dberr != nil { if dberr != nil {
userPreference.ID = valuer.GenerateUUID() user.ID = valuer.GenerateUUID()
userPreference.PreferenceID = preferenceID user.PreferenceID = preferenceID
userPreference.PreferenceValue = string(storablePreferenceValue) user.PreferenceValue = string(storableValue)
userPreference.UserID = userID user.UserID = userID
} else { } else {
userPreference.PreferenceValue = string(storablePreferenceValue) user.PreferenceValue = string(storableValue)
} }
dberr = usecase.store.UpsertUserPreference(ctx, userPreference) dberr = module.store.UpsertUser(ctx, user)
if dberr != nil { if dberr != nil {
return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in setting the preference value") return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in setting the preference value")
} }
@ -217,30 +217,30 @@ func (usecase *usecase) UpdateUserPreference(ctx context.Context, preferenceID s
return nil return nil
} }
func (usecase *usecase) GetAllUserPreferences(ctx context.Context, orgID string, userID string) ([]*preferencetypes.PreferenceWithValue, error) { func (module *module) GetAllUser(ctx context.Context, orgID string, userID string) ([]*preferencetypes.PreferenceWithValue, error) {
allUserPreferences := []*preferencetypes.PreferenceWithValue{} allUsers := []*preferencetypes.PreferenceWithValue{}
orgPreferences, err := usecase.store.GetAllOrgPreferences(ctx, orgID) orgs, err := module.store.GetAllOrg(ctx, orgID)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all org preference values") return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all org preference values")
} }
preferenceOrgValueMap := map[string]interface{}{} preferenceOrgValueMap := map[string]interface{}{}
for _, preferenceValue := range orgPreferences { for _, preferenceValue := range orgs {
preferenceOrgValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue preferenceOrgValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue
} }
userPreferences, err := usecase.store.GetAllUserPreferences(ctx, userID) users, err := module.store.GetAllUser(ctx, userID)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all user preference values") return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all user preference values")
} }
preferenceUserValueMap := map[string]interface{}{} preferenceUserValueMap := map[string]interface{}{}
for _, preferenceValue := range userPreferences { for _, preferenceValue := range users {
preferenceUserValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue preferenceUserValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue
} }
for _, preference := range usecase.defaultMap { for _, preference := range module.defaultMap {
isEnabledForUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope) isEnabledForUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope)
if isEnabledForUserScope { if isEnabledForUserScope {
@ -271,8 +271,8 @@ func (usecase *usecase) GetAllUserPreferences(ctx context.Context, orgID string,
} }
preferenceWithValue.Value = preference.SanitizeValue(preferenceWithValue.Value) preferenceWithValue.Value = preference.SanitizeValue(preferenceWithValue.Value)
allUserPreferences = append(allUserPreferences, preferenceWithValue) allUsers = append(allUsers, preferenceWithValue)
} }
} }
return allUserPreferences, nil return allUsers, nil
} }

View File

@ -1,4 +1,4 @@
package core package implpreference
import ( import (
"context" "context"
@ -11,11 +11,11 @@ type store struct {
store sqlstore.SQLStore store sqlstore.SQLStore
} }
func NewStore(db sqlstore.SQLStore) preferencetypes.PreferenceStore { func NewStore(db sqlstore.SQLStore) preferencetypes.Store {
return &store{store: db} return &store{store: db}
} }
func (store *store) GetOrgPreference(ctx context.Context, orgID string, preferenceID string) (*preferencetypes.StorableOrgPreference, error) { func (store *store) GetOrg(ctx context.Context, orgID string, preferenceID string) (*preferencetypes.StorableOrgPreference, error) {
orgPreference := new(preferencetypes.StorableOrgPreference) orgPreference := new(preferencetypes.StorableOrgPreference)
err := store. err := store.
store. store.
@ -33,7 +33,7 @@ func (store *store) GetOrgPreference(ctx context.Context, orgID string, preferen
return orgPreference, nil return orgPreference, nil
} }
func (store *store) GetAllOrgPreferences(ctx context.Context, orgID string) ([]*preferencetypes.StorableOrgPreference, error) { func (store *store) GetAllOrg(ctx context.Context, orgID string) ([]*preferencetypes.StorableOrgPreference, error) {
orgPreferences := make([]*preferencetypes.StorableOrgPreference, 0) orgPreferences := make([]*preferencetypes.StorableOrgPreference, 0)
err := store. err := store.
store. store.
@ -50,7 +50,7 @@ func (store *store) GetAllOrgPreferences(ctx context.Context, orgID string) ([]*
return orgPreferences, nil return orgPreferences, nil
} }
func (store *store) UpsertOrgPreference(ctx context.Context, orgPreference *preferencetypes.StorableOrgPreference) error { func (store *store) UpsertOrg(ctx context.Context, orgPreference *preferencetypes.StorableOrgPreference) error {
_, err := store. _, err := store.
store. store.
BunDB(). BunDB().
@ -65,7 +65,7 @@ func (store *store) UpsertOrgPreference(ctx context.Context, orgPreference *pref
return nil return nil
} }
func (store *store) GetUserPreference(ctx context.Context, userID string, preferenceID string) (*preferencetypes.StorableUserPreference, error) { func (store *store) GetUser(ctx context.Context, userID string, preferenceID string) (*preferencetypes.StorableUserPreference, error) {
userPreference := new(preferencetypes.StorableUserPreference) userPreference := new(preferencetypes.StorableUserPreference)
err := store. err := store.
store. store.
@ -83,7 +83,7 @@ func (store *store) GetUserPreference(ctx context.Context, userID string, prefer
return userPreference, nil return userPreference, nil
} }
func (store *store) GetAllUserPreferences(ctx context.Context, userID string) ([]*preferencetypes.StorableUserPreference, error) { func (store *store) GetAllUser(ctx context.Context, userID string) ([]*preferencetypes.StorableUserPreference, error) {
userPreferences := make([]*preferencetypes.StorableUserPreference, 0) userPreferences := make([]*preferencetypes.StorableUserPreference, 0)
err := store. err := store.
store. store.
@ -100,7 +100,7 @@ func (store *store) GetAllUserPreferences(ctx context.Context, userID string) ([
return userPreferences, nil return userPreferences, nil
} }
func (store *store) UpsertUserPreference(ctx context.Context, userPreference *preferencetypes.StorableUserPreference) error { func (store *store) UpsertUser(ctx context.Context, userPreference *preferencetypes.StorableUserPreference) error {
_, err := store. _, err := store.
store. store.
BunDB(). BunDB().

View File

@ -0,0 +1,48 @@
package preference
import (
"context"
"net/http"
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
)
type Module interface {
// Returns the preference for the given organization
GetOrg(ctx context.Context, preferenceId string, orgId string) (*preferencetypes.GettablePreference, error)
// Returns the preference for the given user
GetUser(ctx context.Context, preferenceId string, orgId string, userId string) (*preferencetypes.GettablePreference, error)
// Returns all preferences for the given organization
GetAllOrg(ctx context.Context, orgId string) ([]*preferencetypes.PreferenceWithValue, error)
// Returns all preferences for the given user
GetAllUser(ctx context.Context, orgId string, userId string) ([]*preferencetypes.PreferenceWithValue, error)
// Updates the preference for the given organization
UpdateOrg(ctx context.Context, preferenceId string, preferenceValue interface{}, orgId string) error
// Updates the preference for the given user
UpdateUser(ctx context.Context, preferenceId string, preferenceValue interface{}, userId string) error
}
type Handler interface {
// Returns the preference for the given organization
GetOrg(http.ResponseWriter, *http.Request)
// Updates the preference for the given organization
UpdateOrg(http.ResponseWriter, *http.Request)
// Returns all preferences for the given organization
GetAllOrg(http.ResponseWriter, *http.Request)
// Returns the preference for the given user
GetUser(http.ResponseWriter, *http.Request)
// Updates the preference for the given user
UpdateUser(http.ResponseWriter, *http.Request)
// Returns all preferences for the given user
GetAllUser(http.ResponseWriter, *http.Request)
}

View File

@ -1,16 +0,0 @@
package preference
import (
"context"
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
)
type Usecase interface {
GetOrgPreference(ctx context.Context, preferenceId string, orgId string) (*preferencetypes.GettablePreference, error)
UpdateOrgPreference(ctx context.Context, preferenceId string, preferenceValue interface{}, orgId string) error
GetAllOrgPreferences(ctx context.Context, orgId string) ([]*preferencetypes.PreferenceWithValue, error)
GetUserPreference(ctx context.Context, preferenceId string, orgId string, userId string) (*preferencetypes.GettablePreference, error)
UpdateUserPreference(ctx context.Context, preferenceId string, preferenceValue interface{}, userId string) error
GetAllUserPreferences(ctx context.Context, orgId string, userId string) ([]*preferencetypes.PreferenceWithValue, error)
}

View File

@ -23,8 +23,6 @@ import (
errorsV2 "github.com/SigNoz/signoz/pkg/errors" errorsV2 "github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/http/middleware" "github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/http/render" "github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/preference"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations" "github.com/SigNoz/signoz/pkg/query-service/app/integrations"
"github.com/SigNoz/signoz/pkg/query-service/app/metricsexplorer" "github.com/SigNoz/signoz/pkg/query-service/app/metricsexplorer"
"github.com/SigNoz/signoz/pkg/signoz" "github.com/SigNoz/signoz/pkg/signoz"
@ -147,11 +145,6 @@ type APIHandler struct {
FieldsAPI *fields.API FieldsAPI *fields.API
Signoz *signoz.SigNoz Signoz *signoz.SigNoz
Preference preference.API
OrganizationAPI organization.API
OrganizationModule organization.Module
} }
type APIHandlerOpts struct { type APIHandlerOpts struct {
@ -199,10 +192,6 @@ type APIHandlerOpts struct {
FieldsAPI *fields.API FieldsAPI *fields.API
Signoz *signoz.SigNoz Signoz *signoz.SigNoz
Preference preference.API
OrganizationAPI organization.API
OrganizationModule organization.Module
} }
// NewAPIHandler returns an APIHandler // NewAPIHandler returns an APIHandler
@ -271,10 +260,7 @@ func NewAPIHandler(opts APIHandlerOpts) (*APIHandler, error) {
SummaryService: summaryService, SummaryService: summaryService,
AlertmanagerAPI: opts.AlertmanagerAPI, AlertmanagerAPI: opts.AlertmanagerAPI,
Signoz: opts.Signoz, Signoz: opts.Signoz,
Preference: opts.Preference,
FieldsAPI: opts.FieldsAPI, FieldsAPI: opts.FieldsAPI,
OrganizationAPI: opts.OrganizationAPI,
OrganizationModule: opts.OrganizationModule,
} }
logsQueryBuilder := logsv3.PrepareLogsQuery logsQueryBuilder := logsv3.PrepareLogsQuery
@ -596,23 +582,13 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *middleware.AuthZ) {
router.HandleFunc("/api/v1/disks", am.ViewAccess(aH.getDisks)).Methods(http.MethodGet) router.HandleFunc("/api/v1/disks", am.ViewAccess(aH.getDisks)).Methods(http.MethodGet)
// === Preference APIs === router.HandleFunc("/api/v1/user/preferences", am.ViewAccess(aH.Signoz.Handlers.Preference.GetAllUser)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/user/preferences/{preferenceId}", am.ViewAccess(aH.Signoz.Handlers.Preference.GetUser)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/user/preferences/{preferenceId}", am.ViewAccess(aH.Signoz.Handlers.Preference.UpdateUser)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/org/preferences", am.AdminAccess(aH.Signoz.Handlers.Preference.GetAllOrg)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/org/preferences/{preferenceId}", am.AdminAccess(aH.Signoz.Handlers.Preference.GetOrg)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/org/preferences/{preferenceId}", am.AdminAccess(aH.Signoz.Handlers.Preference.UpdateOrg)).Methods(http.MethodPut)
// user actions
router.HandleFunc("/api/v1/user/preferences", am.ViewAccess(aH.getAllUserPreferences)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/user/preferences/{preferenceId}", am.ViewAccess(aH.getUserPreference)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/user/preferences/{preferenceId}", am.ViewAccess(aH.updateUserPreference)).Methods(http.MethodPut)
// org actions
router.HandleFunc("/api/v1/org/preferences", am.AdminAccess(aH.getAllOrgPreferences)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/org/preferences/{preferenceId}", am.AdminAccess(aH.getOrgPreference)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/org/preferences/{preferenceId}", am.AdminAccess(aH.updateOrgPreference)).Methods(http.MethodPut)
// === Authentication APIs ===
router.HandleFunc("/api/v1/invite", am.AdminAccess(aH.inviteUser)).Methods(http.MethodPost) router.HandleFunc("/api/v1/invite", am.AdminAccess(aH.inviteUser)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/invite/bulk", am.AdminAccess(aH.inviteUsers)).Methods(http.MethodPost) router.HandleFunc("/api/v1/invite/bulk", am.AdminAccess(aH.inviteUsers)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/invite/{token}", am.OpenAccess(aH.getInvite)).Methods(http.MethodGet) router.HandleFunc("/api/v1/invite/{token}", am.OpenAccess(aH.getInvite)).Methods(http.MethodGet)
@ -633,9 +609,8 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *middleware.AuthZ) {
router.HandleFunc("/api/v1/orgUsers/{id}", am.AdminAccess(aH.getOrgUsers)).Methods(http.MethodGet) router.HandleFunc("/api/v1/orgUsers/{id}", am.AdminAccess(aH.getOrgUsers)).Methods(http.MethodGet)
router.HandleFunc("/api/v2/orgs", am.AdminAccess(aH.getOrgs)).Methods(http.MethodGet) router.HandleFunc("/api/v2/orgs/me", am.AdminAccess(aH.Signoz.Handlers.Organization.Get)).Methods(http.MethodGet)
router.HandleFunc("/api/v2/orgs/me", am.AdminAccess(aH.getOrg)).Methods(http.MethodGet) router.HandleFunc("/api/v2/orgs/me", am.AdminAccess(aH.Signoz.Handlers.Organization.Update)).Methods(http.MethodPut)
router.HandleFunc("/api/v2/orgs/me", am.AdminAccess(aH.updateOrg)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/getResetPasswordToken/{id}", am.AdminAccess(aH.getResetPasswordToken)).Methods(http.MethodGet) router.HandleFunc("/api/v1/getResetPasswordToken/{id}", am.AdminAccess(aH.getResetPasswordToken)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/resetPassword", am.OpenAccess(aH.resetPassword)).Methods(http.MethodPost) router.HandleFunc("/api/v1/resetPassword", am.OpenAccess(aH.resetPassword)).Methods(http.MethodPost)
@ -2064,7 +2039,7 @@ func (aH *APIHandler) inviteUsers(w http.ResponseWriter, r *http.Request) {
func (aH *APIHandler) getInvite(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) getInvite(w http.ResponseWriter, r *http.Request) {
token := mux.Vars(r)["token"] token := mux.Vars(r)["token"]
resp, err := auth.GetInvite(context.Background(), token, aH.OrganizationModule) resp, err := auth.GetInvite(context.Background(), token, aH.Signoz.Modules.Organization)
if err != nil { if err != nil {
RespondError(w, &model.ApiError{Err: err, Typ: model.ErrorNotFound}, nil) RespondError(w, &model.ApiError{Err: err, Typ: model.ErrorNotFound}, nil)
return return
@ -2105,7 +2080,7 @@ func (aH *APIHandler) listPendingInvites(w http.ResponseWriter, r *http.Request)
if err != nil { if err != nil {
render.Error(w, errorsV2.Newf(errorsV2.TypeInvalidInput, errorsV2.CodeInvalidInput, "invalid org_id in the invite")) render.Error(w, errorsV2.Newf(errorsV2.TypeInvalidInput, errorsV2.CodeInvalidInput, "invalid org_id in the invite"))
} }
org, err := aH.OrganizationModule.Get(ctx, orgID) org, err := aH.Signoz.Modules.Organization.Get(ctx, orgID)
if err != nil { if err != nil {
render.Error(w, errorsV2.Newf(errorsV2.TypeInternal, errorsV2.CodeInternal, err.Error())) render.Error(w, errorsV2.Newf(errorsV2.TypeInternal, errorsV2.CodeInternal, err.Error()))
} }
@ -2132,7 +2107,7 @@ func (aH *APIHandler) registerUser(w http.ResponseWriter, r *http.Request) {
return return
} }
_, apiErr := auth.Register(context.Background(), req, aH.Signoz.Alertmanager, aH.OrganizationModule) _, apiErr := auth.Register(context.Background(), req, aH.Signoz.Alertmanager, aH.Signoz.Modules.Organization)
if apiErr != nil { if apiErr != nil {
RespondError(w, apiErr, nil) RespondError(w, apiErr, nil)
return return
@ -2391,18 +2366,6 @@ func (aH *APIHandler) editRole(w http.ResponseWriter, r *http.Request) {
aH.WriteJSON(w, r, map[string]string{"data": "user group updated successfully"}) aH.WriteJSON(w, r, map[string]string{"data": "user group updated successfully"})
} }
func (aH *APIHandler) getOrgs(w http.ResponseWriter, r *http.Request) {
aH.OrganizationAPI.GetAll(w, r)
}
func (aH *APIHandler) getOrg(w http.ResponseWriter, r *http.Request) {
aH.OrganizationAPI.Get(w, r)
}
func (aH *APIHandler) updateOrg(w http.ResponseWriter, r *http.Request) {
aH.OrganizationAPI.Update(w, r)
}
func (aH *APIHandler) getOrgUsers(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) getOrgUsers(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"] id := mux.Vars(r)["id"]
users, apiErr := dao.DB().GetUsersByOrg(context.Background(), id) users, apiErr := dao.DB().GetUsersByOrg(context.Background(), id)
@ -3437,44 +3400,6 @@ func (aH *APIHandler) getProducerConsumerEval(
aH.Respond(w, resp) aH.Respond(w, resp)
} }
// Preferences
func (aH *APIHandler) getUserPreference(
w http.ResponseWriter, r *http.Request,
) {
aH.Preference.GetUserPreference(w, r)
}
func (aH *APIHandler) updateUserPreference(
w http.ResponseWriter, r *http.Request,
) {
aH.Preference.UpdateUserPreference(w, r)
}
func (aH *APIHandler) getAllUserPreferences(
w http.ResponseWriter, r *http.Request,
) {
aH.Preference.GetAllUserPreferences(w, r)
}
func (aH *APIHandler) getOrgPreference(
w http.ResponseWriter, r *http.Request,
) {
aH.Preference.GetOrgPreference(w, r)
}
func (aH *APIHandler) updateOrgPreference(
w http.ResponseWriter, r *http.Request,
) {
aH.Preference.UpdateOrgPreference(w, r)
}
func (aH *APIHandler) getAllOrgPreferences(
w http.ResponseWriter, r *http.Request,
) {
aH.Preference.GetAllOrgPreferences(w, r)
}
// RegisterIntegrationRoutes Registers all Integrations // RegisterIntegrationRoutes Registers all Integrations
func (aH *APIHandler) RegisterIntegrationRoutes(router *mux.Router, am *middleware.AuthZ) { func (aH *APIHandler) RegisterIntegrationRoutes(router *mux.Router, am *middleware.AuthZ) {
subRouter := router.PathPrefix("/api/v1/integrations").Subrouter() subRouter := router.PathPrefix("/api/v1/integrations").Subrouter()
@ -4700,7 +4625,6 @@ func (aH *APIHandler) updateSavedView(w http.ResponseWriter, r *http.Request) {
} }
func (aH *APIHandler) deleteSavedView(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) deleteSavedView(w http.ResponseWriter, r *http.Request) {
viewID := mux.Vars(r)["viewId"] viewID := mux.Vars(r)["viewId"]
viewUUID, err := valuer.NewUUID(viewID) viewUUID, err := valuer.NewUUID(viewID)
if err != nil { if err != nil {

View File

@ -14,9 +14,6 @@ import (
"github.com/SigNoz/signoz/pkg/alertmanager" "github.com/SigNoz/signoz/pkg/alertmanager"
"github.com/SigNoz/signoz/pkg/apis/fields" "github.com/SigNoz/signoz/pkg/apis/fields"
"github.com/SigNoz/signoz/pkg/http/middleware" "github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/modules/organization/implorganization"
"github.com/SigNoz/signoz/pkg/modules/preference"
preferencecore "github.com/SigNoz/signoz/pkg/modules/preference/core"
"github.com/SigNoz/signoz/pkg/prometheus" "github.com/SigNoz/signoz/pkg/prometheus"
"github.com/SigNoz/signoz/pkg/query-service/agentConf" "github.com/SigNoz/signoz/pkg/query-service/agentConf"
"github.com/SigNoz/signoz/pkg/query-service/app/clickhouseReader" "github.com/SigNoz/signoz/pkg/query-service/app/clickhouseReader"
@ -30,7 +27,6 @@ import (
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/telemetrystore" "github.com/SigNoz/signoz/pkg/telemetrystore"
"github.com/SigNoz/signoz/pkg/types/authtypes" "github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
"github.com/SigNoz/signoz/pkg/web" "github.com/SigNoz/signoz/pkg/web"
"github.com/rs/cors" "github.com/rs/cors"
"github.com/soheilhy/cmux" "github.com/soheilhy/cmux"
@ -183,9 +179,6 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
} }
telemetry.GetInstance().SetReader(reader) telemetry.GetInstance().SetReader(reader)
preferenceAPI := preference.NewAPI(preferencecore.NewPreference(preferencecore.NewStore(serverOptions.SigNoz.SQLStore), preferencetypes.NewDefaultPreferenceMap()))
organizationAPI := implorganization.NewAPI(implorganization.NewModule(implorganization.NewStore(serverOptions.SigNoz.SQLStore)))
organizationModule := implorganization.NewModule(implorganization.NewStore(serverOptions.SigNoz.SQLStore))
apiHandler, err := NewAPIHandler(APIHandlerOpts{ apiHandler, err := NewAPIHandler(APIHandlerOpts{
Reader: reader, Reader: reader,
SkipConfig: skipConfig, SkipConfig: skipConfig,
@ -204,9 +197,6 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
AlertmanagerAPI: alertmanager.NewAPI(serverOptions.SigNoz.Alertmanager), AlertmanagerAPI: alertmanager.NewAPI(serverOptions.SigNoz.Alertmanager),
FieldsAPI: fields.NewAPI(serverOptions.SigNoz.TelemetryStore), FieldsAPI: fields.NewAPI(serverOptions.SigNoz.TelemetryStore),
Signoz: serverOptions.SigNoz, Signoz: serverOptions.SigNoz,
Preference: preferenceAPI,
OrganizationAPI: organizationAPI,
OrganizationModule: organizationModule,
}) })
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -18,6 +18,7 @@ import (
"github.com/SigNoz/signoz/pkg/query-service/featureManager" "github.com/SigNoz/signoz/pkg/query-service/featureManager"
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3" v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
"github.com/SigNoz/signoz/pkg/query-service/utils" "github.com/SigNoz/signoz/pkg/query-service/utils"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types"
mockhouse "github.com/srikanthccv/ClickHouse-go-mock" mockhouse "github.com/srikanthccv/ClickHouse-go-mock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -297,11 +298,17 @@ func NewFilterSuggestionsTestBed(t *testing.T) *FilterSuggestionsTestBed {
reader, mockClickhouse := NewMockClickhouseReader(t, testDB) reader, mockClickhouse := NewMockClickhouseReader(t, testDB)
mockClickhouse.MatchExpectationsInOrder(false) mockClickhouse.MatchExpectationsInOrder(false)
modules := signoz.NewModules(testDB)
apiHandler, err := app.NewAPIHandler(app.APIHandlerOpts{ apiHandler, err := app.NewAPIHandler(app.APIHandlerOpts{
Reader: reader, Reader: reader,
AppDao: dao.DB(), AppDao: dao.DB(),
FeatureFlags: fm, FeatureFlags: fm,
JWT: jwt, JWT: jwt,
Signoz: &signoz.SigNoz{
Modules: modules,
Handlers: signoz.NewHandlers(modules),
},
}) })
if err != nil { if err != nil {
t.Fatalf("could not create a new ApiHandler: %v", err) t.Fatalf("could not create a new ApiHandler: %v", err)

View File

@ -10,6 +10,7 @@ import (
"github.com/SigNoz/signoz/pkg/http/middleware" "github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/modules/organization/implorganization" "github.com/SigNoz/signoz/pkg/modules/organization/implorganization"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest" "github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
"github.com/SigNoz/signoz/pkg/query-service/app" "github.com/SigNoz/signoz/pkg/query-service/app"
@ -360,12 +361,19 @@ func NewCloudIntegrationsTestBed(t *testing.T, testDB sqlstore.SQLStore) *CloudI
reader, mockClickhouse := NewMockClickhouseReader(t, testDB) reader, mockClickhouse := NewMockClickhouseReader(t, testDB)
mockClickhouse.MatchExpectationsInOrder(false) mockClickhouse.MatchExpectationsInOrder(false)
modules := signoz.NewModules(testDB)
handlers := signoz.NewHandlers(modules)
apiHandler, err := app.NewAPIHandler(app.APIHandlerOpts{ apiHandler, err := app.NewAPIHandler(app.APIHandlerOpts{
Reader: reader, Reader: reader,
AppDao: dao.DB(), AppDao: dao.DB(),
CloudIntegrationsController: controller, CloudIntegrationsController: controller,
FeatureFlags: fm, FeatureFlags: fm,
JWT: jwt, JWT: jwt,
Signoz: &signoz.SigNoz{
Modules: modules,
Handlers: handlers,
},
}) })
if err != nil { if err != nil {
t.Fatalf("could not create a new ApiHandler: %v", err) t.Fatalf("could not create a new ApiHandler: %v", err)

View File

@ -19,6 +19,7 @@ import (
"github.com/SigNoz/signoz/pkg/query-service/model" "github.com/SigNoz/signoz/pkg/query-service/model"
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3" v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
"github.com/SigNoz/signoz/pkg/query-service/utils" "github.com/SigNoz/signoz/pkg/query-service/utils"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/pipelinetypes" "github.com/SigNoz/signoz/pkg/types/pipelinetypes"
@ -566,6 +567,9 @@ func NewIntegrationsTestBed(t *testing.T, testDB sqlstore.SQLStore) *Integration
t.Fatalf("could not create cloud integrations controller: %v", err) t.Fatalf("could not create cloud integrations controller: %v", err)
} }
modules := signoz.NewModules(testDB)
handlers := signoz.NewHandlers(modules)
apiHandler, err := app.NewAPIHandler(app.APIHandlerOpts{ apiHandler, err := app.NewAPIHandler(app.APIHandlerOpts{
Reader: reader, Reader: reader,
AppDao: dao.DB(), AppDao: dao.DB(),
@ -573,6 +577,10 @@ func NewIntegrationsTestBed(t *testing.T, testDB sqlstore.SQLStore) *Integration
FeatureFlags: fm, FeatureFlags: fm,
JWT: jwt, JWT: jwt,
CloudIntegrationsController: cloudIntegrationsController, CloudIntegrationsController: cloudIntegrationsController,
Signoz: &signoz.SigNoz{
Modules: modules,
Handlers: handlers,
},
}) })
if err != nil { if err != nil {
t.Fatalf("could not create a new ApiHandler: %v", err) t.Fatalf("could not create a new ApiHandler: %v", err)

20
pkg/signoz/handler.go Normal file
View File

@ -0,0 +1,20 @@
package signoz
import (
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/organization/implorganization"
"github.com/SigNoz/signoz/pkg/modules/preference"
"github.com/SigNoz/signoz/pkg/modules/preference/implpreference"
)
type Handlers struct {
Organization organization.Handler
Preference preference.Handler
}
func NewHandlers(modules Modules) Handlers {
return Handlers{
Organization: implorganization.NewHandler(modules.Organization),
Preference: implpreference.NewHandler(modules.Preference),
}
}

22
pkg/signoz/module.go Normal file
View File

@ -0,0 +1,22 @@
package signoz
import (
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/organization/implorganization"
"github.com/SigNoz/signoz/pkg/modules/preference"
"github.com/SigNoz/signoz/pkg/modules/preference/implpreference"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
)
type Modules struct {
Organization organization.Module
Preference preference.Module
}
func NewModules(sqlstore sqlstore.SQLStore) Modules {
return Modules{
Organization: implorganization.NewModule(implorganization.NewStore(sqlstore)),
Preference: implpreference.NewModule(implpreference.NewStore(sqlstore), preferencetypes.NewDefaultPreferenceMap()),
}
}

View File

@ -26,6 +26,8 @@ type SigNoz struct {
TelemetryStore telemetrystore.TelemetryStore TelemetryStore telemetrystore.TelemetryStore
Prometheus prometheus.Prometheus Prometheus prometheus.Prometheus
Alertmanager alertmanager.Alertmanager Alertmanager alertmanager.Alertmanager
Modules Modules
Handlers Handlers
} }
func New( func New(
@ -124,6 +126,7 @@ func New(
return nil, err return nil, err
} }
// Initialize alertmanager from the available alertmanager provider factories
alertmanager, err := factory.NewProviderFromNamedMap( alertmanager, err := factory.NewProviderFromNamedMap(
ctx, ctx,
providerSettings, providerSettings,
@ -135,6 +138,12 @@ func New(
return nil, err return nil, err
} }
// Initialize all modules
modules := NewModules(sqlstore)
// Initialize all handlers for the modules
handlers := NewHandlers(modules)
registry, err := factory.NewRegistry( registry, err := factory.NewRegistry(
instrumentation.Logger(), instrumentation.Logger(),
factory.NewNamedService(factory.MustNewName("instrumentation"), instrumentation), factory.NewNamedService(factory.MustNewName("instrumentation"), instrumentation),
@ -153,5 +162,7 @@ func New(
TelemetryStore: telemetrystore, TelemetryStore: telemetrystore,
Prometheus: prometheus, Prometheus: prometheus,
Alertmanager: alertmanager, Alertmanager: alertmanager,
Modules: modules,
Handlers: handlers,
}, nil }, nil
} }

View File

@ -38,14 +38,26 @@ func (migration *dropLicensesSites) Up(ctx context.Context, db *bun.DB) error {
} }
defer tx.Rollback() defer tx.Rollback()
if _, err := tx.NewDropTable().IfExists().Table("sites").Exec(ctx); err != nil { if _, err := tx.
return err NewDropTable().
} IfExists().
if _, err := tx.NewDropTable().IfExists().Table("licenses").Exec(ctx); err != nil { Table("sites").
Exec(ctx); err != nil {
return err return err
} }
_, err = migration.store.Dialect().RenameColumn(ctx, tx, "saved_views", "uuid", "id") if _, err := tx.
NewDropTable().
IfExists().
Table("licenses").
Exec(ctx); err != nil {
return err
}
_, err = migration.
store.
Dialect().
RenameColumn(ctx, tx, "saved_views", "uuid", "id")
if err != nil { if err != nil {
return err return err
} }

View File

@ -42,10 +42,7 @@ type newInvite struct {
} }
func NewUpdateInvitesFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] { func NewUpdateInvitesFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory. return factory.NewProviderFactory(factory.MustNewName("update_invites"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
NewProviderFactory(
factory.MustNewName("update_invites"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newUpdateInvites(ctx, ps, c, sqlstore) return newUpdateInvites(ctx, ps, c, sqlstore)
}) })
} }
@ -55,8 +52,7 @@ func newUpdateInvites(_ context.Context, _ factory.ProviderSettings, _ Config, s
} }
func (migration *updateInvites) Register(migrations *migrate.Migrations) error { func (migration *updateInvites) Register(migrations *migrate.Migrations) error {
if err := migrations. if err := migrations.Register(migration.Up, migration.Down); err != nil {
Register(migration.Up, migration.Down); err != nil {
return err return err
} }
@ -64,8 +60,7 @@ func (migration *updateInvites) Register(migrations *migrate.Migrations) error {
} }
func (migration *updateInvites) Up(ctx context.Context, db *bun.DB) error { func (migration *updateInvites) Up(ctx context.Context, db *bun.DB) error {
tx, err := db. tx, err := db.BeginTx(ctx, nil)
BeginTx(ctx, nil)
if err != nil { if err != nil {
return err return err
} }
@ -88,8 +83,7 @@ func (migration *updateInvites) Up(ctx context.Context, db *bun.DB) error {
} }
if err == nil && len(existingInvites) > 0 { if err == nil && len(existingInvites) > 0 {
newInvites := migration. newInvites := migration.CopyOldInvitesToNewInvites(existingInvites)
CopyOldInvitesToNewInvites(existingInvites)
_, err = tx. _, err = tx.
NewInsert(). NewInsert().
Model(&newInvites). Model(&newInvites).

View File

@ -20,9 +20,7 @@ func NewUpdatePatFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQL
} }
func newUpdatePat(_ context.Context, _ factory.ProviderSettings, _ Config, store sqlstore.SQLStore) (SQLMigration, error) { func newUpdatePat(_ context.Context, _ factory.ProviderSettings, _ Config, store sqlstore.SQLStore) (SQLMigration, error) {
return &updatePat{ return &updatePat{store: store}, nil
store: store,
}, nil
} }
func (migration *updatePat) Register(migrations *migrate.Migrations) error { func (migration *updatePat) Register(migrations *migrate.Migrations) error {
@ -34,25 +32,33 @@ func (migration *updatePat) Register(migrations *migrate.Migrations) error {
} }
func (migration *updatePat) Up(ctx context.Context, db *bun.DB) error { func (migration *updatePat) Up(ctx context.Context, db *bun.DB) error {
// begin transaction
tx, err := db.BeginTx(ctx, nil) tx, err := db.BeginTx(ctx, nil)
if err != nil { if err != nil {
return err return err
} }
defer tx.Rollback() defer tx.Rollback()
for _, column := range []string{"last_used", "expires_at"} { for _, column := range []string{"last_used", "expires_at"} {
if err := migration.store.Dialect().AddNotNullDefaultToColumn(ctx, tx, "personal_access_tokens", column, "INTEGER", "0"); err != nil { if err := migration.
store.
Dialect().
AddNotNullDefaultToColumn(ctx, tx, "personal_access_tokens", column, "INTEGER", "0"); err != nil {
return err return err
} }
} }
if err := migration.store.Dialect().AddNotNullDefaultToColumn(ctx, tx, "personal_access_tokens", "revoked", "BOOLEAN", "false"); err != nil { if err := migration.
store.
Dialect().
AddNotNullDefaultToColumn(ctx, tx, "personal_access_tokens", "revoked", "BOOLEAN", "false"); err != nil {
return err return err
} }
if err := migration.store.Dialect().AddNotNullDefaultToColumn(ctx, tx, "personal_access_tokens", "updated_by_user_id", "TEXT", "''"); err != nil { if err := migration.
store.
Dialect().
AddNotNullDefaultToColumn(ctx, tx, "personal_access_tokens", "updated_by_user_id", "TEXT", "''"); err != nil {
return err return err
} }

View File

@ -77,10 +77,7 @@ type newAlertmanagerState struct {
} }
func NewUpdateAlertmanagerFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] { func NewUpdateAlertmanagerFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory. return factory.NewProviderFactory(factory.MustNewName("update_alertmanager"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
NewProviderFactory(
factory.MustNewName("update_alertmanager"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newUpdateAlertmanager(ctx, ps, c, sqlstore) return newUpdateAlertmanager(ctx, ps, c, sqlstore)
}) })
} }
@ -90,8 +87,7 @@ func newUpdateAlertmanager(_ context.Context, _ factory.ProviderSettings, _ Conf
} }
func (migration *updateAlertmanager) Register(migrations *migrate.Migrations) error { func (migration *updateAlertmanager) Register(migrations *migrate.Migrations) error {
if err := migrations. if err := migrations.Register(migration.Up, migration.Down); err != nil {
Register(migration.Up, migration.Down); err != nil {
return err return err
} }
@ -99,8 +95,7 @@ func (migration *updateAlertmanager) Register(migrations *migrate.Migrations) er
} }
func (migration *updateAlertmanager) Up(ctx context.Context, db *bun.DB) error { func (migration *updateAlertmanager) Up(ctx context.Context, db *bun.DB) error {
tx, err := db. tx, err := db.BeginTx(ctx, nil)
BeginTx(ctx, nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -49,10 +49,7 @@ type newUserPreference struct {
} }
func NewUpdatePreferencesFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] { func NewUpdatePreferencesFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory. return factory.NewProviderFactory(factory.MustNewName("update_preferences"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
NewProviderFactory(
factory.MustNewName("update_preferences"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newUpdatePreferences(ctx, ps, c, sqlstore) return newUpdatePreferences(ctx, ps, c, sqlstore)
}) })
} }
@ -62,8 +59,7 @@ func newUpdatePreferences(_ context.Context, _ factory.ProviderSettings, _ Confi
} }
func (migration *updatePreferences) Register(migrations *migrate.Migrations) error { func (migration *updatePreferences) Register(migrations *migrate.Migrations) error {
if err := migrations. if err := migrations.Register(migration.Up, migration.Down); err != nil {
Register(migration.Up, migration.Down); err != nil {
return err return err
} }
@ -71,8 +67,7 @@ func (migration *updatePreferences) Register(migrations *migrate.Migrations) err
} }
func (migration *updatePreferences) Up(ctx context.Context, db *bun.DB) error { func (migration *updatePreferences) Up(ctx context.Context, db *bun.DB) error {
tx, err := db. tx, err := db.BeginTx(ctx, nil)
BeginTx(ctx, nil)
if err != nil { if err != nil {
return err return err
} }
@ -135,8 +130,7 @@ func (migration *updatePreferences) Up(ctx context.Context, db *bun.DB) error {
} }
if err == nil && len(existingUserPreferences) > 0 { if err == nil && len(existingUserPreferences) > 0 {
newUserPreferences := migration. newUserPreferences := migration.CopyOldUserPreferencesToNewUserPreferences(existingUserPreferences)
CopyOldUserPreferencesToNewUserPreferences(existingUserPreferences)
_, err = tx. _, err = tx.
NewInsert(). NewInsert().
Model(&newUserPreferences). Model(&newUserPreferences).

View File

@ -61,10 +61,7 @@ type newTTLStatus struct {
} }
func NewUpdateApdexTtlFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] { func NewUpdateApdexTtlFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory. return factory.NewProviderFactory(factory.MustNewName("update_apdex_ttl"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
NewProviderFactory(
factory.MustNewName("update_apdex_ttl"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newUpdateApdexTtl(ctx, ps, c, sqlstore) return newUpdateApdexTtl(ctx, ps, c, sqlstore)
}) })
} }
@ -74,8 +71,7 @@ func newUpdateApdexTtl(_ context.Context, _ factory.ProviderSettings, _ Config,
} }
func (migration *updateApdexTtl) Register(migrations *migrate.Migrations) error { func (migration *updateApdexTtl) Register(migrations *migrate.Migrations) error {
if err := migrations. if err := migrations.Register(migration.Up, migration.Down); err != nil {
Register(migration.Up, migration.Down); err != nil {
return err return err
} }
@ -83,8 +79,7 @@ func (migration *updateApdexTtl) Register(migrations *migrate.Migrations) error
} }
func (migration *updateApdexTtl) Up(ctx context.Context, db *bun.DB) error { func (migration *updateApdexTtl) Up(ctx context.Context, db *bun.DB) error {
tx, err := db. tx, err := db.BeginTx(ctx, nil)
BeginTx(ctx, nil)
if err != nil { if err != nil {
return err return err
} }
@ -161,8 +156,7 @@ func (migration *updateApdexTtl) Up(ctx context.Context, db *bun.DB) error {
} }
if err == nil { if err == nil {
newTTLStatus := migration. newTTLStatus := migration.CopyExistingTTLStatusToNewTTLStatus(existingTTLStatus, orgID)
CopyExistingTTLStatusToNewTTLStatus(existingTTLStatus, orgID)
_, err = tx. _, err = tx.
NewInsert(). NewInsert().
Model(&newTTLStatus). Model(&newTTLStatus).

View File

@ -61,10 +61,7 @@ type newPersonalAccessToken struct {
} }
func NewUpdateResetPasswordFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] { func NewUpdateResetPasswordFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory. return factory.NewProviderFactory(factory.MustNewName("update_reset_password"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
NewProviderFactory(
factory.MustNewName("update_reset_password"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newUpdateResetPassword(ctx, ps, c, sqlstore) return newUpdateResetPassword(ctx, ps, c, sqlstore)
}) })
} }
@ -74,8 +71,7 @@ func newUpdateResetPassword(_ context.Context, _ factory.ProviderSettings, _ Con
} }
func (migration *updateResetPassword) Register(migrations *migrate.Migrations) error { func (migration *updateResetPassword) Register(migrations *migrate.Migrations) error {
if err := migrations. if err := migrations.Register(migration.Up, migration.Down); err != nil {
Register(migration.Up, migration.Down); err != nil {
return err return err
} }
@ -83,8 +79,7 @@ func (migration *updateResetPassword) Register(migrations *migrate.Migrations) e
} }
func (migration *updateResetPassword) Up(ctx context.Context, db *bun.DB) error { func (migration *updateResetPassword) Up(ctx context.Context, db *bun.DB) error {
tx, err := db. tx, err := db.BeginTx(ctx, nil)
BeginTx(ctx, nil)
if err != nil { if err != nil {
return err return err
} }
@ -104,8 +99,7 @@ func (migration *updateResetPassword) Up(ctx context.Context, db *bun.DB) error
} }
if err == nil && len(existingResetPasswordRequests) > 0 { if err == nil && len(existingResetPasswordRequests) > 0 {
newResetPasswordRequests := migration. newResetPasswordRequests := migration.CopyExistingResetPasswordRequestsToNewResetPasswordRequests(existingResetPasswordRequests)
CopyExistingResetPasswordRequestsToNewResetPasswordRequests(existingResetPasswordRequests)
_, err = tx. _, err = tx.
NewInsert(). NewInsert().
Model(&newResetPasswordRequests). Model(&newResetPasswordRequests).
@ -134,8 +128,7 @@ func (migration *updateResetPassword) Up(ctx context.Context, db *bun.DB) error
} }
if err == nil && len(existingPersonalAccessTokens) > 0 { if err == nil && len(existingPersonalAccessTokens) > 0 {
newPersonalAccessTokens := migration. newPersonalAccessTokens := migration.CopyExistingPATsToNewPATs(existingPersonalAccessTokens)
CopyExistingPATsToNewPATs(existingPersonalAccessTokens)
_, err = tx.NewInsert().Model(&newPersonalAccessTokens).Exec(ctx) _, err = tx.NewInsert().Model(&newPersonalAccessTokens).Exec(ctx)
if err != nil { if err != nil {
return err return err

View File

@ -26,9 +26,7 @@ func NewUpdateIntegrationsFactory(sqlstore sqlstore.SQLStore) factory.ProviderFa
} }
func newUpdateIntegrations(_ context.Context, _ factory.ProviderSettings, _ Config, store sqlstore.SQLStore) (SQLMigration, error) { func newUpdateIntegrations(_ context.Context, _ factory.ProviderSettings, _ Config, store sqlstore.SQLStore) (SQLMigration, error) {
return &updateIntegrations{ return &updateIntegrations{store: store}, nil
store: store,
}, nil
} }
func (migration *updateIntegrations) Register(migrations *migrate.Migrations) error { func (migration *updateIntegrations) Register(migrations *migrate.Migrations) error {
@ -136,9 +134,7 @@ func (migration *updateIntegrations) Up(ctx context.Context, db *bun.DB) error {
return nil return nil
} }
// ---
// installed integrations // installed integrations
// ---
err = migration. err = migration.
store. store.
Dialect(). Dialect().
@ -171,9 +167,7 @@ func (migration *updateIntegrations) Up(ctx context.Context, db *bun.DB) error {
return err return err
} }
// ---
// cloud integrations // cloud integrations
// ---
err = migration. err = migration.
store. store.
Dialect(). Dialect().
@ -213,9 +207,7 @@ func (migration *updateIntegrations) Up(ctx context.Context, db *bun.DB) error {
return err return err
} }
// ---
// cloud integration service // cloud integration service
// ---
err = migration. err = migration.
store. store.
Dialect(). Dialect().

View File

@ -93,10 +93,7 @@ type ruleHistory struct {
} }
func NewUpdateRulesFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] { func NewUpdateRulesFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory. return factory.NewProviderFactory(factory.MustNewName("update_rules"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
NewProviderFactory(
factory.MustNewName("update_rules"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newUpdateRules(ctx, ps, c, sqlstore) return newUpdateRules(ctx, ps, c, sqlstore)
}) })
} }
@ -106,8 +103,7 @@ func newUpdateRules(_ context.Context, _ factory.ProviderSettings, _ Config, sto
} }
func (migration *updateRules) Register(migrations *migrate.Migrations) error { func (migration *updateRules) Register(migrations *migrate.Migrations) error {
if err := migrations. if err := migrations.Register(migration.Up, migration.Down); err != nil {
Register(migration.Up, migration.Down); err != nil {
return err return err
} }
@ -115,8 +111,7 @@ func (migration *updateRules) Register(migrations *migrate.Migrations) error {
} }
func (migration *updateRules) Up(ctx context.Context, db *bun.DB) error { func (migration *updateRules) Up(ctx context.Context, db *bun.DB) error {
tx, err := db. tx, err := db.BeginTx(ctx, nil)
BeginTx(ctx, nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -14,9 +14,7 @@ type updateOrganizations struct {
} }
func NewUpdateOrganizationsFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] { func NewUpdateOrganizationsFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory.NewProviderFactory( return factory.NewProviderFactory(factory.MustNewName("update_organizations"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
factory.MustNewName("update_organizations"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newUpdateOrganizations(ctx, ps, c, sqlstore) return newUpdateOrganizations(ctx, ps, c, sqlstore)
}) })
} }
@ -26,8 +24,7 @@ func newUpdateOrganizations(_ context.Context, _ factory.ProviderSettings, _ Con
} }
func (migration *updateOrganizations) Register(migrations *migrate.Migrations) error { func (migration *updateOrganizations) Register(migrations *migrate.Migrations) error {
if err := migrations. if err := migrations.Register(migration.Up, migration.Down); err != nil {
Register(migration.Up, migration.Down); err != nil {
return err return err
} }
@ -35,8 +32,7 @@ func (migration *updateOrganizations) Register(migrations *migrate.Migrations) e
} }
func (migration *updateOrganizations) Up(ctx context.Context, db *bun.DB) error { func (migration *updateOrganizations) Up(ctx context.Context, db *bun.DB) error {
tx, err := db. tx, err := db.BeginTx(ctx, nil)
BeginTx(ctx, nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -4,10 +4,11 @@ import (
"context" "context"
"database/sql" "database/sql"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3" sqlite3 "github.com/mattn/go-sqlite3"
"github.com/uptrace/bun" "github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/sqlitedialect" "github.com/uptrace/bun/dialect/sqlitedialect"
) )
@ -77,3 +78,21 @@ func (provider *provider) BunDBCtx(ctx context.Context) bun.IDB {
func (provider *provider) RunInTxCtx(ctx context.Context, opts *sql.TxOptions, cb func(ctx context.Context) error) error { func (provider *provider) RunInTxCtx(ctx context.Context, opts *sql.TxOptions, cb func(ctx context.Context) error) error {
return provider.bundb.RunInTxCtx(ctx, opts, cb) return provider.bundb.RunInTxCtx(ctx, opts, cb)
} }
func (provider *provider) WrapNotFoundErrf(err error, code errors.Code, format string, args ...any) error {
if err == sql.ErrNoRows {
return errors.Wrapf(err, errors.TypeNotFound, code, format, args...)
}
return err
}
func (provider *provider) WrapAlreadyExistsErrf(err error, code errors.Code, format string, args ...any) error {
if sqlite3Err, ok := err.(sqlite3.Error); ok {
if sqlite3Err.ExtendedCode == sqlite3.ErrConstraintUnique {
return errors.Wrapf(err, errors.TypeAlreadyExists, code, format, args...)
}
}
return err
}

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"database/sql" "database/sql"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
@ -30,6 +31,12 @@ type SQLStore interface {
// BunDBCtx returns an instance of bun.IDB for the given context. // BunDBCtx returns an instance of bun.IDB for the given context.
// If a transaction is present in the context, it will be used. Otherwise, the default will be used. // If a transaction is present in the context, it will be used. Otherwise, the default will be used.
BunDBCtx(ctx context.Context) bun.IDB BunDBCtx(ctx context.Context) bun.IDB
// WrapNotFoundErrf wraps the given error with the given message and returns it.
WrapNotFoundErrf(err error, code errors.Code, format string, args ...any) error
// WrapAlreadyExistsErrf wraps the given error with the given message and returns it.
WrapAlreadyExistsErrf(err error, code errors.Code, format string, args ...any) error
} }
type SQLStoreHook interface { type SQLStoreHook interface {

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"github.com/DATA-DOG/go-sqlmock" "github.com/DATA-DOG/go-sqlmock"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
"github.com/uptrace/bun" "github.com/uptrace/bun"
@ -74,3 +75,11 @@ func (provider *Provider) BunDBCtx(ctx context.Context) bun.IDB {
func (provider *Provider) RunInTxCtx(ctx context.Context, opts *sql.TxOptions, cb func(ctx context.Context) error) error { func (provider *Provider) RunInTxCtx(ctx context.Context, opts *sql.TxOptions, cb func(ctx context.Context) error) error {
return cb(ctx) return cb(ctx)
} }
func (provider *Provider) WrapNotFoundErrf(err error, code errors.Code, format string, args ...any) error {
return fmt.Errorf(format, args...)
}
func (provider *Provider) WrapAlreadyExistsErrf(err error, code errors.Code, format string, args ...any) error {
return fmt.Errorf(format, args...)
}

View File

@ -4,10 +4,16 @@ import (
"context" "context"
"time" "time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/valuer" "github.com/SigNoz/signoz/pkg/valuer"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
var (
ErrOrganizationAlreadyExists = errors.MustNewCode("organization_already_exists")
ErrOrganizationNotFound = errors.MustNewCode("organization_not_found")
)
type Organization struct { type Organization struct {
bun.BaseModel `bun:"table:organizations"` bun.BaseModel `bun:"table:organizations"`
TimeAuditable TimeAuditable

View File

@ -2,7 +2,6 @@ package preferencetypes
import ( import (
"context" "context"
"fmt"
"strings" "strings"
"github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/errors"
@ -133,7 +132,7 @@ func NewDefaultPreferenceMap() map[string]Preference {
} }
func (p *Preference) ErrorValueTypeMismatch() error { func (p *Preference) ErrorValueTypeMismatch() error {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("the preference value is not of expected type: %s", p.ValueType)) return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "the preference value is not of expected type: %s", p.ValueType)
} }
func (p *Preference) checkIfInAllowedValues(preferenceValue interface{}) (bool, error) { func (p *Preference) checkIfInAllowedValues(preferenceValue interface{}) (bool, error) {
@ -219,7 +218,7 @@ func (p *Preference) IsValidValue(preferenceValue interface{}) error {
} }
if !p.IsDiscreteValues { if !p.IsDiscreteValues {
if val < p.Range.Min || val > p.Range.Max { if val < p.Range.Min || val > p.Range.Max {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("the preference value is not in the range specified, min: %v , max:%v", p.Range.Min, p.Range.Max)) return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "the preference value is not in the range specified, min: %v , max: %v", p.Range.Min, p.Range.Max)
} }
} }
case PreferenceValueTypeString: case PreferenceValueTypeString:
@ -248,7 +247,7 @@ func (p *Preference) IsValidValue(preferenceValue interface{}) error {
return valueMisMatchErr return valueMisMatchErr
} }
if !isInAllowedValues { if !isInAllowedValues {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, fmt.Sprintf("the preference value is not in the list of allowedValues: %v", p.AllowedValues)) return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "the preference value is not in the list of allowedValues: %v", p.AllowedValues)
} }
} }
} }
@ -280,11 +279,11 @@ func (p *Preference) SanitizeValue(preferenceValue interface{}) interface{} {
} }
} }
type PreferenceStore interface { type Store interface {
GetOrgPreference(context.Context, string, string) (*StorableOrgPreference, error) GetOrg(context.Context, string, string) (*StorableOrgPreference, error)
GetAllOrgPreferences(context.Context, string) ([]*StorableOrgPreference, error) GetAllOrg(context.Context, string) ([]*StorableOrgPreference, error)
UpsertOrgPreference(context.Context, *StorableOrgPreference) error UpsertOrg(context.Context, *StorableOrgPreference) error
GetUserPreference(context.Context, string, string) (*StorableUserPreference, error) GetUser(context.Context, string, string) (*StorableUserPreference, error)
GetAllUserPreferences(context.Context, string) ([]*StorableUserPreference, error) GetAllUser(context.Context, string) ([]*StorableUserPreference, error)
UpsertUserPreference(context.Context, *StorableUserPreference) error UpsertUser(context.Context, *StorableUserPreference) error
} }