Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var AfterMessageDelivery = func(m *protocol.Message) {
logger.WithField("message", m).Debug("message delivered")
}
var ( // Config is the active configuration of guble (used when starting-up the server) Config = &GubleConfig{ Log: kingpin.Flag("log", "Log level"). Default(log.ErrorLevel.String()). Envar("GUBLE_LOG"). Enum(logLevels()...), EnvName: kingpin.Flag("env", `Name of the environment on which the application is running`). Default(development). Envar("GUBLE_ENV"). Enum(environments...), HttpListen: kingpin.Flag("http", `The address to for the HTTP server to listen on (format: "[Host]:Port")`). Default(defaultHttpListen). Envar("GUBLE_HTTP_LISTEN"). String(), KVS: kingpin.Flag("kvs", "The storage backend for the key-value store to use : file | memory | postgres "). Default(defaultKVSBackend). Envar("GUBLE_KVS"). String(), MS: kingpin.Flag("ms", "The message storage backend : file | memory"). Default(defaultMSBackend). HintOptions("file", "memory"). Envar("GUBLE_MS"). String(), StoragePath: kingpin.Flag("storage-path", "The path for storing messages and key-value data if 'file' is selected"). Default(defaultStoragePath). Envar("GUBLE_STORAGE_PATH"). ExistingDir(), HealthEndpoint: kingpin.Flag("health-endpoint", `The health endpoint to be used by the HTTP server (value for disabling it: "")`). Default(defaultHealthEndpoint). Envar("GUBLE_HEALTH_ENDPOINT"). String(), MetricsEndpoint: kingpin.Flag("metrics-endpoint", `The metrics endpoint to be used by the HTTP server (value for disabling it: "")`). Default(defaultMetricsEndpoint). Envar("GUBLE_METRICS_ENDPOINT"). String(), Profile: kingpin.Flag("profile", `The profiler to be used (default: none): mem | cpu | block`). Default(""). Envar("GUBLE_PROFILE"). Enum("mem", "cpu", "block", ""), Postgres: PostgresConfig{ Host: kingpin.Flag("pg-host", "The PostgreSQL hostname"). Default("localhost"). Envar("GUBLE_PG_HOST"). String(), Port: kingpin.Flag("pg-port", "The PostgreSQL port"). Default("5432"). Envar("GUBLE_PG_PORT"). Int(), User: kingpin.Flag("pg-user", "The PostgreSQL user"). Default("guble"). Envar("GUBLE_PG_USER"). String(), Password: kingpin.Flag("pg-password", "The PostgreSQL password"). Default("guble"). Envar("GUBLE_PG_PASSWORD"). String(), DbName: kingpin.Flag("pg-dbname", "The PostgreSQL database name"). Default("guble"). Envar("GUBLE_PG_DBNAME"). String(), }, FCM: fcm.Config{ Enabled: kingpin.Flag("fcm", "Enable the Google Firebase Cloud Messaging connector"). Envar("GUBLE_FCM"). Bool(), APIKey: kingpin.Flag("fcm-api-key", "The Google API Key for Google Firebase Cloud Messaging"). Envar("GUBLE_FCM_API_KEY"). String(), Workers: kingpin.Flag("fcm-workers", "The number of workers handling traffic with Firebase Cloud Messaging (default: number of CPUs)"). Default(strconv.Itoa(runtime.NumCPU())). Envar("GUBLE_FCM_WORKERS"). Int(), Endpoint: kingpin.Flag("fcm-endpoint", "The Google Firebase Cloud Messaging endpoint"). Default(defaultFCMEndpoint). Envar("GUBLE_FCM_ENDPOINT"). String(), Prefix: kingpin.Flag("fcm-prefix", "The FCM prefix / endpoint"). Envar("GUBLE_FCM_PREFIX"). Default("/fcm/"). String(), IntervalMetrics: &defaultFCMMetrics, }, APNS: apns.Config{ Enabled: kingpin.Flag("apns", "Enable the APNS connector (by default, in Development mode)"). Envar("GUBLE_APNS"). Bool(), Production: kingpin.Flag("apns-production", "Enable the APNS connector in Production mode"). Envar("GUBLE_APNS_PRODUCTION"). Bool(), CertificateFileName: kingpin.Flag("apns-cert-file", "The APNS certificate file name"). Envar("GUBLE_APNS_CERT_FILE"). String(), CertificateBytes: kingpin.Flag("apns-cert-bytes", "The APNS certificate bytes, as a string of hex-values"). Envar("GUBLE_APNS_CERT_BYTES"). HexBytes(), CertificatePassword: kingpin.Flag("apns-cert-password", "The APNS certificate password"). Envar("GUBLE_APNS_CERT_PASSWORD"). String(), AppTopic: kingpin.Flag("apns-app-topic", "The APNS topic (as used by the mobile application)"). Envar("GUBLE_APNS_APP_TOPIC"). String(), Prefix: kingpin.Flag("apns-prefix", "The APNS prefix / endpoint"). Envar("GUBLE_APNS_PREFIX"). Default("/apns/"). String(), Workers: kingpin.Flag("apns-workers", "The number of workers handling traffic with APNS (default: number of CPUs)"). Default(strconv.Itoa(runtime.NumCPU())). Envar("GUBLE_APNS_WORKERS"). Int(), IntervalMetrics: &defaultAPNSMetrics, }, Cluster: ClusterConfig{ NodeID: kingpin.Flag("node-id", "(cluster mode) This guble node's own ID: a strictly positive integer number which must be unique in cluster"). Envar("GUBLE_NODE_ID").Uint8(), NodePort: kingpin.Flag("node-port", "(cluster mode) This guble node's own local port: a strictly positive integer number"). Default(defaultNodePort).Envar("GUBLE_NODE_PORT").Int(), Remotes: tcpAddrListParser(kingpin.Flag("remotes", `(cluster mode) The list of TCP addresses of some other guble nodes (format: "IP:port")`). Envar("GUBLE_NODE_REMOTES")), }, SMS: sms.Config{ Enabled: kingpin.Flag("sms", "Enable the SMS gateway)"). Envar("GUBLE_SMS"). Bool(), APIKey: kingpin.Flag("sms-api-key", "The Nexmo API Key for Sending sms"). Envar("GUBLE_SMS_API_KEY"). String(), APISecret: kingpin.Flag("sms-api-secret", "The Nexmo API Secret for Sending sms"). Envar("GUBLE_SMS_API_SECRET"). String(), SMSTopic: kingpin.Flag("sms-topic", "The topic for sms route"). Envar("GUBLE_SMS_TOPIC"). Default(sms.SMSDefaultTopic). String(), Workers: kingpin.Flag("sms-workers", "The number of workers handling traffic with Nexmo sms endpoint(default: number of CPUs)"). Default(strconv.Itoa(runtime.NumCPU())). Envar("GUBLE_SMS_WORKERS"). Int(), IntervalMetrics: &defaultSMSMetrics, }, } )
var CreateAccessManager = func() auth.AccessManager { return auth.NewAllowAllAccessManager(true) }
CreateAccessManager is a func which returns a auth.AccessManager implementation (currently: AllowAllAccessManager).
var CreateKVStore = func() kvstore.KVStore { switch *Config.KVS { case "memory": return kvstore.NewMemoryKVStore() case "file": db := kvstore.NewSqliteKVStore(path.Join(*Config.StoragePath, "kv-store.db"), true) if err := db.Open(); err != nil { logger.WithError(err).Panic("Could not open sqlite database connection") } return db case "postgres": db := kvstore.NewPostgresKVStore(kvstore.PostgresConfig{ ConnParams: map[string]string{ "host": *Config.Postgres.Host, "port": strconv.Itoa(*Config.Postgres.Port), "user": *Config.Postgres.User, "password": *Config.Postgres.Password, "dbname": *Config.Postgres.DbName, "sslmode": "disable", }, MaxIdleConns: 1, MaxOpenConns: runtime.GOMAXPROCS(0), }) if err := db.Open(); err != nil { logger.WithError(err).Panic("Could not open postgres database connection") } return db default: panic(fmt.Errorf("Unknown key-value backend: %q", *Config.KVS)) } }
CreateKVStore is a func which returns a kvstore.KVStore implementation (currently, based on guble configuration).
var CreateMessageStore = func() store.MessageStore { switch *Config.MS { case "none", "memory", "": return dummystore.New(kvstore.NewMemoryKVStore()) case "file": logger.WithField("storagePath", *Config.StoragePath).Info("Using FileMessageStore in directory") return filestore.New(*Config.StoragePath) default: panic(fmt.Errorf("Unknown message-store backend: %q", *Config.MS)) } }
CreateMessageStore is a func which returns a store.MessageStore implementation (currently, based on guble configuration).
var CreateModules = func(router router.Router) []interface{} { var modules []interface{} if wsHandler, err := websocket.NewWSHandler(router, "/stream/"); err != nil { logger.WithError(err).Error("Error loading WSHandler module") } else { modules = append(modules, wsHandler) } modules = append(modules, rest.NewRestMessageAPI(router, "/api/")) if *Config.FCM.Enabled { logger.Info("Firebase Cloud Messaging: enabled") if *Config.FCM.APIKey == "" { logger.Panic("The API Key has to be provided when Firebase Cloud Messaging is enabled") } Config.FCM.AfterMessageDelivery = AfterMessageDelivery *Config.FCM.IntervalMetrics = true if Config.FCM.Endpoint != nil { gcm.GcmSendEndpoint = *Config.FCM.Endpoint } sender := fcm.NewSender(*Config.FCM.APIKey) if fcmConn, err := fcm.New(router, sender, Config.FCM); err != nil { logger.WithError(err).Error("Error creating FCM connector") } else { modules = append(modules, fcmConn) } } else { logger.Info("Firebase Cloud Messaging: disabled") } if *Config.APNS.Enabled { if *Config.APNS.Production { logger.Info("APNS: enabled in production mode") } else { logger.Info("APNS: enabled in development mode") } logger.Info("APNS: enabled") if *Config.APNS.CertificateFileName == "" && Config.APNS.CertificateBytes == nil { logger.Panic("The certificate (as filename or bytes) has to be provided when APNS is enabled") } if *Config.APNS.CertificatePassword == "" { logger.Panic("A non-empty password has to be provided when APNS is enabled") } if *Config.APNS.AppTopic == "" { logger.Panic("The Mobile App Topic (usually the bundle-id) has to be provided when APNS is enabled") } apnsSender, err := apns.NewSender(Config.APNS) if err != nil { logger.Panic("APNS Sender could not be created") } *Config.APNS.IntervalMetrics = true if apnsConn, err := apns.New(router, apnsSender, Config.APNS); err != nil { logger.WithError(err).Error("Error creating APNS connector") } else { modules = append(modules, apnsConn) } } else { logger.Info("APNS: disabled") } if *Config.SMS.Enabled { logger.Info("Nexmo SMS: enabled") if *Config.SMS.APIKey == "" || *Config.SMS.APISecret == "" { logger.Panic("The API Key has to be provided when NEXMO SMS connector is enabled") } nexmoSender, err := sms.NewNexmoSender(*Config.SMS.APIKey, *Config.SMS.APISecret) if err != nil { logger.WithError(err).Error("Error creating Nexmo Sender") } smsConn, err := sms.New(router, nexmoSender, Config.SMS) if err != nil { logger.WithError(err).Error("Error creating Nexmo Sender") } else { modules = append(modules, smsConn) } } else { logger.Info("SMS: disabled") } return modules }
CreateModules is a func which returns a slice of modules which should be used by the service (currently, based on guble configuration); see package `service` for terminological details.
var ValidateStoragePath = func() error { if *Config.KVS == fileOption || *Config.MS == fileOption { testfile := path.Join(*Config.StoragePath, "write-test-file") f, err := os.Create(testfile) if err != nil { logger.WithError(err).WithField("storagePath", *Config.StoragePath).Error("Storage path not present/writeable.") return err } f.Close() os.Remove(testfile) } return nil }
ValidateStoragePath validates the guble configuration with regard to the storagePath (which can be used by MessageStore and/or KVStore implementations).
Functions ¶
func StartService ¶
StartService starts a server.Service after first creating the router (and its dependencies), the webserver.
Types ¶
type ClusterConfig ¶
ClusterConfig is used for configuring the cluster component.
type GubleConfig ¶
type GubleConfig struct { Log *string EnvName *string HttpListen *string KVS *string MS *string StoragePath *string HealthEndpoint *string MetricsEndpoint *string Profile *string Postgres PostgresConfig FCM fcm.Config APNS apns.Config SMS sms.Config Cluster ClusterConfig }
GubleConfig is used for configuring Guble server (including its modules / connectors).
Directories ¶
Path | Synopsis |
---|---|
Package metrics implements simple general counter-metrics.
|
Package metrics implements simple general counter-metrics. |
filestore
Package filestore is a filesystem-based implementation of the MessageStore interface.
|
Package filestore is a filesystem-based implementation of the MessageStore interface. |