refactored totally, but now exits and doesn't serve for some reason
This commit is contained in:
parent
6c9b82a10c
commit
297b8f4e1a
|
@ -1,13 +1,13 @@
|
|||
//3456789112345676892123456789312345678941234567895123456789612345678971234567898
|
||||
package main
|
||||
|
||||
import "time"
|
||||
import "os"
|
||||
import "sync"
|
||||
import "time"
|
||||
|
||||
import "github.com/rs/zerolog"
|
||||
import "github.com/rs/zerolog/log"
|
||||
import "golang.org/x/crypto/ssh/terminal"
|
||||
import "github.com/sneak/merp"
|
||||
import "golang.org/x/crypto/ssh/terminal"
|
||||
|
||||
//revive:disable
|
||||
var Version string
|
||||
|
@ -21,7 +21,16 @@ var Appname string
|
|||
func main() {
|
||||
initLogging()
|
||||
identify()
|
||||
merp.ServeForever()
|
||||
var wg sync.WaitGroup
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
ms := merp.NewMerpServer()
|
||||
ms.ServeForever()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func identify() {
|
||||
|
|
|
@ -1,62 +1,48 @@
|
|||
package models
|
||||
package merp
|
||||
|
||||
import "os"
|
||||
import "time"
|
||||
import "github.com/astaxie/beego/orm"
|
||||
import "github.com/sneak/merp/models"
|
||||
import "github.com/rs/zerolog/log"
|
||||
import _ "github.com/lib/pq" //revive:disable-line
|
||||
|
||||
var ormObject orm.Ormer
|
||||
|
||||
func initialize() {
|
||||
func GetDB() orm.Ormer {
|
||||
if os.Getenv("DEBUG") != "" {
|
||||
orm.Debug = true
|
||||
}
|
||||
|
||||
connectToDb()
|
||||
syncDB()
|
||||
o := connectDB()
|
||||
syncDB(o)
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
// ConnectToDb - Initializes the ORM and Connection to the postgres DB
|
||||
func connectToDb() {
|
||||
|
||||
func connectDB() orm.Ormer {
|
||||
orm.DefaultTimeLoc = time.UTC
|
||||
|
||||
dbURL := os.Getenv("POSTGRES_DB_URL")
|
||||
|
||||
orm.RegisterDriver("postgres", orm.DRPostgres)
|
||||
orm.RegisterDataBase("default", "postgres", dbURL)
|
||||
orm.SetMaxIdleConns("default", 1)
|
||||
orm.SetMaxOpenConns("default", 5)
|
||||
|
||||
orm.RegisterModel(new(Merp))
|
||||
ormObject = orm.NewOrm()
|
||||
ormObject.Using("default")
|
||||
|
||||
orm.RegisterModel(new(models.Merp))
|
||||
o := orm.NewOrm()
|
||||
o.Using("default")
|
||||
return o
|
||||
}
|
||||
|
||||
// SyncDB() is responsible for creating the schema in the database
|
||||
func syncDB() {
|
||||
func syncDB(o orm.Ormer) {
|
||||
// Database alias.
|
||||
name := "default"
|
||||
|
||||
// Drop table and re-create.
|
||||
force := false
|
||||
|
||||
// Print log.
|
||||
verbose := true
|
||||
|
||||
// Error.
|
||||
err := orm.RunSyncdb(name, force, verbose)
|
||||
if err != nil {
|
||||
log.Fatal().Msg(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// GetOrmObject - Getter function for the ORM object with which we can query the database
|
||||
func GetOrmObject() orm.Ormer {
|
||||
if ormObject == nil {
|
||||
initialize()
|
||||
}
|
||||
return ormObject
|
||||
}
|
71
merp.go
71
merp.go
|
@ -2,7 +2,6 @@ package merp
|
|||
|
||||
import "encoding/json"
|
||||
import "net/http"
|
||||
import "regexp"
|
||||
import "time"
|
||||
|
||||
import "github.com/astaxie/beego/orm"
|
||||
|
@ -11,34 +10,21 @@ import "github.com/google/uuid"
|
|||
import "github.com/rs/zerolog/log"
|
||||
import "github.com/sneak/merp/models"
|
||||
|
||||
func thingRegex() *regexp.Regexp {
|
||||
ThingRegex, e := regexp.Compile(`^[a-zA-Z0-9\_\-]+$`)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
return ThingRegex
|
||||
}
|
||||
|
||||
func decodeJSON(in []byte) interface{} {
|
||||
func decodeJSON(in []byte) (interface{}, error) {
|
||||
var out interface{}
|
||||
err := json.Unmarshal(in, &out)
|
||||
if err != nil {
|
||||
log.Error().Msg("error decoding json")
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
return out
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func getLatestMerps() gin.HandlerFunc {
|
||||
ThingRegex := thingRegex()
|
||||
o := models.GetOrmObject()
|
||||
|
||||
h := func(c *gin.Context) {
|
||||
|
||||
func (ms *MerpServer) getLatestMerps() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
thing := c.Param("thing")
|
||||
|
||||
if thing != "" {
|
||||
if ThingRegex.MatchString(thing) == false {
|
||||
if ms.thingRegex.MatchString(thing) == false {
|
||||
c.JSON(http.StatusPreconditionFailed, gin.H{
|
||||
"this": "failed",
|
||||
"status": http.StatusPreconditionFailed,
|
||||
|
@ -50,9 +36,9 @@ func getLatestMerps() gin.HandlerFunc {
|
|||
|
||||
var qs orm.QuerySeter
|
||||
if thing == "" {
|
||||
qs = o.QueryTable("merp").OrderBy("-created").Limit(50)
|
||||
qs = ms.db.QueryTable("merp").OrderBy("-created").Limit(50)
|
||||
} else {
|
||||
qs = o.QueryTable("merp").Filter("thing", thing).OrderBy("-created").Limit(50)
|
||||
qs = ms.db.QueryTable("merp").Filter("thing", thing).OrderBy("-created").Limit(50)
|
||||
}
|
||||
|
||||
var merps []*models.Merp
|
||||
|
@ -62,8 +48,8 @@ func getLatestMerps() gin.HandlerFunc {
|
|||
for _, merp := range merps {
|
||||
outelem := make(map[string]interface{})
|
||||
outelem["thing"] = merp.Thing
|
||||
outjs := decodeJSON([]byte(merp.Content))
|
||||
if outjs == nil {
|
||||
outjs, err := decodeJSON([]byte(merp.Content))
|
||||
if err != nil {
|
||||
outelem["content"] = gin.H{}
|
||||
} else {
|
||||
outelem["content"] = outjs
|
||||
|
@ -79,40 +65,13 @@ func getLatestMerps() gin.HandlerFunc {
|
|||
"with": output,
|
||||
})
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func getLatestMerp() gin.HandlerFunc {
|
||||
ThingRegex := thingRegex()
|
||||
|
||||
h := func(c *gin.Context) {
|
||||
thing := c.Param("thing")
|
||||
if ThingRegex.MatchString(thing) == false {
|
||||
c.JSON(http.StatusPreconditionFailed, gin.H{
|
||||
"this": "failed",
|
||||
"status": http.StatusPreconditionFailed,
|
||||
"because": "invalid thing format, try [a-zA-Z0-9-_]",
|
||||
})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"this": "succeeded",
|
||||
})
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func handleNewMerp() gin.HandlerFunc {
|
||||
// server startup time
|
||||
|
||||
ThingRegex := thingRegex()
|
||||
// establish db connection *first*, before requests
|
||||
orm := models.GetOrmObject()
|
||||
|
||||
h := func(c *gin.Context) {
|
||||
func (ms *MerpServer) handleNewMerp() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// request time
|
||||
thing := c.Param("thing")
|
||||
if ThingRegex.MatchString(thing) == false {
|
||||
if ms.thingRegex.MatchString(thing) == false {
|
||||
c.JSON(http.StatusPreconditionFailed, gin.H{
|
||||
"this": "failed",
|
||||
"status": http.StatusPreconditionFailed,
|
||||
|
@ -159,7 +118,7 @@ func handleNewMerp() gin.HandlerFunc {
|
|||
UUID: u.String(),
|
||||
}
|
||||
|
||||
_, err := orm.Insert(&merp)
|
||||
_, err := ms.db.Insert(&merp)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(
|
||||
|
@ -185,6 +144,4 @@ func handleNewMerp() gin.HandlerFunc {
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
|
122
server.go
122
server.go
|
@ -1,27 +1,78 @@
|
|||
package merp
|
||||
|
||||
//3456789112345676892123456789312345678941234567895123456789612345678971234567898
|
||||
|
||||
import "encoding/json"
|
||||
import "fmt"
|
||||
import "net/http"
|
||||
import "os"
|
||||
import "regexp"
|
||||
import "strconv"
|
||||
import "time"
|
||||
|
||||
//import "github.com/rs/zerolog/log"
|
||||
import "github.com/didip/tollbooth"
|
||||
import "github.com/didip/tollbooth_gin"
|
||||
import "github.com/gin-gonic/gin"
|
||||
import "github.com/dn365/gin-zerolog"
|
||||
import "github.com/thoas/stats"
|
||||
|
||||
// ServeForever causes merp to serve http forever
|
||||
func ServeForever() {
|
||||
s := getServer()
|
||||
s.ListenAndServe()
|
||||
import "github.com/astaxie/beego/orm"
|
||||
import _ "github.com/lib/pq" //revive:disable-line
|
||||
|
||||
type MerpServer struct {
|
||||
db orm.Ormer
|
||||
debug bool
|
||||
gin *gin.Engine
|
||||
port uint
|
||||
server *http.Server
|
||||
stats *stats.Stats
|
||||
thingRegex *regexp.Regexp
|
||||
}
|
||||
|
||||
func getHealthCheckHandler() http.HandlerFunc {
|
||||
func NewMerpServer() *MerpServer {
|
||||
ms := new(MerpServer)
|
||||
ms.init()
|
||||
return ms
|
||||
}
|
||||
|
||||
func (ms *MerpServer) init() {
|
||||
|
||||
ms.thingRegex = regexp.MustCompile(`^[a-zA-Z0-9\_\-]+$`)
|
||||
|
||||
if os.Getenv("DEBUG") != "" {
|
||||
ms.debug = true
|
||||
}
|
||||
|
||||
ms.port = 8080
|
||||
var s uint64
|
||||
var err error
|
||||
if os.Getenv("PORT") != "" {
|
||||
if s, err = strconv.ParseUint(os.Getenv("PORT"), 10, 64); err == nil {
|
||||
} else {
|
||||
panic("invalid PORT in environment")
|
||||
}
|
||||
ms.port = uint(s)
|
||||
}
|
||||
ms.connectDB()
|
||||
ms.setupRoutes()
|
||||
|
||||
ms.server = &http.Server{
|
||||
Addr: fmt.Sprintf(":%s", ms.port),
|
||||
Handler: ms.gin,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *MerpServer) connectDB() {
|
||||
ms.db = GetDB()
|
||||
}
|
||||
|
||||
// ServeForever causes merp to serve http forever
|
||||
func (ms *MerpServer) ServeForever() {
|
||||
ms.server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (ms *MerpServer) HealthCheckHandler() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
result := gin.H{
|
||||
"status": "ok",
|
||||
|
@ -38,24 +89,23 @@ func getHealthCheckHandler() http.HandlerFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func getStatsHandler(middleware *stats.Stats) http.HandlerFunc {
|
||||
func (ms *MerpServer) StatsHandler() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
stats := middleware.Data()
|
||||
stats := ms.stats.Data()
|
||||
b, _ := json.Marshal(stats)
|
||||
w.Write(b)
|
||||
}
|
||||
}
|
||||
|
||||
func getRouter() *gin.Engine {
|
||||
|
||||
if os.Getenv("DEBUG") == "" {
|
||||
func (ms *MerpServer) setupRoutes() {
|
||||
if !ms.debug {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
||||
limiter := tollbooth.NewLimiter(5, nil)
|
||||
|
||||
statsMiddleware := stats.New()
|
||||
ms.stats = stats.New()
|
||||
|
||||
// empty router
|
||||
r := gin.New()
|
||||
|
@ -67,41 +117,19 @@ func getRouter() *gin.Engine {
|
|||
r.Use(ginzerolog.Logger("gin"))
|
||||
|
||||
r.Use(func(c *gin.Context) {
|
||||
beginning, recorder := statsMiddleware.Begin(c.Writer)
|
||||
beginning, recorder := ms.stats.Begin(c.Writer)
|
||||
c.Next()
|
||||
statsMiddleware.End(beginning, stats.WithRecorder(recorder))
|
||||
ms.stats.End(beginning, stats.WithRecorder(recorder))
|
||||
})
|
||||
|
||||
r.GET("/.well-known/healthcheck.json", gin.WrapF(getHealthCheckHandler()))
|
||||
r.GET("/admin/healthcheck.json", gin.WrapF(getHealthCheckHandler()))
|
||||
r.GET("/admin/stats.json", gin.WrapF(getStatsHandler(statsMiddleware)))
|
||||
r.GET("/admin/other.json", gin.WrapF(getStatsHandler(statsMiddleware)))
|
||||
r.GET("/.well-known/healthcheck.json", gin.WrapF(ms.HealthCheckHandler()))
|
||||
r.GET("/admin/healthcheck.json", gin.WrapF(ms.HealthCheckHandler()))
|
||||
r.GET("/admin/stats.json", gin.WrapF(ms.StatsHandler()))
|
||||
r.GET("/admin/other.json", gin.WrapF(ms.StatsHandler()))
|
||||
r.GET("/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), ms.handleNewMerp())
|
||||
r.GET("/get/latest/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), ms.getLatestMerps())
|
||||
r.GET("/get/latest/merps", tollbooth_gin.LimitHandler(limiter), ms.getLatestMerps())
|
||||
r.GET("/get/merps/for/:thing", tollbooth_gin.LimitHandler(limiter), ms.getLatestMerps())
|
||||
|
||||
// call it, it returns the appropriate handler function
|
||||
// so we can execute some code at startup time
|
||||
// and not just request time
|
||||
r.GET("/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), handleNewMerp())
|
||||
r.GET("/get/latest/merp/for/:thing", tollbooth_gin.LimitHandler(limiter), getLatestMerp())
|
||||
r.GET("/get/latest/merps", tollbooth_gin.LimitHandler(limiter), getLatestMerps())
|
||||
r.GET("/get/merps/for/:thing", tollbooth_gin.LimitHandler(limiter), getLatestMerps())
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func getServer() *http.Server {
|
||||
r := getRouter()
|
||||
|
||||
port := "8080"
|
||||
if os.Getenv("PORT") != "" {
|
||||
port = os.Getenv("PORT")
|
||||
}
|
||||
|
||||
s := &http.Server{
|
||||
Addr: fmt.Sprintf(":%s", port),
|
||||
Handler: r,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
return s
|
||||
ms.gin = r
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue