Files
social/core/social.go

146 lines
3.8 KiB
Go

package core
import (
"context"
"io"
"net/http"
"github.com/go-redis/redis/v8"
"repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/flagx"
"repositories.action2quare.com/ayo/gocommon/logger"
"repositories.action2quare.com/ayo/gocommon/session"
"repositories.action2quare.com/ayo/gocommon/wshandler"
)
var devflag = flagx.Bool("dev", false, "")
type SocialConfig struct {
session.SessionConfig `json:",inline"`
MaingateApiToken string `json:"maingate_api_token"`
RedisURL string `json:"social_redis_url"`
MongoURL string `json:"social_storage_url"`
}
var config SocialConfig
type Social struct {
wsh *wshandler.WebsocketHandler
mongoClient gocommon.MongoClient
redison *gocommon.RedisonHandler
httpApiBorker gocommon.HttpApiBroker
}
// New :
func New(ctx context.Context, wsh *wshandler.WebsocketHandler, inconfig *SocialConfig) (*Social, error) {
if inconfig == nil {
var loaded SocialConfig
if err := gocommon.LoadConfig(&loaded); err != nil {
return nil, err
}
inconfig = &loaded
}
config = *inconfig
opt, err := redis.ParseURL(config.RedisURL)
if err != nil {
return nil, logger.ErrorWithCallStack(err)
}
mc, err := gocommon.NewMongoClient(ctx, config.MongoURL)
if err != nil {
return nil, logger.ErrorWithCallStack(err)
}
so := &Social{
wsh: wsh,
redison: gocommon.NewRedisonHandler(ctx, redis.NewClient(opt)),
mongoClient: mc,
}
if err := so.prepare(ctx); err != nil {
logger.Println("social prepare() failed :", err)
return nil, logger.ErrorWithCallStack(err)
}
return so, nil
}
func (so *Social) Cleanup() {
so.mongoClient.Close()
}
func (so *Social) prepare(ctx context.Context) error {
redisClient, err := gocommon.NewRedisClient(config.RedisURL)
if err != nil {
return logger.ErrorWithCallStack(err)
}
so.redison = gocommon.NewRedisonHandler(redisClient.Context(), redisClient)
connections := makeConnections()
so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(connections, "social"))
so.httpApiBorker.AddHandler(gocommon.MakeHttpApiHandler(connections, "social"))
blocks, err := makeBlocklist(ctx, so, connections)
if err != nil {
return logger.ErrorWithCallStack(err)
}
so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(blocks, "social"))
so.httpApiBorker.AddHandler(gocommon.MakeHttpApiHandler(blocks, "social"))
friends, err := makeFriends(ctx, so, connections)
if err != nil {
return logger.ErrorWithCallStack(err)
}
so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(friends, "social"))
so.httpApiBorker.AddHandler(gocommon.MakeHttpApiHandler(friends, "social"))
invitation, err := makeInvitation(ctx, so, friends)
if err != nil {
return logger.ErrorWithCallStack(err)
}
so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(invitation, "social"))
so.httpApiBorker.AddHandler(gocommon.MakeHttpApiHandler(invitation, "social"))
return nil
}
func (so *Social) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux, prefix string) error {
so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(so, "social"))
pattern := gocommon.MakeHttpHandlerPattern(prefix, "api")
serveMux.HandleFunc(pattern, so.api)
return nil
}
func (so *Social) api(w http.ResponseWriter, r *http.Request) {
defer func() {
s := recover()
if s != nil {
logger.Error(s)
}
io.Copy(io.Discard, r.Body)
r.Body.Close()
}()
// 서버에서 오는 요청만 처리
apitoken := r.Header.Get("MG-X-API-TOKEN")
if apitoken != config.MaingateApiToken {
// 서버가 보내는 쿼리만 허용
logger.Println("MG-X-API-TOKEN is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
funcname := r.URL.Query().Get("call")
if len(funcname) == 0 {
logger.Println("query param 'call' is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
so.httpApiBorker.Call(funcname, w, r)
}