Compare commits

...

10 Commits

Author SHA1 Message Date
Florian Herrengt 61a13c9114 structure files 2022-12-22 00:33:47 +01:00
Florian Herrengt 56b17b2b0b publish raw events 2022-12-13 01:05:22 +00:00
Florian Herrengt 1ce14e7d36 add /healthz 2022-12-09 17:07:14 +00:00
Florian Herrengt fde8e32f7a bring back url in tags 2022-12-05 21:54:45 +00:00
Florian Herrengt d90ebddc86 add file 2022-12-05 19:59:50 +00:00
Florian Herrengt 2028cc529b add context 2022-12-05 19:57:50 +00:00
Florian Herrengt 848c3749ca ssh-key 2022-12-05 19:56:10 +00:00
Florian Herrengt 7717e009f4 SSH_PRIVATE_KEY 2022-12-05 19:54:47 +00:00
Florian Herrengt 04aa01bd6c add context 2022-12-05 19:48:09 +00:00
Florian Herrengt 2c7e22aa4b checkout@v3 2022-12-05 19:46:07 +00:00
11 changed files with 134 additions and 93 deletions

View File

@ -4,17 +4,14 @@ on:
branches:
- main
jobs:
api-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
api-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: "true"
ssh-key: |
${{ secrets.SSH_PRIVATE_KEY}}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
@ -28,11 +25,13 @@ jobs:
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: |
nocodelytics/tracker-api:latest
nocodelytics/tracker-api:${{ github.sha }}
container-registry.nocodelytics.com/nocodelytics/tracker-api:latest
container-registry.nocodelytics.com/nocodelytics/tracker-api:${{ github.sha }}
# # Migrate database
# - name: migrate db

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
main
gin-bin
schemas
.env
.env
vendor

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "schemas"]
path = schemas
url = git@github.com:nocodelytics/schemas.git

58
api/handlers/events.go Normal file
View File

@ -0,0 +1,58 @@
package handlers
import (
"encoding/json"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
nocodelytics_schemas "github.com/nocodelytics/schemas"
"github.com/nocodelytics/tracker-api/internal"
"github.com/xeipuuv/gojsonschema"
)
var schema = nocodelytics_schemas.BuildEventsQueueInputSchemas()
func TrackEvent(c *gin.Context) {
nc := internal.NewNatsConnection()
id, _ := uuid.NewRandom()
ipAddress := c.ClientIP()
userAgent := c.Request.Header.Get("User-Agent")
createdAt := time.Now().Format(time.RFC3339)
data := gin.H{
"id": id,
"ip": ipAddress,
"userAgent": userAgent,
"createdAt": createdAt,
}
for k, v := range c.Request.URL.Query() {
data[k] = v[0]
}
documentLoader := gojsonschema.NewGoLoader(data)
result, err := schema.Validate(documentLoader)
if err != nil {
panic(err)
}
var errors []string
for _, val := range result.Errors() {
errors = append(errors, val.String())
}
if !result.Valid() {
c.JSON(http.StatusBadRequest, gin.H{"errors": errors})
return
}
jsonData, _ := json.Marshal(data)
nc.Publish("events", []byte(jsonData))
c.JSON(http.StatusOK, gin.H{
"ok": 1,
"id": id,
})
}

11
api/handlers/ping.go Normal file
View File

@ -0,0 +1,11 @@
package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
)
func GetPing(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}

14
api/router.go Normal file
View File

@ -0,0 +1,14 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/nocodelytics/tracker-api/api/handlers"
)
func SetupRouter() *gin.Engine {
r := gin.Default()
r.GET("/ping", handlers.GetPing)
r.GET("n.json", handlers.TrackEvent)
return r
}

3
go.mod
View File

@ -1,4 +1,4 @@
module nocodelytics/tracker-api
module github.com/nocodelytics/tracker-api
go 1.19
@ -26,6 +26,7 @@ require (
github.com/nats-io/nats-server/v2 v2.9.8 // indirect
github.com/nats-io/nkeys v0.3.0 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/nocodelytics/schemas v0.0.0-20221221224547-8be8499c3f14 // indirect
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect

4
go.sum
View File

@ -53,6 +53,10 @@ github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nocodelytics/schemas v0.0.0-20221221221107-c5236fd5bc1a h1:nlu5umvJwOXVKtbtkNjF6L0zpQphjC2a1cuvguuqkkI=
github.com/nocodelytics/schemas v0.0.0-20221221221107-c5236fd5bc1a/go.mod h1:91blRjYsb6npZ571xhf6cLUVU85OvDzLxF+zPQEhra8=
github.com/nocodelytics/schemas v0.0.0-20221221224547-8be8499c3f14 h1:SfE9BvrMZguiMchZGjQVF1xYSEoLXihk9F5R/D8zotc=
github.com/nocodelytics/schemas v0.0.0-20221221224547-8be8499c3f14/go.mod h1:91blRjYsb6npZ571xhf6cLUVU85OvDzLxF+zPQEhra8=
github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=

27
internal/nats.go Normal file
View File

@ -0,0 +1,27 @@
package internal
import (
"os"
"sync"
"github.com/nats-io/nats.go"
)
var (
err error
nc *nats.Conn
once sync.Once
)
func NewNatsConnection() *nats.Conn {
once.Do(func() {
nc, err = nats.Connect(
os.Getenv("NATS_URL"),
nats.UserInfo(os.Getenv("NATS_USER"), os.Getenv("NATS_PASSWORD")),
)
if err != nil {
panic(err)
}
})
return nc
}

88
main.go
View File

@ -2,88 +2,18 @@ package main
import (
_ "embed"
"encoding/json"
"net/http"
"os"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/nats-io/nats.go"
"github.com/xeipuuv/gojsonschema"
"github.com/nocodelytics/tracker-api/api"
"github.com/nocodelytics/tracker-api/internal"
)
//go:embed "schemas/jsonSchemas/eventsQueueInput.schema.json"
var eventsQueueInputSchema string
func setupRouter() *gin.Engine {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"ok": 1,
"name": "tracker api",
})
})
sl := gojsonschema.NewSchemaLoader()
jsonSchemaLoader := gojsonschema.NewStringLoader(eventsQueueInputSchema)
schema, err := sl.Compile(jsonSchemaLoader)
if err != nil {
panic(err)
}
nc, err := nats.Connect(os.Getenv("NATS_URL"), nats.UserInfo(os.Getenv("NATS_USER"), os.Getenv("NATS_PASSWORD")))
if err != nil {
panic(err)
}
r.GET("/n.json", func(c *gin.Context) {
id, _ := uuid.NewRandom()
ipAddress := c.ClientIP()
userAgent := c.Request.Header.Get("User-Agent")
createdAt := time.Now().Format(time.RFC3339)
data := gin.H{
"id": id,
"ip": ipAddress,
"userAgent": userAgent,
"createdAt": createdAt,
}
for k, v := range c.Request.URL.Query() {
data[k] = v[0]
}
documentLoader := gojsonschema.NewGoLoader(data)
result, err := schema.Validate(documentLoader)
if err != nil {
panic(err)
}
var errors []string
for _, val := range result.Errors() {
errors = append(errors, val.String())
}
if !result.Valid() {
c.JSON(http.StatusBadRequest, gin.H{"errors": errors})
return
}
jsonData, _ := json.Marshal(data)
nc.Publish("events", []byte(string(jsonData)))
c.JSON(http.StatusOK, gin.H{
"ok": 1,
"id": id,
})
})
return r
}
func main() {
r := setupRouter()
r.Run(":3001")
internal.NewNatsConnection()
r := api.SetupRouter()
port := os.Getenv("PORT")
if port == "" {
port = "3001"
}
r.Run(":" + port)
}

@ -1 +0,0 @@
Subproject commit f4254a9c9f471047bbb88183401e04669d61472a