chore: support single queue and multiple worker (#589)
This commit is contained in:
134
router/server.go
134
router/server.go
@@ -3,14 +3,18 @@ package router
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/appleboy/gorush/config"
|
||||
"github.com/appleboy/gorush/core"
|
||||
"github.com/appleboy/gorush/gorush"
|
||||
"github.com/appleboy/gorush/logx"
|
||||
"github.com/appleboy/gorush/metric"
|
||||
"github.com/appleboy/gorush/queue"
|
||||
"github.com/appleboy/gorush/status"
|
||||
|
||||
api "github.com/appleboy/gin-status-api"
|
||||
@@ -26,14 +30,12 @@ import (
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
)
|
||||
|
||||
var isTerm bool
|
||||
var (
|
||||
isTerm bool
|
||||
doOnce sync.Once
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Support metrics
|
||||
m := metric.NewMetrics(func() int {
|
||||
return len(gorush.QueueNotification)
|
||||
})
|
||||
prometheus.MustRegister(m)
|
||||
isTerm = isatty.IsTerminal(os.Stdout.Fd())
|
||||
}
|
||||
|
||||
@@ -61,7 +63,7 @@ func versionHandler(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func pushHandler(cfg config.ConfYaml) gin.HandlerFunc {
|
||||
func pushHandler(cfg config.ConfYaml, q *queue.Queue) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var form gorush.RequestPush
|
||||
var msg string
|
||||
@@ -101,7 +103,7 @@ func pushHandler(cfg config.ConfYaml) gin.HandlerFunc {
|
||||
}
|
||||
}()
|
||||
|
||||
counts, logs := gorush.HandleNotification(ctx, form)
|
||||
counts, logs := handleNotification(ctx, cfg, form, q)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"success": "ok",
|
||||
@@ -121,21 +123,23 @@ func metricsHandler(c *gin.Context) {
|
||||
promhttp.Handler().ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
|
||||
func appStatusHandler(c *gin.Context) {
|
||||
result := status.App{}
|
||||
func appStatusHandler(q *queue.Queue) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
result := status.App{}
|
||||
|
||||
result.Version = GetVersion()
|
||||
result.QueueMax = cap(gorush.QueueNotification)
|
||||
result.QueueUsage = len(gorush.QueueNotification)
|
||||
result.TotalCount = status.StatStorage.GetTotalCount()
|
||||
result.Ios.PushSuccess = status.StatStorage.GetIosSuccess()
|
||||
result.Ios.PushError = status.StatStorage.GetIosError()
|
||||
result.Android.PushSuccess = status.StatStorage.GetAndroidSuccess()
|
||||
result.Android.PushError = status.StatStorage.GetAndroidError()
|
||||
result.Huawei.PushSuccess = status.StatStorage.GetHuaweiSuccess()
|
||||
result.Huawei.PushError = status.StatStorage.GetHuaweiError()
|
||||
result.Version = GetVersion()
|
||||
result.QueueMax = q.Capacity()
|
||||
result.QueueUsage = q.Usage()
|
||||
result.TotalCount = status.StatStorage.GetTotalCount()
|
||||
result.Ios.PushSuccess = status.StatStorage.GetIosSuccess()
|
||||
result.Ios.PushError = status.StatStorage.GetIosError()
|
||||
result.Android.PushSuccess = status.StatStorage.GetAndroidSuccess()
|
||||
result.Android.PushError = status.StatStorage.GetAndroidError()
|
||||
result.Huawei.PushSuccess = status.StatStorage.GetHuaweiSuccess()
|
||||
result.Huawei.PushError = status.StatStorage.GetHuaweiError()
|
||||
|
||||
c.JSON(http.StatusOK, result)
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
}
|
||||
|
||||
func sysStatsHandler() gin.HandlerFunc {
|
||||
@@ -153,7 +157,7 @@ func StatMiddleware() gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func autoTLSServer(cfg config.ConfYaml) *http.Server {
|
||||
func autoTLSServer(cfg config.ConfYaml, q *queue.Queue) *http.Server {
|
||||
m := autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(cfg.Core.AutoTLS.Host),
|
||||
@@ -163,11 +167,11 @@ func autoTLSServer(cfg config.ConfYaml) *http.Server {
|
||||
return &http.Server{
|
||||
Addr: ":https",
|
||||
TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
|
||||
Handler: routerEngine(cfg),
|
||||
Handler: routerEngine(cfg, q),
|
||||
}
|
||||
}
|
||||
|
||||
func routerEngine(cfg config.ConfYaml) *gin.Engine {
|
||||
func routerEngine(cfg config.ConfYaml, q *queue.Queue) *gin.Engine {
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
if cfg.Core.Mode == "debug" {
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
@@ -184,6 +188,14 @@ func routerEngine(cfg config.ConfYaml) *gin.Engine {
|
||||
)
|
||||
}
|
||||
|
||||
// Support metrics
|
||||
doOnce.Do(func() {
|
||||
m := metric.NewMetrics(func() int {
|
||||
return q.Usage()
|
||||
})
|
||||
prometheus.MustRegister(m)
|
||||
})
|
||||
|
||||
// set server mode
|
||||
gin.SetMode(cfg.Core.Mode)
|
||||
|
||||
@@ -202,10 +214,10 @@ func routerEngine(cfg config.ConfYaml) *gin.Engine {
|
||||
r.Use(StatMiddleware())
|
||||
|
||||
r.GET(cfg.API.StatGoURI, api.GinHandler)
|
||||
r.GET(cfg.API.StatAppURI, appStatusHandler)
|
||||
r.GET(cfg.API.StatAppURI, appStatusHandler(q))
|
||||
r.GET(cfg.API.ConfigURI, configHandler(cfg))
|
||||
r.GET(cfg.API.SysStatURI, sysStatsHandler())
|
||||
r.POST(cfg.API.PushURI, pushHandler(cfg))
|
||||
r.POST(cfg.API.PushURI, pushHandler(cfg, q))
|
||||
r.GET(cfg.API.MetricURI, metricsHandler)
|
||||
r.GET(cfg.API.HealthURI, heartbeatHandler)
|
||||
r.HEAD(cfg.API.HealthURI, heartbeatHandler)
|
||||
@@ -214,3 +226,73 @@ func routerEngine(cfg config.ConfYaml) *gin.Engine {
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// markFailedNotification adds failure logs for all tokens in push notification
|
||||
func markFailedNotification(cfg config.ConfYaml, notification *gorush.PushNotification, reason string) {
|
||||
logx.LogError.Error(reason)
|
||||
for _, token := range notification.Tokens {
|
||||
notification.AddLog(logx.GetLogPushEntry(&logx.InputLog{
|
||||
ID: notification.ID,
|
||||
Status: core.FailedPush,
|
||||
Token: token,
|
||||
Message: notification.Message,
|
||||
Platform: notification.Platform,
|
||||
Error: errors.New(reason),
|
||||
HideToken: cfg.Log.HideToken,
|
||||
Format: cfg.Log.Format,
|
||||
}))
|
||||
}
|
||||
notification.WaitDone()
|
||||
}
|
||||
|
||||
// HandleNotification add notification to queue list.
|
||||
func handleNotification(ctx context.Context, cfg config.ConfYaml, req gorush.RequestPush, q *queue.Queue) (int, []logx.LogPushEntry) {
|
||||
var count int
|
||||
wg := sync.WaitGroup{}
|
||||
newNotification := []*gorush.PushNotification{}
|
||||
for i := range req.Notifications {
|
||||
notification := &req.Notifications[i]
|
||||
switch notification.Platform {
|
||||
case core.PlatFormIos:
|
||||
if !cfg.Ios.Enabled {
|
||||
continue
|
||||
}
|
||||
case core.PlatFormAndroid:
|
||||
if !cfg.Android.Enabled {
|
||||
continue
|
||||
}
|
||||
case core.PlatFormHuawei:
|
||||
if !cfg.Huawei.Enabled {
|
||||
continue
|
||||
}
|
||||
}
|
||||
newNotification = append(newNotification, notification)
|
||||
}
|
||||
|
||||
log := make([]logx.LogPushEntry, 0, count)
|
||||
for _, notification := range newNotification {
|
||||
if cfg.Core.Sync {
|
||||
notification.Wg = &wg
|
||||
notification.Log = &log
|
||||
notification.AddWaitCount()
|
||||
}
|
||||
|
||||
if err := q.Enqueue(*notification); err != nil {
|
||||
markFailedNotification(cfg, notification, "max capacity reached")
|
||||
}
|
||||
|
||||
count += len(notification.Tokens)
|
||||
// Count topic message
|
||||
if notification.To != "" {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.Core.Sync {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
status.StatStorage.AddTotalCount(int64(count))
|
||||
|
||||
return count, log
|
||||
}
|
||||
|
||||
@@ -8,12 +8,13 @@ import (
|
||||
|
||||
"github.com/appleboy/gorush/config"
|
||||
"github.com/appleboy/gorush/logx"
|
||||
"github.com/appleboy/gorush/queue"
|
||||
|
||||
"github.com/apex/gateway"
|
||||
)
|
||||
|
||||
// RunHTTPServer provide run http or https protocol.
|
||||
func RunHTTPServer(ctx context.Context, cfg config.ConfYaml, s ...*http.Server) (err error) {
|
||||
func RunHTTPServer(ctx context.Context, cfg config.ConfYaml, q *queue.Queue, s ...*http.Server) (err error) {
|
||||
if !cfg.Core.Enabled {
|
||||
logx.LogAccess.Debug("httpd server is disabled.")
|
||||
return nil
|
||||
@@ -21,5 +22,5 @@ func RunHTTPServer(ctx context.Context, cfg config.ConfYaml, s ...*http.Server)
|
||||
|
||||
logx.LogAccess.Info("HTTPD server is running on " + cfg.Core.Port + " port.")
|
||||
|
||||
return gateway.ListenAndServe(cfg.Core.Address+":"+cfg.Core.Port, routerEngine(cfg))
|
||||
return gateway.ListenAndServe(cfg.Core.Address+":"+cfg.Core.Port, routerEngine(cfg, q))
|
||||
}
|
||||
|
||||
@@ -12,12 +12,13 @@ import (
|
||||
|
||||
"github.com/appleboy/gorush/config"
|
||||
"github.com/appleboy/gorush/logx"
|
||||
"github.com/appleboy/gorush/queue"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// RunHTTPServer provide run http or https protocol.
|
||||
func RunHTTPServer(ctx context.Context, cfg config.ConfYaml, s ...*http.Server) (err error) {
|
||||
func RunHTTPServer(ctx context.Context, cfg config.ConfYaml, q *queue.Queue, s ...*http.Server) (err error) {
|
||||
var server *http.Server
|
||||
|
||||
if !cfg.Core.Enabled {
|
||||
@@ -28,7 +29,7 @@ func RunHTTPServer(ctx context.Context, cfg config.ConfYaml, s ...*http.Server)
|
||||
if len(s) == 0 {
|
||||
server = &http.Server{
|
||||
Addr: cfg.Core.Address + ":" + cfg.Core.Port,
|
||||
Handler: routerEngine(cfg),
|
||||
Handler: routerEngine(cfg, q),
|
||||
}
|
||||
} else {
|
||||
server = s[0]
|
||||
@@ -36,7 +37,7 @@ func RunHTTPServer(ctx context.Context, cfg config.ConfYaml, s ...*http.Server)
|
||||
|
||||
logx.LogAccess.Info("HTTPD server is running on " + cfg.Core.Port + " port.")
|
||||
if cfg.Core.AutoTLS.Enabled {
|
||||
return startServer(ctx, autoTLSServer(cfg), cfg)
|
||||
return startServer(ctx, autoTLSServer(cfg, q), cfg)
|
||||
} else if cfg.Core.SSL {
|
||||
config := &tls.Config{
|
||||
MinVersion: tls.VersionTLS10,
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/appleboy/gorush/core"
|
||||
"github.com/appleboy/gorush/gorush"
|
||||
"github.com/appleboy/gorush/logx"
|
||||
"github.com/appleboy/gorush/queue"
|
||||
"github.com/appleboy/gorush/status"
|
||||
|
||||
"github.com/appleboy/gofight/v2"
|
||||
@@ -23,7 +24,10 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var goVersion = runtime.Version()
|
||||
var (
|
||||
goVersion = runtime.Version()
|
||||
q *queue.Queue
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := initTest()
|
||||
@@ -40,11 +44,14 @@ func TestMain(m *testing.M) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
q = queue.NewQueue(cfg)
|
||||
q.Start()
|
||||
defer q.Stop()
|
||||
m.Run()
|
||||
}
|
||||
|
||||
func initTest() config.ConfYaml {
|
||||
cfg, _ := config.LoadConf("")
|
||||
cfg, _ := config.LoadConf()
|
||||
cfg.Core.Mode = "test"
|
||||
return cfg
|
||||
}
|
||||
@@ -88,7 +95,7 @@ func TestRunNormalServer(t *testing.T) {
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
assert.NoError(t, RunHTTPServer(ctx, cfg))
|
||||
assert.NoError(t, RunHTTPServer(ctx, cfg, q))
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
@@ -112,7 +119,7 @@ func TestRunTLSServer(t *testing.T) {
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
assert.NoError(t, RunHTTPServer(ctx, cfg))
|
||||
assert.NoError(t, RunHTTPServer(ctx, cfg, q))
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
@@ -140,7 +147,7 @@ func TestRunTLSBase64Server(t *testing.T) {
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
assert.NoError(t, RunHTTPServer(ctx, cfg))
|
||||
assert.NoError(t, RunHTTPServer(ctx, cfg, q))
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
@@ -159,7 +166,7 @@ func TestRunAutoTLSServer(t *testing.T) {
|
||||
cfg.Core.AutoTLS.Enabled = true
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
assert.NoError(t, RunHTTPServer(ctx, cfg))
|
||||
assert.NoError(t, RunHTTPServer(ctx, cfg, q))
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
@@ -179,7 +186,7 @@ func TestLoadTLSCertError(t *testing.T) {
|
||||
cfg.Core.CertPath = "../config/config.yml"
|
||||
cfg.Core.KeyPath = "../config/config.yml"
|
||||
|
||||
assert.Error(t, RunHTTPServer(context.Background(), cfg))
|
||||
assert.Error(t, RunHTTPServer(context.Background(), cfg, q))
|
||||
}
|
||||
|
||||
func TestMissingTLSCertcfgg(t *testing.T) {
|
||||
@@ -192,8 +199,8 @@ func TestMissingTLSCertcfgg(t *testing.T) {
|
||||
cfg.Core.CertBase64 = ""
|
||||
cfg.Core.KeyBase64 = ""
|
||||
|
||||
err := RunHTTPServer(context.Background(), cfg)
|
||||
assert.Error(t, RunHTTPServer(context.Background(), cfg))
|
||||
err := RunHTTPServer(context.Background(), cfg, q)
|
||||
assert.Error(t, RunHTTPServer(context.Background(), cfg, q))
|
||||
assert.Equal(t, "missing https cert config", err.Error())
|
||||
}
|
||||
|
||||
@@ -206,7 +213,7 @@ func TestRootHandler(t *testing.T) {
|
||||
cfg.Log.Format = "json"
|
||||
|
||||
r.GET("/").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
data := r.Body.Bytes()
|
||||
|
||||
value, _ := jsonparser.GetString(data, "text")
|
||||
@@ -223,7 +230,7 @@ func TestAPIStatusGoHandler(t *testing.T) {
|
||||
r := gofight.New()
|
||||
|
||||
r.GET("/api/stat/go").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
data := r.Body.Bytes()
|
||||
|
||||
value, _ := jsonparser.GetString(data, "go_version")
|
||||
@@ -242,7 +249,7 @@ func TestAPIStatusAppHandler(t *testing.T) {
|
||||
SetVersion(appVersion)
|
||||
|
||||
r.GET("/api/stat/app").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
data := r.Body.Bytes()
|
||||
|
||||
value, _ := jsonparser.GetString(data, "version")
|
||||
@@ -258,7 +265,7 @@ func TestAPIConfigHandler(t *testing.T) {
|
||||
r := gofight.New()
|
||||
|
||||
r.GET("/api/config").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusCreated, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -270,7 +277,7 @@ func TestMissingNotificationsParameter(t *testing.T) {
|
||||
|
||||
// missing notifications parameter.
|
||||
r.POST("/api/push").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
assert.Equal(t, "application/json; charset=utf-8", r.HeaderMap.Get("Content-Type"))
|
||||
})
|
||||
@@ -286,7 +293,7 @@ func TestEmptyNotifications(t *testing.T) {
|
||||
SetJSON(gofight.D{
|
||||
"notifications": []gorush.PushNotification{},
|
||||
}).
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -314,8 +321,8 @@ func TestMutableContent(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}).
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
// json: cannot unmarshal number into Go struct field PushNotification.mutable_content of type bool
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
// json: cannot unmarshal number into Go struct field gorush.PushNotification.mutable_content of type bool
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -343,7 +350,7 @@ func TestOutOfRangeMaxNotifications(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}).
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -369,7 +376,7 @@ func TestSuccessPushHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}).
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -380,7 +387,7 @@ func TestSysStatsHandler(t *testing.T) {
|
||||
r := gofight.New()
|
||||
|
||||
r.GET("/sys/stats").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -391,7 +398,7 @@ func TestMetricsHandler(t *testing.T) {
|
||||
r := gofight.New()
|
||||
|
||||
r.GET("/metrics").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -402,7 +409,7 @@ func TestGETHeartbeatHandler(t *testing.T) {
|
||||
r := gofight.New()
|
||||
|
||||
r.GET("/healthz").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -413,7 +420,7 @@ func TestHEADHeartbeatHandler(t *testing.T) {
|
||||
r := gofight.New()
|
||||
|
||||
r.HEAD("/healthz").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -425,7 +432,7 @@ func TestVersionHandler(t *testing.T) {
|
||||
r := gofight.New()
|
||||
|
||||
r.GET("/version").
|
||||
Run(routerEngine(cfg), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(cfg, q), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
data := r.Body.Bytes()
|
||||
|
||||
@@ -438,8 +445,231 @@ func TestVersionHandler(t *testing.T) {
|
||||
func TestDisabledHTTPServer(t *testing.T) {
|
||||
cfg := initTest()
|
||||
cfg.Core.Enabled = false
|
||||
err := RunHTTPServer(context.Background(), cfg)
|
||||
err := RunHTTPServer(context.Background(), cfg, q)
|
||||
cfg.Core.Enabled = true
|
||||
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestSenMultipleNotifications(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cfg := initTest()
|
||||
|
||||
cfg.Ios.Enabled = true
|
||||
cfg.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||
err := gorush.InitAPNSClient(cfg)
|
||||
assert.Nil(t, err)
|
||||
|
||||
cfg.Android.Enabled = true
|
||||
cfg.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
q.Config(cfg)
|
||||
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := gorush.RequestPush{
|
||||
Notifications: []gorush.PushNotification{
|
||||
// ios
|
||||
{
|
||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
Platform: core.PlatFormIos,
|
||||
Message: "Welcome",
|
||||
},
|
||||
// android
|
||||
{
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: core.PlatFormAndroid,
|
||||
Message: "Welcome",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count, logs := handleNotification(ctx, cfg, req, q)
|
||||
assert.Equal(t, 3, count)
|
||||
assert.Equal(t, 0, len(logs))
|
||||
}
|
||||
|
||||
func TestDisabledAndroidNotifications(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cfg := initTest()
|
||||
|
||||
cfg.Ios.Enabled = true
|
||||
cfg.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||
err := gorush.InitAPNSClient(cfg)
|
||||
assert.Nil(t, err)
|
||||
|
||||
cfg.Android.Enabled = false
|
||||
cfg.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
q.Config(cfg)
|
||||
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := gorush.RequestPush{
|
||||
Notifications: []gorush.PushNotification{
|
||||
// ios
|
||||
{
|
||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
Platform: core.PlatFormIos,
|
||||
Message: "Welcome",
|
||||
},
|
||||
// android
|
||||
{
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: core.PlatFormAndroid,
|
||||
Message: "Welcome",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count, logs := handleNotification(ctx, cfg, req, q)
|
||||
assert.Equal(t, 1, count)
|
||||
assert.Equal(t, 0, len(logs))
|
||||
}
|
||||
|
||||
func TestSyncModeForNotifications(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cfg := initTest()
|
||||
|
||||
cfg.Ios.Enabled = true
|
||||
cfg.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||
err := gorush.InitAPNSClient(cfg)
|
||||
assert.Nil(t, err)
|
||||
|
||||
cfg.Android.Enabled = true
|
||||
cfg.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
// enable sync mode
|
||||
cfg.Core.Sync = true
|
||||
q.Config(cfg)
|
||||
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := gorush.RequestPush{
|
||||
Notifications: []gorush.PushNotification{
|
||||
// ios
|
||||
{
|
||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
Platform: core.PlatFormIos,
|
||||
Message: "Welcome",
|
||||
},
|
||||
// android
|
||||
{
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: core.PlatFormAndroid,
|
||||
Message: "Welcome",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count, logs := handleNotification(ctx, cfg, req, q)
|
||||
assert.Equal(t, 3, count)
|
||||
assert.Equal(t, 2, len(logs))
|
||||
}
|
||||
|
||||
func TestSyncModeForTopicNotification(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cfg := initTest()
|
||||
|
||||
cfg.Android.Enabled = true
|
||||
cfg.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
cfg.Log.HideToken = false
|
||||
|
||||
// enable sync mode
|
||||
cfg.Core.Sync = true
|
||||
q.Config(cfg)
|
||||
|
||||
req := gorush.RequestPush{
|
||||
Notifications: []gorush.PushNotification{
|
||||
// android
|
||||
{
|
||||
// error:InvalidParameters
|
||||
// Check that the provided parameters have the right name and type.
|
||||
To: "/topics/foo-bar@@@##",
|
||||
Platform: core.PlatFormAndroid,
|
||||
Message: "This is a Firebase Cloud Messaging Topic Message!",
|
||||
},
|
||||
// android
|
||||
{
|
||||
// success
|
||||
To: "/topics/foo-bar",
|
||||
Platform: core.PlatFormAndroid,
|
||||
Message: "This is a Firebase Cloud Messaging Topic Message!",
|
||||
},
|
||||
// android
|
||||
{
|
||||
// success
|
||||
Condition: "'dogs' in topics || 'cats' in topics",
|
||||
Platform: core.PlatFormAndroid,
|
||||
Message: "This is a Firebase Cloud Messaging Topic Message!",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count, logs := handleNotification(ctx, cfg, req, q)
|
||||
assert.Equal(t, 2, count)
|
||||
assert.Equal(t, 1, len(logs))
|
||||
}
|
||||
|
||||
func TestSyncModeForDeviceGroupNotification(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cfg := initTest()
|
||||
|
||||
cfg.Android.Enabled = true
|
||||
cfg.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
cfg.Log.HideToken = false
|
||||
|
||||
// enable sync mode
|
||||
cfg.Core.Sync = true
|
||||
q.Config(cfg)
|
||||
|
||||
req := gorush.RequestPush{
|
||||
Notifications: []gorush.PushNotification{
|
||||
// android
|
||||
{
|
||||
To: "aUniqueKey",
|
||||
Platform: core.PlatFormAndroid,
|
||||
Message: "This is a Firebase Cloud Messaging Device Group Message!",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count, logs := handleNotification(ctx, cfg, req, q)
|
||||
assert.Equal(t, 1, count)
|
||||
assert.Equal(t, 1, len(logs))
|
||||
}
|
||||
|
||||
func TestDisabledIosNotifications(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cfg := initTest()
|
||||
|
||||
cfg.Ios.Enabled = false
|
||||
cfg.Ios.KeyPath = "../certificate/certificate-valid.pem"
|
||||
err := gorush.InitAPNSClient(cfg)
|
||||
assert.Nil(t, err)
|
||||
|
||||
cfg.Android.Enabled = true
|
||||
cfg.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
q.Config(cfg)
|
||||
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := gorush.RequestPush{
|
||||
Notifications: []gorush.PushNotification{
|
||||
// ios
|
||||
{
|
||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
||||
Platform: core.PlatFormIos,
|
||||
Message: "Welcome",
|
||||
},
|
||||
// android
|
||||
{
|
||||
Tokens: []string{androidToken, androidToken + "_"},
|
||||
Platform: core.PlatFormAndroid,
|
||||
Message: "Welcome",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
count, logs := handleNotification(ctx, cfg, req, q)
|
||||
assert.Equal(t, 2, count)
|
||||
assert.Equal(t, 0, len(logs))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user