Skip to content

Commit

Permalink
refactor(api,ssh,pkg): move session's events to it own collection
Browse files Browse the repository at this point in the history
  • Loading branch information
henrybarreto committed Feb 27, 2025
1 parent 6023ec1 commit cfb9dfd
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 181 deletions.
1 change: 1 addition & 0 deletions api/routes/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func (h *Handler) EventSession(c gateway.Context) error {
}

return h.service.EventSession(c.Ctx(), models.UID(req.UID), &models.SessionEvent{
Session: req.UID,
Type: req.Type,
Timestamp: req.Timestamp,
Data: req.Data,
Expand Down
86 changes: 60 additions & 26 deletions api/store/mongo/migrations/migration_90.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package migrations
import (
"context"

"github.com/shellhub-io/shellhub/pkg/models"
"github.com/sirupsen/logrus"
migrate "github.com/xakep666/mongo-migrate"
"go.mongodb.org/mongo-driver/bson"
Expand All @@ -11,55 +12,88 @@ import (

var migration90 = migrate.Migration{
Version: 90,
Description: "Add events field on sessions",
Description: "Add sessions_events collections",
Up: migrate.MigrationFunc(func(ctx context.Context, db *mongo.Database) error {
logrus.WithFields(logrus.Fields{
"component": "migration",
"version": 90,
"action": "Up",
}).Info("Applying migration")

filter := bson.M{
"events": bson.M{"$exists": false},
"events.types": bson.M{"$exists": false},
"events.items": bson.M{"$exists": false},
if err := db.CreateCollection(ctx, "sessions_events"); err != nil {
return err
}

update := bson.M{
"$set": bson.M{
"events": bson.M{
"types": bson.A{},
"items": bson.A{},
"seats": bson.A{0},
},
},
cursor, err := db.Collection("sessions").Find(ctx, bson.M{"events.items": bson.M{"$exists": true}})
if err != nil {
return err
}

_, err := db.
Collection("sessions").
UpdateMany(ctx, filter, update)
defer cursor.Close(ctx)

for cursor.Next(ctx) {
var session struct {
UID string `bson:"uid"`
Events struct {
Items []models.SessionEvent `bson:"items"`
} `bson:"events"`
}

if err := cursor.Decode(&session); err != nil {
return err
}

for _, event := range session.Events.Items {
event.Session = session.UID
if _, err := db.Collection("sessions_events").InsertOne(ctx, event); err != nil {
return err
}
}

if _, err := db.Collection("sessions").UpdateOne(ctx, bson.M{
"uid": session.UID,
}, bson.M{
"$unset": bson.M{
"events.items": "",
},
}); err != nil {
return err
}
}

return err
return nil
}),
Down: migrate.MigrationFunc(func(ctx context.Context, db *mongo.Database) error {
logrus.WithFields(logrus.Fields{
"component": "migration",
"version": 90,
"action": "Down",
}).Info("Reverting migration")
cursor, err := db.Collection("sessions_events").Find(ctx, bson.M{})
if err != nil {
return err
}

filter := bson.M{}
defer cursor.Close(ctx)

update := bson.M{
"$unset": bson.M{
"events": "",
},
for cursor.Next(ctx) {
var event models.SessionEvent
if err := cursor.Decode(&event); err != nil {
return err
}
sessionID := event.Session

event.Session = ""
update := bson.M{"$push": bson.M{"events.items": event}}
if _, err := db.Collection("sessions").UpdateOne(ctx, bson.M{"uid": sessionID}, update); err != nil {
return err
}
}

_, err := db.
Collection("sessions").
UpdateMany(ctx, filter, update)
if err := db.Collection("sessions_events").Drop(ctx); err != nil {
return err
}

return err
return nil
}),
}
82 changes: 27 additions & 55 deletions api/store/mongo/migrations/migration_90_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package migrations

import (
"context"
"fmt"
"testing"

"github.com/shellhub-io/shellhub/pkg/envs"
envmock "github.com/shellhub-io/shellhub/pkg/envs/mocks"
"github.com/shellhub-io/shellhub/pkg/models"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
migrate "github.com/xakep666/mongo-migrate"
Expand All @@ -29,7 +29,20 @@ func TestMigration90Up(t *testing.T) {
_, err := c.
Database("test").
Collection("sessions").
InsertOne(ctx, map[string]interface{}{})
InsertOne(ctx, bson.M{
"uid": "session-1",
"events": bson.M{
"types": bson.A{
"test",
},
"items": []bson.M{
{
"type": "test",
"data": "some data",
},
},
},
})

return err
},
Expand All @@ -45,71 +58,30 @@ func TestMigration90Up(t *testing.T) {
assert.NoError(tt, tc.setup())

migrates := migrate.NewMigrate(c.Database("test"), GenerateMigrations()[89])
require.NoError(tt, migrates.Up(context.Background(), migrate.AllAvailable))
require.NoError(tt, migrates.Up(ctx, migrate.AllAvailable))

query := c.
Database("test").
Collection("sessions").
FindOne(context.TODO(), bson.M{})
Collection("sessions_events").
FindOne(ctx, bson.M{"session": "session-1"})

session := make(map[string]interface{})
require.NoError(tt, query.Decode(&session))
sessionEvent := make(map[string]interface{})
require.NoError(tt, query.Decode(&sessionEvent))
fmt.Println(sessionEvent)

require.Contains(tt, session, "events")
})
}
}
require.Contains(tt, sessionEvent, "type")
require.Contains(tt, sessionEvent, "data")

func TestMigration90Down(t *testing.T) {
ctx := context.Background()

mock := &envmock.Backend{}
envs.DefaultBackend = mock

cases := []struct {
description string
setup func() error
}{
{
description: "Success to revert migration 90",
setup: func() error {
_, err := c.
Database("test").
Collection("sessions").
InsertOne(ctx, models.Session{
Events: models.SessionEvents{
Types: []string{},
Items: []models.SessionEvent{},
Seats: []int{0},
},
})

return err
},
},
}

for _, tc := range cases {
t.Run(tc.description, func(tt *testing.T) {
tt.Cleanup(func() {
assert.NoError(tt, srv.Reset())
})

assert.NoError(tt, tc.setup())

migrates := migrate.NewMigrate(c.Database("test"), GenerateMigrations()[89])
require.NoError(tt, migrates.Up(context.Background(), migrate.AllAvailable))
require.NoError(tt, migrates.Down(context.Background(), migrate.AllAvailable))

query := c.
query = c.
Database("test").
Collection("sessions").
FindOne(context.TODO(), bson.M{})
FindOne(ctx, bson.M{"uid": "session-1"})

session := make(map[string]interface{})
require.NoError(tt, query.Decode(&session))
fmt.Println(session)

require.NotContains(tt, session, "events")
require.NotContains(tt, session, "events.items")
})
}
}
56 changes: 37 additions & 19 deletions api/store/mongo/migrations/migration_91.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

var migration91 = migrate.Migration{
Version: 91,
Description: "Adding seat and seats to sessions and event's session",
Description: "Adding seat and seats to sessions and sessions events",
Up: migrate.MigrationFunc(func(ctx context.Context, db *mongo.Database) error {
logrus.WithFields(logrus.Fields{
"component": "migration",
Expand All @@ -21,18 +21,27 @@ var migration91 = migrate.Migration{

filter := bson.M{}

update := bson.M{
"$set": bson.M{
"events.items.$[].seat": 0,
"events.seats": bson.A{0},
},
if _, err := db.
Collection("sessions").
UpdateMany(ctx, filter, bson.M{
"$set": bson.M{
"events.seats": bson.A{0},
},
}); err != nil {
return err
}

_, err := db.
Collection("sessions").
UpdateMany(ctx, filter, update)
if _, err := db.
Collection("sessions_events").
UpdateMany(ctx, filter, bson.M{
"$set": bson.M{
"seat": 0,
},
}); err != nil {
return err
}

return err
return nil
}),
Down: migrate.MigrationFunc(func(ctx context.Context, db *mongo.Database) error {
logrus.WithFields(logrus.Fields{
Expand All @@ -43,17 +52,26 @@ var migration91 = migrate.Migration{

filter := bson.M{}

update := bson.M{
"$unset": bson.M{
"events.items.$[].seat": "",
"events.seats": "",
},
if _, err := db.
Collection("sessions").
UpdateMany(ctx, filter, bson.M{
"$unset": bson.M{
"events.seats": "",
},
}); err != nil {
return err
}

_, err := db.
Collection("sessions").
UpdateMany(ctx, filter, update)
if _, err := db.
Collection("sessions_events").
UpdateMany(ctx, filter, bson.M{
"$unset": bson.M{
"seat": "",
},
}); err != nil {
return err
}

return err
return nil
}),
}
Loading

0 comments on commit cfb9dfd

Please sign in to comment.