diff --git a/example.env b/example.env index 5d7f92f..ffe812f 100644 --- a/example.env +++ b/example.env @@ -1,4 +1,10 @@ DEBUG=false HOST=127.0.0.1 PORT=8080 -MANAGEMENTSYSTEM_API_KEY=test \ No newline at end of file +MANAGEMENTSYSTEM_API_KEY=test + +# ScyllaDB +SCYLLADB_HOST=127.0.0.1 +SCYLLADB_USERNAME=user +SCYLLADB_PASSWORD=password +SCYLLADB_KEYSPACE=keyspace \ No newline at end of file diff --git a/go.mod b/go.mod index 96b1ac1..a1e68c4 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,10 @@ require ( require ( github.com/andybalholm/brotli v1.0.4 // indirect + github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect @@ -19,9 +22,12 @@ require ( github.com/rivo/uniseg v0.4.3 // indirect github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect github.com/savsgio/gotils v0.0.0-20230203094617-bcbc01813b4f // indirect + github.com/scylladb/go-reflectx v1.0.1 // indirect + github.com/scylladb/gocqlx/v2 v2.8.0 // indirect github.com/tinylib/msgp v1.1.8 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.44.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect golang.org/x/sys v0.4.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect ) diff --git a/go.sum b/go.sum index 82cd9f8..203bcfd 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,30 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= 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/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 h1:px9qUCy/RNJNsfCam4m2IxWGxNuimkrioEF0vrrbPsg= +github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= github.com/gofiber/fiber/v2 v2.42.0 h1:Fnp7ybWvS+sjNQsFvkhf4G8OhXswvB6Vee8hM/LyS+8= github.com/gofiber/fiber/v2 v2.42.0/go.mod h1:3+SGNjqMh5VQH5Vz2Wdi43zTIV16ktlFd3x3R6O1Zlc= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/joho/godotenv v1.5.0 h1:C/Vohk/9L1RCoS/UW2gfyi2N0EElSW3yb9zwi3PjosE= github.com/joho/godotenv v1.5.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -36,9 +48,14 @@ github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d h1:Q+gqLBOPkFGHyCJx github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= github.com/savsgio/gotils v0.0.0-20230203094617-bcbc01813b4f h1:LKLq2MuL/uCGWS7BGo7yOeE/sj5wKxy2aQs69D8imsc= github.com/savsgio/gotils v0.0.0-20230203094617-bcbc01813b4f/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= +github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= +github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= +github.com/scylladb/gocqlx/v2 v2.8.0 h1:f/oIgoEPjKDKd+RIoeHqexsIQVIbalVmT+axwvUqQUg= +github.com/scylladb/gocqlx/v2 v2.8.0/go.mod h1:4/+cga34PVqjhgSoo5Nr2fX1MQIqZB5eCE5DK4xeDig= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= @@ -105,5 +122,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 8214a90..6d58415 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ package main import ( "clickandjoin.app/managementsystem/modules/config" + "clickandjoin.app/managementsystem/modules/scylladb" "clickandjoin.app/managementsystem/routers/router" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" @@ -30,6 +31,8 @@ func init() { } logrus.Println("Debug:", config.Cfg.Debug) + + scylladb.InitDatabase() } func main() { @@ -43,40 +46,7 @@ func main() { })) } - /* - cache.WebSocketSessions["test"] = []string{"alpha", "test", "testa", "bob", "beta"} - - logrus.Println(len(cache.WebSocketSessions["test"])) - - user := cache.WebSocketSessions["test"] - - for index, item := range user { - if item == "alpha" { - user = remove(user, index) - } - } - - logrus.Println("s", cache.WebSocketSessions, len(user)) */ - /* - t1 := time.NewTicker(3 * time.Second) - - i := 0 - - go func() { - for range t1.C { - i++ - logrus.Println("timer", cache.WebSocketSessions) - } - }() */ - router.SetupRoutes(app) app.Listen(cfg.Host + ":" + cfg.Port) } - -/* -func remove(s []string, i int) []string { - s[i] = s[0] - return s[1:] -} -*/ diff --git a/modules/config/config.go b/modules/config/config.go index 6742182..d37787c 100644 --- a/modules/config/config.go +++ b/modules/config/config.go @@ -15,6 +15,14 @@ type Config struct { Host string Port string ManagementSystemApiKey string + ScyllaDB ScyllaDB +} + +type ScyllaDB struct { + Host string + Username string + Password string + Keyspace string } func LoadConfig() { @@ -38,6 +46,12 @@ func LoadConfig() { Host: os.Getenv("HOST"), Port: os.Getenv("PORT"), ManagementSystemApiKey: os.Getenv("MANAGEMENTSYSTEM_API_KEY"), + ScyllaDB: ScyllaDB{ + Host: os.Getenv("SCYLLADB_HOST"), + Username: os.Getenv("SCYLLADB_USERNAME"), + Password: os.Getenv("SCYLLADB_PASSWORD"), + Keyspace: os.Getenv("SCYLLADB_KEYSPACE"), + }, } Cfg = cfg diff --git a/modules/scylladb/models.go b/modules/scylladb/models.go new file mode 100644 index 0000000..dcd5bd0 --- /dev/null +++ b/modules/scylladb/models.go @@ -0,0 +1,31 @@ +package scylladb + +import ( + "github.com/scylladb/gocqlx/v2/table" +) + +var ( + Users = table.New(table.Metadata{ + Name: "users", + Columns: []string{ + "id", + "username", + "account_name", + "account_name_lc", + "email", + "password", + "description", + "latitude", + "longitude", + "xp_level", + "xp_points", + "followers_count", + "following_count", + "account_status", + "avatar_url", + "public_keys", + "created_at", + "updated_at"}, + PartKey: []string{"id"}, + }) +) diff --git a/modules/scylladb/scylladb.go b/modules/scylladb/scylladb.go new file mode 100644 index 0000000..8e1a250 --- /dev/null +++ b/modules/scylladb/scylladb.go @@ -0,0 +1,32 @@ +package scylladb + +import ( + "clickandjoin.app/managementsystem/modules/config" + "github.com/gocql/gocql" + "github.com/scylladb/gocqlx/v2" + "github.com/sirupsen/logrus" +) + +var Session gocqlx.Session +var Cluster *gocql.ClusterConfig + +func InitDatabase() { + Cluster = gocql.NewCluster(config.Cfg.ScyllaDB.Host) + + Cluster.Authenticator = gocql.PasswordAuthenticator{ + Username: config.Cfg.ScyllaDB.Username, + Password: config.Cfg.ScyllaDB.Password, + } + + Cluster.Keyspace = config.Cfg.ScyllaDB.Keyspace + + var err error + + Session, err = gocqlx.WrapSession(Cluster.CreateSession()) + + if err != nil { + logrus.Fatal(err) + } + + logrus.Info("Database connected") +} diff --git a/modules/structs/user.go b/modules/structs/user.go new file mode 100644 index 0000000..fc8fa1a --- /dev/null +++ b/modules/structs/user.go @@ -0,0 +1,52 @@ +package structs + +import ( + "reflect" + + "github.com/gocql/gocql" + "github.com/scylladb/gocqlx/v2" +) + +type User struct { + Id string + Username string + AccountName string + AccountNameLc string + Email string + Password string + Description string + Latitude float64 + Longitude float64 + XpLevel int + XpPoints int + FollowersCount int + FollowingCount int + AccountStatus uint8 + AvatarUrl string + PublicKeys []UserPublicKeys + CreatedAt int64 + UpdatedAt int64 +} + +type UserPublicKeys struct { + gocqlx.UDT + Id string + PublicKey string +} + +// needed to store into database +func (u UserPublicKeys) MarshalUDT(name string, info gocql.TypeInfo) ([]byte, error) { + f := gocqlx.DefaultMapper.FieldByName(reflect.ValueOf(u), name) + return gocql.Marshal(info, f.Interface()) +} + +// needed to take from database +func (u *UserPublicKeys) UnmarshalUDT(name string, info gocql.TypeInfo, data []byte) error { + f := gocqlx.DefaultMapper.FieldByName(reflect.ValueOf(u), name) + return gocql.Unmarshal(info, data, f.Addr().Interface()) +} + +// swagger:model UsersResponse +type UsersResponse struct { + Users []User +} diff --git a/routers/api/v1/users/users.go b/routers/api/v1/users/users.go new file mode 100644 index 0000000..edb457d --- /dev/null +++ b/routers/api/v1/users/users.go @@ -0,0 +1,46 @@ +package users + +import ( + "clickandjoin.app/managementsystem/modules/scylladb" + "clickandjoin.app/managementsystem/modules/structs" + "github.com/gofiber/fiber/v2" + "github.com/sirupsen/logrus" +) + +func GetAllUsers(c *fiber.Ctx) error { + // swagger:operation GET /users users usersGetAllUsers + // --- + // summary: List of users + // consumes: + // - application/json + // produces: + // - application/json + // responses: + // '200': + // description: List of users + // schema: + // "$ref": "#/definitions/FoundAccountNamesResponse" + // '400': + // description: Invalid account name format + // '500': + // description: Internal server error + + var users []structs.User + + q := scylladb.Session.Query(scylladb.Users.SelectAll()) + + if err := q.SelectRelease(&users); err != nil { + logrus.Errorln("Failed to get users, err:", err) + } + + var nUsers []structs.User + + if len(users) > 0 { // remove password value from result + for _, user := range users { + user.Password = "" + nUsers = append(nUsers, user) + } + } + + return c.JSON(structs.UsersResponse{Users: nUsers}) +} diff --git a/routers/router/router.go b/routers/router/router.go index 18d79af..cb8c500 100644 --- a/routers/router/router.go +++ b/routers/router/router.go @@ -2,11 +2,15 @@ package router import ( "clickandjoin.app/managementsystem/modules/config" + "clickandjoin.app/managementsystem/routers/api/v1/users" "github.com/gofiber/fiber/v2" ) func SetupRoutes(app *fiber.App) { - //v1 := app.Group("/v1") + v1 := app.Group("/v1") + + us := v1.Group("/users") + us.Get("/", ApiKeyValidation, users.GetAllUsers) } func ApiKeyValidation(c *fiber.Ctx) error {