diff --git a/bima.go b/bima.go index f90d1e5..51d9aee 100644 --- a/bima.go +++ b/bima.go @@ -11,7 +11,7 @@ import ( "gorm.io/gorm" ) -const VERSION_STRING = "v2.0.14" +const VERSION_STRING = "v2.1.0" type ( Module struct { diff --git a/configs/struct.go b/configs/struct.go index 9a0a2d3..f96741c 100644 --- a/configs/struct.go +++ b/configs/struct.go @@ -9,38 +9,62 @@ type ( Role int } + Service struct { + Name string + ConnonicalName string + Host string + } + + Db struct { + Host string + Port int + User string + Password string + Name string + Driver string + } + + Elasticsearch struct { + Host string + Port int + Index string + } + + MongoDb struct { + Host string + Port int + Database string + } + + Amqp struct { + Host string + Port int + User string + Password string + } + + AuthHeader struct { + Id string + Email string + Role string + MaxRole int + } + Env struct { - Debug bool - HtppPort int - RpcPort int - Version string - ApiVersion string - ServiceName string - ServiceCanonicalName string - ServiceHost string - DbHost string - DbPort int - DbUser string - DbPassword string - DbName string - DbDriver string - ElasticsearchHost string - ElasticsearchPort int - ElasticsearchIndex string - MongoDbHost string - MongoDbPort int - MongoDbName string - AmqpHost string - AmqpPort int - AmqpUser string - AmqpPassword string - HeaderUserId string - HeaderUserEmail string - HeaderUserRole string - MaximumRole int - CacheLifetime int - User *User - TemplateLocation string + Debug bool + HtppPort int + RpcPort int + Version string + ApiVersion string + Service Service + Db Db + Elasticsearch Elasticsearch + MongoDb MongoDb + Amqp Amqp + AuthHeader AuthHeader + CacheLifetime int + User *User + TemplateLocation string } Template struct { diff --git a/dics/core.go b/dics/core.go index 5344471..6fcaf12 100644 --- a/dics/core.go +++ b/dics/core.go @@ -112,44 +112,61 @@ var Container = []dingo.Def{ ) (*configs.Env, error) { env := configs.Env{} - env.ServiceName = os.Getenv("APP_NAME") - env.ServiceCanonicalName = word.Underscore(env.ServiceName) - env.ServiceHost = os.Getenv("APP_HOST") env.Version = os.Getenv("APP_VERSION") env.ApiVersion = os.Getenv("API_VERSION") env.Debug, _ = strconv.ParseBool(os.Getenv("APP_DEBUG")) env.HtppPort, _ = strconv.Atoi(os.Getenv("APP_PORT")) env.RpcPort, _ = strconv.Atoi(os.Getenv("GRPC_PORT")) - env.DbDriver = os.Getenv("DB_DRIVER") - env.DbHost = os.Getenv("DB_HOST") - env.DbPort, _ = strconv.Atoi(os.Getenv("DB_PORT")) - env.DbUser = os.Getenv("DB_USER") - env.DbPassword = os.Getenv("DB_PASSWORD") - env.DbName = os.Getenv("DB_NAME") + sName := os.Getenv("APP_NAME") + env.Service = configs.Service{ + Name: sName, + ConnonicalName: word.Underscore(sName), + Host: os.Getenv("APP_HOST"), + } - env.ElasticsearchHost = os.Getenv("ELASTICSEARCH_HOST") - env.ElasticsearchPort, _ = strconv.Atoi(os.Getenv("ELASTICSEARCH_PORT")) - env.ElasticsearchIndex = env.DbName + dbPort, _ := strconv.Atoi(os.Getenv("DB_PORT")) + env.Db = configs.Db{ + Host: os.Getenv("DB_HOST"), + Port: dbPort, + User: os.Getenv("DB_USER"), + Password: os.Getenv("DB_PASSWORD"), + Name: os.Getenv("DB_NAME"), + Driver: os.Getenv("DB_DRIVER"), + } - env.MongoDbHost = os.Getenv("MONGODB_HOST") - env.MongoDbPort, _ = strconv.Atoi(os.Getenv("MONGODB_PORT")) - env.MongoDbName = "data_logs" + esPort, _ := strconv.Atoi(os.Getenv("ELASTICSEARCH_PORT")) + env.Elasticsearch = configs.Elasticsearch{ + Host: os.Getenv("ELASTICSEARCH_HOST"), + Port: esPort, + Index: env.Db.Name, + } - env.AmqpHost = os.Getenv("AMQP_HOST") - env.AmqpPort, _ = strconv.Atoi(os.Getenv("AMQP_PORT")) - env.AmqpUser = os.Getenv("AMQP_USER") - env.AmqpPassword = os.Getenv("AMQP_PASSWORD") + mgdbPort, _ := strconv.Atoi(os.Getenv("MONGODB_PORT")) + env.MongoDb = configs.MongoDb{ + Host: os.Getenv("MONGODB_HOST"), + Port: mgdbPort, + Database: "data_logs", + } - env.HeaderUserId = os.Getenv("HEADER_USER_ID") - env.HeaderUserEmail = os.Getenv("HEADER_USER_EMAIL") - env.HeaderUserRole = os.Getenv("HEADER_USER_ROLE") - env.MaximumRole, _ = strconv.Atoi(os.Getenv("MAXIMUM_ROLE")) + amqpPort, _ := strconv.Atoi(os.Getenv("AMQP_PORT")) + env.Amqp = configs.Amqp{ + Host: os.Getenv("AMQP_HOST"), + Port: amqpPort, + User: os.Getenv("AMQP_USER"), + Password: os.Getenv("AMQP_PASSWORD"), + } - env.CacheLifetime, _ = strconv.Atoi(os.Getenv("CACHE_LIFETIME")) + maxRole, _ := strconv.Atoi(os.Getenv("AUTH_HEADER_MAX_ROLE")) + env.AuthHeader = configs.AuthHeader{ + Id: os.Getenv("AUTH_HEADER_ID"), + Email: os.Getenv("AUTH_HEADER_EMAIL"), + Role: os.Getenv("AUTH_HEADER_ROLE"), + MaxRole: maxRole, + } + env.CacheLifetime, _ = strconv.Atoi(os.Getenv("CACHE_LIFETIME")) env.User = user - env.TemplateLocation = generators.TEMPLATE_PATH return &env, nil @@ -287,27 +304,27 @@ var Container = []dingo.Def{ ) (*gorm.DB, error) { var db configs.Driver - switch env.DbDriver { + switch env.Db.Driver { case "mysql": db = mysql case "postgresql": db = postgresql default: - return nil, errors.New("Unknown Database Driver") + return nil, errors.New("Unknown database driver") } util := color.New(color.FgCyan, color.Bold) util.Printf("✓ ") - fmt.Printf("Database configured using '%s' driver...\n", env.DbDriver) + fmt.Printf("Database configured using '%s' driver...\n", env.Db.Driver) time.Sleep(100 * time.Millisecond) return db.Connect( - env.DbHost, - env.DbPort, - env.DbUser, - env.DbPassword, - env.DbName, + env.Db.Host, + env.Db.Port, + env.Db.User, + env.Db.Password, + env.Db.Name, env.Debug, ), nil }, @@ -321,7 +338,7 @@ var Container = []dingo.Def{ Name: "bima:connection:elasticsearch", Build: func(env *configs.Env) (*elastic.Client, error) { client, err := elastic.NewClient( - elastic.SetURL(fmt.Sprintf("%s:%d", env.ElasticsearchHost, env.ElasticsearchPort)), + elastic.SetURL(fmt.Sprintf("%s:%d", env.Elasticsearch.Host, env.Elasticsearch.Port)), elastic.SetSniff(false), elastic.SetHealthcheck(false), elastic.SetGzip(true), @@ -541,7 +558,7 @@ var Container = []dingo.Def{ fmt.Println("MongoDB Logger Extension configured...") time.Sleep(100 * time.Millisecond) - mongodb, err := mongodb.NewHooker(fmt.Sprintf("%s:%d", env.MongoDbHost, env.MongoDbPort), env.MongoDbName, "logs") + mongodb, err := mongodb.NewHooker(fmt.Sprintf("%s:%d", env.MongoDb.Host, env.MongoDb.Port), env.MongoDb.Database, "logs") if err != nil { return nil, err } @@ -562,7 +579,7 @@ var Container = []dingo.Def{ fmt.Println("Pub/Sub configured...") time.Sleep(100 * time.Millisecond) - return amqp.NewDurableQueueConfig(fmt.Sprintf("amqp://%s:%s@%s:%d/", env.AmqpUser, env.AmqpPassword, env.AmqpHost, env.AmqpPort)), nil + return amqp.NewDurableQueueConfig(fmt.Sprintf("amqp://%s:%s@%s:%d/", env.Amqp.User, env.Amqp.Password, env.Amqp.Host, env.Amqp.Port)), nil }, }, { diff --git a/events/dispatcher.go b/events/dispatcher.go index a52f601..aa7eb4e 100644 --- a/events/dispatcher.go +++ b/events/dispatcher.go @@ -2,6 +2,7 @@ package events import ( "errors" + "fmt" "sort" "github.com/KejawenLab/bima/v2/configs" @@ -26,13 +27,13 @@ func (d *Dispatcher) Register(listeners []configs.Listener) { } } -func (d *Dispatcher) Dispatch(name string, event interface{}) error { - if _, ok := d.Events[name]; !ok { - return errors.New("Unregistered event") +func (d *Dispatcher) Dispatch(event string, payload interface{}) error { + if _, ok := d.Events[event]; !ok { + return errors.New(fmt.Sprintf("Event '%s' not registered", event)) } - for _, listener := range d.Events[name] { - listener.Handle(event) + for _, listener := range d.Events[event] { + listener.Handle(payload) } return nil diff --git a/handlers/handler.go b/handlers/handler.go index b1145e9..5a97f14 100644 --- a/handlers/handler.go +++ b/handlers/handler.go @@ -38,7 +38,7 @@ func (h *Handler) Paginate(paginator paginations.Pagination) (paginations.Metada } var result []interface{} - adapter := adapter.NewElasticsearchAdapter(h.Context, h.Elasticsearch, fmt.Sprintf("%s_%s", h.Env.ServiceCanonicalName, paginator.Model), paginator.UseCounter, paginator.Counter, query) + adapter := adapter.NewElasticsearchAdapter(h.Context, h.Elasticsearch, fmt.Sprintf("%s_%s", h.Env.Service.ConnonicalName, paginator.Model), paginator.UseCounter, paginator.Counter, query) paginator.Paginate(adapter) paginator.Pager.Results(&result) next := paginator.Page + 1 diff --git a/handlers/logger.go b/handlers/logger.go index 6260ede..802dfe0 100644 --- a/handlers/logger.go +++ b/handlers/logger.go @@ -120,7 +120,7 @@ func (l *Logger) Panic(message string) { func (l *Logger) fields(caller string, file string, line int) logrus.Fields { return logrus.Fields{ - "ServiceName": l.Env.ServiceName, + "ServiceName": l.Env.Service.Name, "Debug": l.Env.Debug, "Caller": caller, "File": file, diff --git a/listeners/creates/elasticsearch.go b/listeners/creates/elasticsearch.go index c632e3d..9454348 100644 --- a/listeners/creates/elasticsearch.go +++ b/listeners/creates/elasticsearch.go @@ -25,7 +25,7 @@ func (c *Elasticsearch) Handle(event interface{}) { m := e.Data.(configs.Model) data, _ := json.Marshal(e.Data) - c.Elasticsearch.Index().Index(fmt.Sprintf("%s_%s", c.Env.ServiceCanonicalName, m.TableName())).BodyJson(string(data)).Do(c.Context) + c.Elasticsearch.Index().Index(fmt.Sprintf("%s_%s", c.Env.Service.ConnonicalName, m.TableName())).BodyJson(string(data)).Do(c.Context) m.SetSyncedAt(time.Now()) e.Repository.Update(m) diff --git a/listeners/deletes/elasticsearch.go b/listeners/deletes/elasticsearch.go index 4d22515..1c65f88 100644 --- a/listeners/deletes/elasticsearch.go +++ b/listeners/deletes/elasticsearch.go @@ -25,9 +25,9 @@ func (d *Elasticsearch) Handle(event interface{}) { query := elastic.NewMatchQuery("Id", e.Id) d.Logger.Info(fmt.Sprintf("Deleting data in elasticsearch with ID: %s", string(e.Id))) - result, _ := d.Elasticsearch.Search().Index(fmt.Sprintf("%s_%s", d.Env.ServiceCanonicalName, m.TableName())).Query(query).Do(d.Context) + result, _ := d.Elasticsearch.Search().Index(fmt.Sprintf("%s_%s", d.Env.Service.ConnonicalName, m.TableName())).Query(query).Do(d.Context) for _, hit := range result.Hits.Hits { - d.Elasticsearch.Delete().Index(fmt.Sprintf("%s_%s", d.Env.ServiceCanonicalName, m.TableName())).Id(hit.Id).Do(d.Context) + d.Elasticsearch.Delete().Index(fmt.Sprintf("%s_%s", d.Env.Service.ConnonicalName, m.TableName())).Id(hit.Id).Do(d.Context) } m.SetSyncedAt(time.Now()) diff --git a/listeners/updates/elasticsearch.go b/listeners/updates/elasticsearch.go index b5d608d..4423197 100644 --- a/listeners/updates/elasticsearch.go +++ b/listeners/updates/elasticsearch.go @@ -26,15 +26,15 @@ func (u *Elasticsearch) Handle(event interface{}) { query := elastic.NewMatchQuery("Id", e.Id) u.Logger.Info(fmt.Sprintf("Deleting data in elasticsearch with ID: %s", string(e.Id))) - result, _ := u.Elasticsearch.Search().Index(fmt.Sprintf("%s_%s", u.Env.ServiceCanonicalName, m.TableName())).Query(query).Do(u.Context) + result, _ := u.Elasticsearch.Search().Index(fmt.Sprintf("%s_%s", u.Env.Service.ConnonicalName, m.TableName())).Query(query).Do(u.Context) for _, hit := range result.Hits.Hits { - u.Elasticsearch.Delete().Index(fmt.Sprintf("%s_%s", u.Env.ServiceCanonicalName, m.TableName())).Id(hit.Id).Do(u.Context) + u.Elasticsearch.Delete().Index(fmt.Sprintf("%s_%s", u.Env.Service.ConnonicalName, m.TableName())).Id(hit.Id).Do(u.Context) } data, _ := json.Marshal(e.Data) u.Logger.Info(fmt.Sprintf("Sending data to elasticsearch: %s", string(data))) - u.Elasticsearch.Index().Index(fmt.Sprintf("%s_%s", u.Env.ServiceCanonicalName, m.TableName())).BodyJson(string(data)).Do(u.Context) + u.Elasticsearch.Index().Index(fmt.Sprintf("%s_%s", u.Env.Service.ConnonicalName, m.TableName())).BodyJson(string(data)).Do(u.Context) m.SetSyncedAt(time.Now()) e.Repository.Update(m) diff --git a/middlewares/auth.go b/middlewares/auth.go index 4cb357e..1d959f4 100644 --- a/middlewares/auth.go +++ b/middlewares/auth.go @@ -12,11 +12,11 @@ type Auth struct { } func (a *Auth) Attach(request *http.Request, response http.ResponseWriter) bool { - a.Env.User.Id = request.Header.Get(a.Env.HeaderUserId) - a.Env.User.Email = request.Header.Get(a.Env.HeaderUserEmail) - a.Env.User.Role, _ = strconv.Atoi(request.Header.Get(a.Env.HeaderUserRole)) + a.Env.User.Id = request.Header.Get(a.Env.AuthHeader.Id) + a.Env.User.Email = request.Header.Get(a.Env.AuthHeader.Email) + a.Env.User.Role, _ = strconv.Atoi(request.Header.Get(a.Env.AuthHeader.Role)) - if a.Env.User.Role == 0 || a.Env.User.Role > a.Env.MaximumRole { + if a.Env.User.Role == 0 || a.Env.User.Role > a.Env.AuthHeader.MaxRole { http.Error(response, "Unauthorization", http.StatusUnauthorized) return true