1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

Heartbeat Insertions.

Restructuring.
This commit is contained in:
Ferdinand Mütsch 2019-05-06 00:40:41 +02:00
parent 6e7f47dc79
commit 9df289b7ed
8 changed files with 110 additions and 22 deletions

19
main.go
View File

@ -13,12 +13,12 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/n1try/wakapi/middlewares"
"github.com/n1try/wakapi/models" "github.com/n1try/wakapi/models"
"github.com/n1try/wakapi/routes"
"github.com/n1try/wakapi/services" "github.com/n1try/wakapi/services"
) )
var HeartbeatSrvc services.HeartbeatService
func getConfig() models.Config { func getConfig() models.Config {
portPtr := flag.Int("port", 8080, "Port for the webserver to listen on") portPtr := flag.Int("port", 8080, "Port for the webserver to listen on")
flag.Parse() flag.Parse()
@ -40,8 +40,15 @@ func main() {
os.Exit(1) os.Exit(1)
} }
// Init Services // Services
HeartbeatSrvc = services.HeartbeatService{db} heartbeatSrvc := &services.HeartbeatService{db}
userSrvc := &services.UserService{db}
// Handlers
heartbeatHandler := &routes.HeartbeatHandler{HeartbeatSrvc: heartbeatSrvc}
// Middlewares
authenticate := &middlewares.AuthenticateMiddleware{UserSrvc: userSrvc}
// Setup Routing // Setup Routing
router := mux.NewRouter() router := mux.NewRouter()
@ -51,11 +58,11 @@ func main() {
// API Routes // API Routes
heartbeats := apiRouter.Path("/heartbeat").Subrouter() heartbeats := apiRouter.Path("/heartbeat").Subrouter()
heartbeats.Methods("POST").HandlerFunc(HeartbeatHandler) heartbeats.Methods("POST").HandlerFunc(heartbeatHandler.Post)
// Sub-Routes Setup // Sub-Routes Setup
router.PathPrefix("/api").Handler(negroni.Classic().With( router.PathPrefix("/api").Handler(negroni.Classic().With(
negroni.HandlerFunc(AuthenticateMiddleware), negroni.HandlerFunc(authenticate.Handle),
negroni.Wrap(apiRouter), negroni.Wrap(apiRouter),
)) ))

View File

@ -1,7 +0,0 @@
package main
import "net/http"
func AuthenticateMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
next(w, r)
}

View File

@ -0,0 +1,38 @@
package middlewares
import (
"context"
"encoding/base64"
"net/http"
"strings"
"github.com/n1try/wakapi/models"
"github.com/n1try/wakapi/services"
)
type AuthenticateMiddleware struct {
UserSrvc *services.UserService
}
func (m *AuthenticateMiddleware) Handle(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
authHeader := strings.Split(r.Header.Get("Authorization"), " ")
if len(authHeader) != 2 {
w.WriteHeader(401)
return
}
key, err := base64.StdEncoding.DecodeString(authHeader[1])
if err != nil {
w.WriteHeader(401)
return
}
user, err := m.UserSrvc.GetUserByKey(strings.TrimSpace(string(key)))
if err != nil {
w.WriteHeader(401)
return
}
ctx := context.WithValue(r.Context(), models.UserKey, &user)
next(w, r.WithContext(ctx))
}

5
models/shared.go Normal file
View File

@ -0,0 +1,5 @@
package models
const (
UserKey = "user"
)

6
models/user.go Normal file
View File

@ -0,0 +1,6 @@
package models
type User struct {
UserId string `json:"id"`
ApiKey string `json:"api_key"`
}

View File

@ -1,15 +1,21 @@
package main package routes
import ( import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"os" "os"
"github.com/n1try/wakapi/services"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/n1try/wakapi/models" "github.com/n1try/wakapi/models"
) )
func HeartbeatHandler(w http.ResponseWriter, r *http.Request) { type HeartbeatHandler struct {
HeartbeatSrvc *services.HeartbeatService
}
func (h *HeartbeatHandler) Post(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" { if r.Method != "POST" {
w.WriteHeader(415) w.WriteHeader(415)
return return
@ -23,7 +29,8 @@ func HeartbeatHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
err = HeartbeatSrvc.InsertMulti(heartbeats) user := r.Context().Value(models.UserKey).(*models.User)
err = h.HeartbeatSrvc.InsertBatch(heartbeats, user)
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(500)
os.Stderr.WriteString(err.Error()) os.Stderr.WriteString(err.Error())

View File

@ -8,25 +8,23 @@ import (
"github.com/n1try/wakapi/models" "github.com/n1try/wakapi/models"
) )
const ( const TableHeartbeat = "heartbeat"
TableName = "heartbeat"
)
type HeartbeatService struct { type HeartbeatService struct {
Db *sql.DB Db *sql.DB
} }
func (srv *HeartbeatService) InsertMulti(heartbeats []models.Heartbeat) error { func (srv *HeartbeatService) InsertBatch(heartbeats []models.Heartbeat, user *models.User) error {
qTpl := "INSERT INTO %+s (user, time, entity, type, category, is_write, project, branch, language) VALUES %+s;" qTpl := "INSERT INTO %+s (user, time, entity, type, category, is_write, project, branch, language) VALUES %+s;"
qFill := "" qFill := ""
vals := []interface{}{} vals := []interface{}{}
for _, h := range heartbeats { for _, h := range heartbeats {
qFill = "(?, ?, ?, ?, ?, ?, ?, ?, ?)," qFill = "(?, ?, ?, ?, ?, ?, ?, ?, ?),"
vals = append(vals, h.User, h.Time.String(), h.Entity, h.Type, h.Category, h.IsWrite, h.Project, h.Branch, h.Language) vals = append(vals, user.UserId, h.Time.String(), h.Entity, h.Type, h.Category, h.IsWrite, h.Project, h.Branch, h.Language)
} }
q := fmt.Sprintf(qTpl, TableName, qFill[0:len(qFill)-1]) q := fmt.Sprintf(qTpl, TableHeartbeat, qFill[0:len(qFill)-1])
stmt, _ := srv.Db.Prepare(q) stmt, _ := srv.Db.Prepare(q)
result, err := stmt.Exec(vals...) result, err := stmt.Exec(vals...)
if err != nil { if err != nil {

34
services/user.go Normal file
View File

@ -0,0 +1,34 @@
package services
import (
"database/sql"
"fmt"
"github.com/n1try/wakapi/models"
)
const TableUser = "user"
type UserService struct {
Db *sql.DB
}
func (srv *UserService) GetUserById(userId string) (models.User, error) {
q := fmt.Sprintf("SELECT user_id, api_key FROM %+s WHERE user_id = ?;", TableUser)
u := models.User{}
err := srv.Db.QueryRow(q, userId).Scan(&u.UserId, &u.ApiKey)
if err != nil {
return u, err
}
return u, nil
}
func (srv *UserService) GetUserByKey(key string) (models.User, error) {
q := fmt.Sprintf("SELECT user_id, api_key FROM %+s WHERE api_key = ?;", TableUser)
var u models.User
err := srv.Db.QueryRow(q, key).Scan(&u.UserId, &u.ApiKey)
if err != nil {
return u, err
}
return u, nil
}