diff --git a/db/db_create_tables.cql b/db/db_create_tables.cql index 68c92cf3..b619b2c8 100644 --- a/db/db_create_tables.cql +++ b/db/db_create_tables.cql @@ -80,7 +80,7 @@ CREATE TABLE IF NOT EXISTS "AppSettings" (key text, column1 text, value blob, PR CREATE TABLE IF NOT EXISTS "RecookingStatus" (module text, partition_id text, state int, updated_time timestamp, primary key (module, partition_id)); -CREATE TABLE IF NOT EXISTS "PenetrationMetrics" (estb_mac text, ecm_mac text, serial_number text, partner text, model text, fw_filename text, fw_version text, fw_reported_version text, fw_additional_version_info text, fw_applied_rule text, rfc_applied_rules text, rfc_features text, rfc_ts timestamp, fw_ts timestamp, time_zone text, rfc_account_hash text, rfc_account_id text, rfc_account_mgmt text, AccountService_account_id text, rfc_partner text, AccountService_partner text, rfc_model text, rfc_fw_reported_version text, rfc_env text, rfc_application_type text, rfc_experience text, rfc_time_zone text, precook_rfc_rules text, rfc_configsethash text, precook_configsethash text, precook_rfc_features text, rfc_post_proc text, rfc_query_params text, rfc_tags text, rfc_estb_ip text, client_cert_expiry text, recovery_cert_expiry text, PRIMARY KEY (estb_mac)); +CREATE TABLE IF NOT EXISTS "PenetrationMetrics" (estb_mac text, ecm_mac text, serial_number text, partner text, model text, fw_filename text, fw_version text, fw_reported_version text, fw_additional_version_info text, fw_applied_rule text, rfc_applied_rules text, rfc_features text, rfc_ts timestamp, fw_ts timestamp, time_zone text, rfc_account_hash text, rfc_account_id text, rfc_account_mgmt text, titan_account_id text, rfc_partner text, titan_partner text, rfc_model text, rfc_fw_reported_version text, rfc_env text, rfc_application_type text, rfc_experience text, rfc_time_zone text, precook_rfc_rules text, rfc_configsethash text, precook_configsethash text, precook_rfc_features text, rfc_post_proc text, rfc_query_params text, rfc_tags text, rfc_estb_ip text, client_cert_expiry text, recovery_cert_expiry text, PRIMARY KEY (estb_mac)); CREATE TABLE IF NOT EXISTS "Tag" (key text, column1 text, value blob, PRIMARY KEY ((key), column1)); diff --git a/main.go b/main.go index 7a5f5aa6..68c17c0b 100644 --- a/main.go +++ b/main.go @@ -33,6 +33,7 @@ import ( xhttp "github.com/rdkcentral/xconfwebconfig/http" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/rdkcentral/xconfwebconfig/shared" log "github.com/sirupsen/logrus" ) @@ -108,6 +109,11 @@ func main() { // setup xconf APIs and tables dataapi.XconfSetup(server, router) + // Bootstrap static application types + if err := shared.InitializeStaticApplicationTypes(); err != nil { + log.Warnf("Failed to initialize static application types: %v", err) + } + router.HandleFunc("/debug/pprof/", pprof.Index) router.HandleFunc("/debug/pprof/profile", pprof.Profile) router.HandleFunc("/debug/pprof/symbol", pprof.Symbol) diff --git a/shared/coretypes.go b/shared/coretypes.go index 3a1fc0ba..6605e506 100644 --- a/shared/coretypes.go +++ b/shared/coretypes.go @@ -25,6 +25,7 @@ import ( "strings" "time" + "github.com/google/uuid" "github.com/rdkcentral/xconfwebconfig/common" "github.com/rdkcentral/xconfwebconfig/db" "github.com/rdkcentral/xconfwebconfig/util" @@ -65,24 +66,47 @@ func (obj *ApplicationType) Clone() (*ApplicationType, error) { return cloneObj.(*ApplicationType), nil } -func isValid(at string) bool { - if at == STB || at == XHOME || at == RDKCLOUD || at == SKY { - return true - } - return false -} - func ValidateApplicationType(applicationType string) error { if applicationType == "" { return common.NewRemoteError(http.StatusBadRequest, "ApplicationType is empty") } - - if applicationType != "" && !isValid(applicationType) { - return fmt.Errorf("ApplicationType %s is not valid", applicationType) + if !IsValidApplicationType(applicationType) { + return common.NewRemoteError(http.StatusBadRequest, fmt.Sprintf("ApplicationType '%s' is invalid or does not exist", applicationType)) } return nil } +func IsValidApplicationType(applicationType string) bool { + if util.IsBlank(applicationType) { + return false + } + allTypes, err := GetAllApplicationTypeList() + if err != nil || len(allTypes) == 0 { + log.Warn(err) + return false + } + for _, appType := range allTypes { + if strings.EqualFold(appType.Name, applicationType) { + return true + } + } + return false +} + +func GetAllApplicationTypeList() ([]*ApplicationType, error) { + result := []*ApplicationType{} + list, err := db.GetCachedSimpleDao().GetAllAsList(db.TABLE_APPLICATION_TYPES, 0) + if err != nil { + log.Warn("no application types found") + return result, err + } + for _, item := range list { + appType := item.(*ApplicationType) + result = append(result, appType) + } + return result, nil +} + const ( TABLE_LOGS_KEY2_FIELD_NAME = "column1" LAST_CONFIG_LOG_ID = "0" @@ -144,6 +168,40 @@ func NewEnvironmentInf() interface{} { return &Environment{} } +// InitializeStaticApplicationTypes creates predefined application types on first run only +func InitializeStaticApplicationTypes() error { + dao := db.GetCachedSimpleDao() + allTypes, err := dao.GetAllAsList(db.TABLE_APPLICATION_TYPES, 0) + if err == nil && len(allTypes) > 0 { + log.Info("Application types already initialized, skipping...") + return nil + } + + log.Info("Creating static application types...") + staticTypes := map[string]string{ + STB: "Set-Top Box application type", + XHOME: "Home security and automation application type", + SKY: "Sky platform application type", + } + + timestamp := time.Now().Unix() + for name, description := range staticTypes { + uid := uuid.New().String() + appType := &ApplicationType{ + ID: uid, + Name: name, + Description: description, + CreatedBy: "system", + CreatedAt: timestamp, + } + if err := dao.SetOne(db.TABLE_APPLICATION_TYPES, uid, appType); err != nil { + return fmt.Errorf("failed to create static application type '%s': %w", name, err) + } + log.Infof("Created static application type: %s ", name) + } + return nil +} + // NewEnvironment ... func NewEnvironment(id string, description string) *Environment { if id != "" { diff --git a/shared/coretypes_test.go b/shared/coretypes_test.go index 8279bca2..567186c7 100644 --- a/shared/coretypes_test.go +++ b/shared/coretypes_test.go @@ -23,46 +23,12 @@ import ( "gotest.tools/assert" ) -// Test isValid function -func TestIsValid(t *testing.T) { - // Valid application types - assert.Assert(t, isValid(STB)) - assert.Assert(t, isValid(XHOME)) - assert.Assert(t, isValid(RDKCLOUD)) - assert.Assert(t, isValid(SKY)) - - // Invalid application types - assert.Assert(t, !isValid("INVALID")) - assert.Assert(t, !isValid("")) - assert.Assert(t, !isValid("random")) - assert.Assert(t, !isValid(ALL)) -} - -// Test ValidateApplicationType -func TestValidateApplicationType_Valid(t *testing.T) { - err := ValidateApplicationType(STB) - assert.NilError(t, err) - - err = ValidateApplicationType(XHOME) - assert.NilError(t, err) - - err = ValidateApplicationType(RDKCLOUD) - assert.NilError(t, err) - - err = ValidateApplicationType(SKY) - assert.NilError(t, err) -} - -func TestValidateApplicationType_Empty(t *testing.T) { +func TestValidateApplicationType(t *testing.T) { err := ValidateApplicationType("") assert.Assert(t, err != nil) - assert.Assert(t, err.Error() == "Http400 ApplicationType is empty") -} -func TestValidateApplicationType_Invalid(t *testing.T) { - err := ValidateApplicationType("INVALID") + err = ValidateApplicationType(STB) assert.Assert(t, err != nil) - assert.Assert(t, err.Error() == "ApplicationType INVALID is not valid") } // Test Environment struct