diff --git a/cmd/maps-service/service.go b/cmd/maps-service/service.go new file mode 100644 index 0000000..33993eb --- /dev/null +++ b/cmd/maps-service/service.go @@ -0,0 +1,23 @@ +package main + +import ( + "git.itzana.me/strafesnet/maps-service/pkg/cmds" + log "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" + "os" +) + +func main() { + log.SetLevel(log.InfoLevel) + log.SetFormatter(&log.JSONFormatter{}) + log.SetReportCaller(true) + + app := cmds.NewApp() + app.Commands = []*cli.Command{ + cmds.NewServeCommand(), + } + + if err := app.Run(os.Args); err != nil { + log.WithError(err).Fatal("Failed to run app") + } +} diff --git a/diagram.md b/docs/submission-workflow.md similarity index 100% rename from diagram.md rename to docs/submission-workflow.md diff --git a/generate.go b/generate.go index 32d8034..a27289b 100644 --- a/generate.go +++ b/generate.go @@ -1,3 +1,3 @@ package main -//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target api --clean openapi.yaml +//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target pkg/api --clean openapi.yaml diff --git a/go.mod b/go.mod index fe1f103..3538101 100644 --- a/go.mod +++ b/go.mod @@ -5,17 +5,31 @@ go 1.22 toolchain go1.23.3 require ( - git.itzana.me/strafesnet/go-grpc v0.0.0-20240302215338-8ebbc7cffb0a + git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9 github.com/go-faster/errors v0.7.1 github.com/go-faster/jx v1.1.0 github.com/ogen-go/ogen v1.2.1 + github.com/sirupsen/logrus v1.9.3 + github.com/urfave/cli/v2 v2.27.5 go.opentelemetry.io/otel v1.32.0 go.opentelemetry.io/otel/metric v1.32.0 go.opentelemetry.io/otel/trace v1.32.0 - google.golang.org/grpc v1.64.0 + gorm.io/driver/postgres v1.5.10 + gorm.io/gorm v1.25.10 ) -require google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.5.5 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect + golang.org/x/crypto v0.23.0 // indirect +) require ( github.com/dlclark/regexp2 v1.11.0 // indirect @@ -36,7 +50,5 @@ require ( golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect - // google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect - google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index dd2437f..ca0a220 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,8 @@ -git.itzana.me/strafesnet/go-grpc v0.0.0-20240302215338-8ebbc7cffb0a h1:679jxkSaW3ZEj0XW6v+sr3Wr3LcmHRbbDLmo80xty5s= -git.itzana.me/strafesnet/go-grpc v0.0.0-20240302215338-8ebbc7cffb0a/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs= +git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9 h1:7lU6jyR7S7Rhh1dnUp7GyIRHUTBXZagw8F4n4hOyxLw= +git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9/go.mod h1:uyYerSieEt4v0MJCdPLppG0LtJ4Yj035vuTetWGsxjY= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= @@ -21,8 +24,22 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -38,10 +55,23 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= +github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= @@ -54,28 +84,32 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg= golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.5.10 h1:7Lggqempgy496c0WfHXsYWxk3Th+ZcW66/21QhVFdeE= +gorm.io/driver/postgres v1.5.10/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= +gorm.io/gorm v1.21.11/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= +gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= diff --git a/api/oas_cfg_gen.go b/pkg/api/oas_cfg_gen.go similarity index 100% rename from api/oas_cfg_gen.go rename to pkg/api/oas_cfg_gen.go diff --git a/api/oas_client_gen.go b/pkg/api/oas_client_gen.go similarity index 100% rename from api/oas_client_gen.go rename to pkg/api/oas_client_gen.go diff --git a/api/oas_handlers_gen.go b/pkg/api/oas_handlers_gen.go similarity index 100% rename from api/oas_handlers_gen.go rename to pkg/api/oas_handlers_gen.go diff --git a/api/oas_json_gen.go b/pkg/api/oas_json_gen.go similarity index 100% rename from api/oas_json_gen.go rename to pkg/api/oas_json_gen.go diff --git a/api/oas_labeler_gen.go b/pkg/api/oas_labeler_gen.go similarity index 100% rename from api/oas_labeler_gen.go rename to pkg/api/oas_labeler_gen.go diff --git a/api/oas_middleware_gen.go b/pkg/api/oas_middleware_gen.go similarity index 100% rename from api/oas_middleware_gen.go rename to pkg/api/oas_middleware_gen.go diff --git a/api/oas_parameters_gen.go b/pkg/api/oas_parameters_gen.go similarity index 100% rename from api/oas_parameters_gen.go rename to pkg/api/oas_parameters_gen.go diff --git a/api/oas_request_decoders_gen.go b/pkg/api/oas_request_decoders_gen.go similarity index 100% rename from api/oas_request_decoders_gen.go rename to pkg/api/oas_request_decoders_gen.go diff --git a/api/oas_request_encoders_gen.go b/pkg/api/oas_request_encoders_gen.go similarity index 100% rename from api/oas_request_encoders_gen.go rename to pkg/api/oas_request_encoders_gen.go diff --git a/api/oas_response_decoders_gen.go b/pkg/api/oas_response_decoders_gen.go similarity index 100% rename from api/oas_response_decoders_gen.go rename to pkg/api/oas_response_decoders_gen.go diff --git a/api/oas_response_encoders_gen.go b/pkg/api/oas_response_encoders_gen.go similarity index 100% rename from api/oas_response_encoders_gen.go rename to pkg/api/oas_response_encoders_gen.go diff --git a/api/oas_router_gen.go b/pkg/api/oas_router_gen.go similarity index 100% rename from api/oas_router_gen.go rename to pkg/api/oas_router_gen.go diff --git a/api/oas_schemas_gen.go b/pkg/api/oas_schemas_gen.go similarity index 100% rename from api/oas_schemas_gen.go rename to pkg/api/oas_schemas_gen.go diff --git a/api/oas_server_gen.go b/pkg/api/oas_server_gen.go similarity index 100% rename from api/oas_server_gen.go rename to pkg/api/oas_server_gen.go diff --git a/api/oas_unimplemented_gen.go b/pkg/api/oas_unimplemented_gen.go similarity index 100% rename from api/oas_unimplemented_gen.go rename to pkg/api/oas_unimplemented_gen.go diff --git a/api/oas_uri_gen.go b/pkg/api/oas_uri_gen.go similarity index 100% rename from api/oas_uri_gen.go rename to pkg/api/oas_uri_gen.go diff --git a/api/oas_validators_gen.go b/pkg/api/oas_validators_gen.go similarity index 100% rename from api/oas_validators_gen.go rename to pkg/api/oas_validators_gen.go diff --git a/pkg/cmds/root.go b/pkg/cmds/root.go index cfaa4e3..26f89eb 100644 --- a/pkg/cmds/root.go +++ b/pkg/cmds/root.go @@ -1,6 +1,7 @@ -package cmd +package cmds import ( + log "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" "os" "path/filepath" @@ -12,6 +13,16 @@ var ( &cli.BoolFlag{ Name: "debug", Usage: "Enable debug logging", + Value: false, + Action: func(ctx *cli.Context, debug bool) error { + log.Println("ran") + if debug { + log.SetLevel(log.DebugLevel) + log.SetFormatter(&log.TextFormatter{}) + log.SetReportCaller(false) + } + return nil + }, }, } ) diff --git a/pkg/cmds/serve.go b/pkg/cmds/serve.go index 23df1e3..9eeff59 100644 --- a/pkg/cmds/serve.go +++ b/pkg/cmds/serve.go @@ -1,11 +1,20 @@ -package cmd +package cmds -import "github.com/urfave/cli/v2" +import ( + "fmt" + "git.itzana.me/strafesnet/maps-service/pkg/api" + "git.itzana.me/strafesnet/maps-service/pkg/datastore/gormstore" + "git.itzana.me/strafesnet/maps-service/pkg/service" + log "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" + "net/http" +) -func NewRunCommand() *cli.Command { +func NewServeCommand() *cli.Command { return &cli.Command{ - Name: "run", - Usage: "Run maps service", + Name: "serve", + Usage: "Run maps service", + Action: serve, Flags: []cli.Flag{ &cli.StringFlag{ Name: "pg-host", @@ -37,6 +46,32 @@ func NewRunCommand() *cli.Command { EnvVars: []string{"PG_PASSWORD"}, Required: true, }, + &cli.BoolFlag{ + Name: "migrate", + Usage: "Run database migrations", + Value: true, + EnvVars: []string{"MIGRATE"}, + }, + &cli.IntFlag{ + Name: "port", + Usage: "Port to listen on", + Value: 8080, + EnvVars: []string{"PORT"}, + }, }, } } + +func serve(ctx *cli.Context) error { + db, err := gormstore.New(ctx) + if err != nil { + log.WithError(err).Fatal("failed to connect database") + } + + srv, err := api.NewServer(&service.Service{DB: db}, api.WithPathPrefix("/v2")) + if err != nil { + log.WithError(err).Fatal("failed to initialize api server") + } + + return http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port")), srv) +} diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index 1efcf91..608b56f 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -3,9 +3,7 @@ package datastore import ( "context" "errors" - "time" - - "git.itzana.me/strafesnet/maps-service/internal/model" + "git.itzana.me/strafesnet/maps-service/pkg/model" ) var ( @@ -13,82 +11,9 @@ var ( ) type Datastore interface { - Times() Times - Users() Users - Bots() Bots - Maps() Maps - Events() Events - Servers() Servers - Transactions() Transactions - Ranks() Ranks + Submissions() Submissions } -type Times interface { - Get(ctx context.Context, id int64) (model.Time, error) - Create(ctx context.Context, time model.Time) (model.Time, error) - Update(ctx context.Context, id int64, values OptionalMap) error - Delete(ctx context.Context, id int64) error - List(ctx context.Context, filters OptionalMap, blacklisted bool, page model.Page, sort uint32) (int64, []model.Time, error) - Rank(ctx context.Context, id int64) (int64, error) - DistinctStylePairs(ctx context.Context) ([]model.Time, error) -} - -type Users interface { - Get(ctx context.Context, id int64) (model.User, error) - GetList(ctx context.Context, id []int64) ([]model.User, error) - Create(ctx context.Context, user model.User) (model.User, error) - Update(ctx context.Context, id int64, values OptionalMap) error - Delete(ctx context.Context, id int64) error - List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.User, error) -} - -type Bots interface { - Get(ctx context.Context, id int64) (model.Bot, error) - GetList(ctx context.Context, id []int64) ([]model.Bot, error) - Create(ctx context.Context, bot model.Bot) (model.Bot, error) - Update(ctx context.Context, id int64, values OptionalMap) error - Delete(ctx context.Context, id int64) error - List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Bot, error) -} - -type Maps interface { - Get(ctx context.Context, id int64) (model.Map, error) - GetList(ctx context.Context, id []int64) ([]model.Map, error) - Create(ctx context.Context, time model.Map) (model.Map, error) - Update(ctx context.Context, id int64, values OptionalMap) error - Delete(ctx context.Context, id int64) error - List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Map, error) -} - -type Events interface { - Latest(ctx context.Context, date int64, page model.Page) ([]model.Event, error) - Create(ctx context.Context, event model.Event) (model.Event, error) - Clean(ctx context.Context) error -} - -type Servers interface { - Get(ctx context.Context, id string) (model.Server, error) - Create(ctx context.Context, server model.Server) (model.Server, error) - Update(ctx context.Context, id string, values OptionalMap) error - Delete(ctx context.Context, id string) error - DeleteByLastUpdated(ctx context.Context, date time.Time) error - List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Server, error) -} - -type Transactions interface { - Balance(ctx context.Context, user int64) (int64, error) - Get(ctx context.Context, id string) (model.Transaction, error) - Create(ctx context.Context, transaction model.Transaction) (model.Transaction, error) - Update(ctx context.Context, id string, values OptionalMap) error - Delete(ctx context.Context, id string) error - List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Transaction, error) -} - -type Ranks interface { - Delete(ctx context.Context, id int64) error - Get(ctx context.Context, user int64, style, game, mode int32, state []int32) (model.Rank, error) - List(ctx context.Context, style, game, mode int32, sort int64, state []int32, page model.Page) ([]model.Rank, error) - UpdateRankCalc(ctx context.Context) error - UpdateAll(ctx context.Context, style, game, mode int32) error - UpdateUsers(ctx context.Context, style, game, mode int32, users []int) error +type Submissions interface { + Get(ctx context.Context, id int64) (model.Submission, error) } diff --git a/pkg/datastore/gormstore/db.go b/pkg/datastore/gormstore/db.go index bb9f364..cce6fe4 100644 --- a/pkg/datastore/gormstore/db.go +++ b/pkg/datastore/gormstore/db.go @@ -2,47 +2,39 @@ package gormstore import ( "fmt" - "os" - "time" - - "git.itzana.me/strafesnet/maps-service/internal/datastore" - "git.itzana.me/strafesnet/maps-service/internal/model" + "git.itzana.me/strafesnet/maps-service/pkg/datastore" + "git.itzana.me/strafesnet/maps-service/pkg/model" "git.itzana.me/strafesnet/utils/logger" - "github.com/eko/gocache/lib/v4/cache" - gocache_store "github.com/eko/gocache/store/go_cache/v4" - gocache "github.com/patrickmn/go-cache" log "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" "gorm.io/driver/postgres" "gorm.io/gorm" ) -func New(migrate bool) (datastore.Datastore, error) { - db, err := gorm.Open(postgres.Open(fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s", os.Getenv("PG_HOST"), os.Getenv("PG_USER"), os.Getenv("PG_PASS"), os.Getenv("PG_DB"), os.Getenv("PG_PORT"))), &gorm.Config{ - Logger: logger.New()}) +func New(ctx *cli.Context) (datastore.Datastore, error) { + db, err := gorm.Open( + postgres.Open( + fmt.Sprintf( + "host=%s user=%s password=%s dbname=%s port=%s", + ctx.String("pg-host"), + ctx.String("pg-user"), + ctx.String("pg-password"), + ctx.String("pg-db"), + ctx.Int("pg-port")), + ), &gorm.Config{ + Logger: logger.New(), + }) if err != nil { - log.WithFields(log.Fields{ - "PG_USER": os.Getenv("PG_USER"), - "PG_HOST": os.Getenv("PG_HOST"), - "PG_PORT": os.Getenv("PG_PORT"), - "PG_DB": os.Getenv("PG_DB"), - "error": err, - }).Errorln("failed to connect to database") + log.WithError(err).Errorln("failed to connect to database") return nil, err } - sqlDB, err := db.DB() - if err != nil { - return nil, err - } - sqlDB.SetMaxIdleConns(10) - sqlDB.SetMaxOpenConns(25) - - if migrate { - if err := db.AutoMigrate(&model.Time{}, &model.User{}, &model.Bot{}, &model.Map{}, &model.Event{}, &model.Server{}, &model.Transaction{}, &model.Rank{}, &model.RankCalc{}); err != nil { - log.WithField("error", err).Errorln("database migration failed") + if ctx.Bool("pg-migrate") { + if err := db.AutoMigrate(&model.Submission{}); err != nil { + log.WithError(err).Errorln("database migration failed") return nil, err } } - return &Gormstore{db, cache.New[[]byte](gocache_store.NewGoCache(gocache.New(5*time.Minute, 10*time.Minute)))}, nil + return &Gormstore{db}, nil } diff --git a/pkg/datastore/gormstore/gormstore.go b/pkg/datastore/gormstore/gormstore.go index fe6ab97..3edc246 100644 --- a/pkg/datastore/gormstore/gormstore.go +++ b/pkg/datastore/gormstore/gormstore.go @@ -1,44 +1,14 @@ package gormstore import ( - "git.itzana.me/strafesnet/maps-service/internal/datastore" - "github.com/eko/gocache/lib/v4/cache" + "git.itzana.me/strafesnet/maps-service/pkg/datastore" "gorm.io/gorm" ) type Gormstore struct { - db *gorm.DB - cache *cache.Cache[[]byte] + db *gorm.DB } -func (g Gormstore) Times() datastore.Times { - return &Times{db: g.db} -} - -func (g Gormstore) Users() datastore.Users { - return &Users{db: g.db} -} - -func (g Gormstore) Bots() datastore.Bots { - return &Bots{db: g.db} -} - -func (g Gormstore) Maps() datastore.Maps { - return &Maps{db: g.db} -} - -func (g Gormstore) Events() datastore.Events { - return &Events{db: g.db} -} - -func (g Gormstore) Servers() datastore.Servers { - return &Servers{db: g.db} -} - -func (g Gormstore) Transactions() datastore.Transactions { - return &Transactions{db: g.db} -} - -func (g Gormstore) Ranks() datastore.Ranks { - return &Ranks{db: g.db, cache: g.cache} +func (g Gormstore) Submissions() datastore.Submissions { + return &Submissions{db: g.db} } diff --git a/pkg/datastore/gormstore/submissions.go b/pkg/datastore/gormstore/submissions.go index 51fa25d..c7c1d5d 100644 --- a/pkg/datastore/gormstore/submissions.go +++ b/pkg/datastore/gormstore/submissions.go @@ -2,71 +2,22 @@ package gormstore import ( "context" - "git.itzana.me/strafesnet/maps-service/internal/datastore" - "git.itzana.me/strafesnet/maps-service/internal/model" + "errors" + "git.itzana.me/strafesnet/maps-service/pkg/datastore" + "git.itzana.me/strafesnet/maps-service/pkg/model" "gorm.io/gorm" ) -type Maps struct { +type Submissions struct { db *gorm.DB } -func (m Maps) Get(ctx context.Context, id int64) (model.Map, error) { - var smap model.Map - if err := m.db.WithContext(ctx).First(&smap, id).Error; err != nil { - if err == gorm.ErrRecordNotFound { - return smap, datastore.ErrNotExist +func (env *Submissions) Get(ctx context.Context, id int64) (model.Submission, error) { + var submission model.Submission + if err := env.db.First(&submission, id).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return submission, datastore.ErrNotExist } - return smap, err } - - return smap, nil -} - -func (m Maps) GetList(ctx context.Context, id []int64) ([]model.Map, error) { - var mapList []model.Map - if err := m.db.WithContext(ctx).Find(&mapList, "id IN ?", id).Error; err != nil { - return mapList, err - } - - return mapList, nil -} - -func (m Maps) Create(ctx context.Context, smap model.Map) (model.Map, error) { - if err := m.db.WithContext(ctx).Create(&smap).Error; err != nil { - return smap, err - } - - return smap, nil -} - -func (m Maps) Update(ctx context.Context, id int64, values datastore.OptionalMap) error { - if err := m.db.WithContext(ctx).Model(&model.Map{}).Where("id = ?", id).Updates(values.Map()).Error; err != nil { - if err == gorm.ErrRecordNotFound { - return datastore.ErrNotExist - } - return err - } - - return nil -} - -func (m Maps) Delete(ctx context.Context, id int64) error { - if err := m.db.WithContext(ctx).Delete(&model.Map{}, id).Error; err != nil { - if err == gorm.ErrRecordNotFound { - return datastore.ErrNotExist - } - return err - } - - return nil -} - -func (m Maps) List(ctx context.Context, filters datastore.OptionalMap, page model.Page) ([]model.Map, error) { - var maps []model.Map - if err := m.db.WithContext(ctx).Where(filters.Map()).Offset(int((page.Number - 1) * page.Size)).Limit(int(page.Size)).Find(&maps).Error; err != nil { - return nil, err - } - - return maps, nil + return submission, nil } diff --git a/pkg/model/submission.go b/pkg/model/submission.go index a96728b..36ca80c 100644 --- a/pkg/model/submission.go +++ b/pkg/model/submission.go @@ -2,7 +2,7 @@ package model import "time" -type Map struct { +type Submission struct { ID int64 DisplayName string Creator string diff --git a/pkg/service/service.go b/pkg/service/service.go index 0b04d34..b6fe682 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -1,4 +1,4 @@ -package controller +package service import ( "context" @@ -6,14 +6,14 @@ import ( "git.itzana.me/strafesnet/maps-service/pkg/datastore" ) -type MapsService struct { - db *datastore.Datastore +type Service struct { + DB datastore.Datastore } // NewError creates *ErrorStatusCode from error returned by handler. // // Used for common default response. -func NewError(ctx context.Context, err error) *api.ErrorStatusCode { +func (svc *Service) NewError(ctx context.Context, err error) *api.ErrorStatusCode { return &api.ErrorStatusCode{ StatusCode: 500, Response: api.Error{Message: err.Error()}, diff --git a/pkg/service/submissions.go b/pkg/service/submissions.go index e2313e2..904dd1f 100644 --- a/pkg/service/submissions.go +++ b/pkg/service/submissions.go @@ -1,4 +1,4 @@ -package controller +package service import ( "context" @@ -6,7 +6,7 @@ import ( ) // POST /submissions -func CreateSubmission(ctx context.Context) (*api.Submission, error) { +func (svc *Service) CreateSubmission(ctx context.Context) (*api.Submission, error) { return nil, nil } @@ -15,7 +15,7 @@ func CreateSubmission(ctx context.Context) (*api.Submission, error) { // Retrieve map with ID. // // GET /submissions/{SubmissionID} -func GetSubmission(ctx context.Context, params api.GetSubmissionParams) (*api.Submission, error) { +func (svc *Service) GetSubmission(ctx context.Context, params api.GetSubmissionParams) (*api.Submission, error) { return nil, nil } @@ -24,7 +24,7 @@ func GetSubmission(ctx context.Context, params api.GetSubmissionParams) (*api.Su // Get list of submissions. // // GET /submissions -func ListSubmissions(ctx context.Context, params api.ListSubmissionsParams) ([]api.Submission, error) { +func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissionsParams) ([]api.Submission, error) { return nil, nil } @@ -33,7 +33,7 @@ func ListSubmissions(ctx context.Context, params api.ListSubmissionsParams) ([]a // Retrieve map with ID. // // PATCH /submissions/{SubmissionID}/completed -func PatchSubmissionCompleted(ctx context.Context, params api.PatchSubmissionCompletedParams) error { +func (svc *Service) PatchSubmissionCompleted(ctx context.Context, params api.PatchSubmissionCompletedParams) error { return nil } @@ -42,7 +42,7 @@ func PatchSubmissionCompleted(ctx context.Context, params api.PatchSubmissionCom // Update model following role restrictions. // // PATCH /submissions/{SubmissionID}/model -func PatchSubmissionModel(ctx context.Context, params api.PatchSubmissionModelParams) error { +func (svc *Service) PatchSubmissionModel(ctx context.Context, params api.PatchSubmissionModelParams) error { return nil } @@ -51,6 +51,6 @@ func PatchSubmissionModel(ctx context.Context, params api.PatchSubmissionModelPa // Update status following role restrictions. // // PATCH /submissions/{SubmissionID}/status -func PatchSubmissionStatus(ctx context.Context, params api.PatchSubmissionStatusParams) error { +func (svc *Service) PatchSubmissionStatus(ctx context.Context, params api.PatchSubmissionStatusParams) error { return nil }