From 5cbb5a011e5862d90bd09c6d610448f0bf3f39a0 Mon Sep 17 00:00:00 2001 From: gadotroee <55343099+gadotroee@users.noreply.github.com> Date: Sun, 23 May 2021 13:11:59 +0300 Subject: [PATCH] More complex message (preparation for knowing status of tapped items in UI) (#49) * no message * no message --- Makefile | 3 +- api/pkg/api/main.go | 27 +++++++------- api/pkg/models/models.go | 70 +++++++++++++++++++++++++++-------- ui/src/components/HarPage.tsx | 33 +++++++++++------ 4 files changed, 92 insertions(+), 41 deletions(-) diff --git a/Makefile b/Makefile index eb481cc9d..b304676bc 100644 --- a/Makefile +++ b/Makefile @@ -38,8 +38,7 @@ api: ## build API server docker: ## build Docker image @(echo "building docker image" ) - docker build -t up9inc/mizu:latest . - #./build-push-featurebranch.sh + ./build-push-featurebranch.sh push: push-docker push-cli ## build and publish Mizu docker image & CLI diff --git a/api/pkg/api/main.go b/api/pkg/api/main.go index 1d2882bda..cbec96746 100644 --- a/api/pkg/api/main.go +++ b/api/pkg/api/main.go @@ -33,7 +33,7 @@ func init() { go func() { for { select { - case err := <- errOut: + case err := <-errOut: fmt.Printf("name resolving error %s", err) } } @@ -97,7 +97,7 @@ func saveHarToDb(entry *har.Entry, sender string) { serviceName, urlPath, serviceHostName := getServiceNameFromUrl(entry.Request.URL) entryId := primitive.NewObjectID().Hex() var ( - resolvedSource *string + resolvedSource *string resolvedDestination *string ) if k8sResolver != nil { @@ -105,22 +105,23 @@ func saveHarToDb(entry *har.Entry, sender string) { resolvedDestination = k8sResolver.Resolve(serviceHostName) } mizuEntry := models.MizuEntry{ - EntryId: entryId, - Entry: string(entryBytes), // simple way to store it and not convert to bytes - Service: serviceName, - Url: entry.Request.URL, - Path: urlPath, - Method: entry.Request.Method, - Status: entry.Response.Status, - RequestSenderIp: sender, - Timestamp: entry.StartedDateTime.UnixNano() / int64(time.Millisecond), - ResolvedSource: resolvedSource, + EntryId: entryId, + Entry: string(entryBytes), // simple way to store it and not convert to bytes + Service: serviceName, + Url: entry.Request.URL, + Path: urlPath, + Method: entry.Request.Method, + Status: entry.Response.Status, + RequestSenderIp: sender, + Timestamp: entry.StartedDateTime.UnixNano() / int64(time.Millisecond), + ResolvedSource: resolvedSource, ResolvedDestination: resolvedDestination, } database.GetEntriesTable().Create(&mizuEntry) baseEntry := utils.GetResolvedBaseEntry(mizuEntry) - baseEntryBytes, _ := json.Marshal(&baseEntry) + messageToSend := models.CreateBaseEntryWebSocketMessage(&baseEntry) + baseEntryBytes, _ := json.Marshal(&messageToSend) broadcastToBrowserClients(baseEntryBytes) } diff --git a/api/pkg/models/models.go b/api/pkg/models/models.go index d85387d40..33b9fde91 100644 --- a/api/pkg/models/models.go +++ b/api/pkg/models/models.go @@ -1,21 +1,23 @@ package models -import "time" +import ( + "time" +) type MizuEntry struct { - ID uint `gorm:"primarykey"` - CreatedAt time.Time - UpdatedAt time.Time - Entry string `json:"entry,omitempty" gorm:"column:entry"` - EntryId string `json:"entryId" gorm:"column:entryId"` - Url string `json:"url" gorm:"column:url"` - Method string `json:"method" gorm:"column:method"` - Status int `json:"status" gorm:"column:status"` - RequestSenderIp string `json:"requestSenderIp" gorm:"column:requestSenderIp"` - Service string `json:"service" gorm:"column:service"` - Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` - Path string `json:"path" gorm:"column:path"` - ResolvedSource *string `json:"resolvedSource,omitempty" gorm:"column:resolvedSource"` + ID uint `gorm:"primarykey"` + CreatedAt time.Time + UpdatedAt time.Time + Entry string `json:"entry,omitempty" gorm:"column:entry"` + EntryId string `json:"entryId" gorm:"column:entryId"` + Url string `json:"url" gorm:"column:url"` + Method string `json:"method" gorm:"column:method"` + Status int `json:"status" gorm:"column:status"` + RequestSenderIp string `json:"requestSenderIp" gorm:"column:requestSenderIp"` + Service string `json:"service" gorm:"column:service"` + Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` + Path string `json:"path" gorm:"column:path"` + ResolvedSource *string `json:"resolvedSource,omitempty" gorm:"column:resolvedSource"` ResolvedDestination *string `json:"resolvedDestination,omitempty" gorm:"column:resolvedDestination"` } @@ -31,7 +33,7 @@ type BaseEntryDetails struct { } type EntryData struct { - Entry string `json:"entry,omitempty"` + Entry string `json:"entry,omitempty"` ResolvedDestination *string `json:"resolvedDestination,omitempty" gorm:"column:resolvedDestination"` } @@ -40,3 +42,41 @@ type EntriesFilter struct { Operator string `query:"operator" validate:"required,oneof='lt' 'gt'"` Timestamp int64 `query:"timestamp" validate:"required,min=1"` } + + + +type WebSocketMessageType string +const ( + WebSocketMessageTypeEntry WebSocketMessageType = "entry" + // WebSocketMessageTypeUpdateStatus WebSocketMessageType = "status" +) + +func CreateBaseEntryWebSocketMessage(base *BaseEntryDetails) *WebSocketEntryMessage { + return &WebSocketEntryMessage{ + WebSocketMessageMetadata: &WebSocketMessageMetadata{ + MessageType: WebSocketMessageTypeEntry, + }, + Data: base, + } +} + +//func CreateWebSocketStatusMessage() *WebSocketStatusMessage { +// return &WebSocketEntryMessage{ +// WebSocketMessageMetadata: &WebSocketMessageMetadata{ +// MessageType: WebSocketMessageTypeUpdateStatus, +// } +// } +//} + +type WebSocketEntryMessage struct { + *WebSocketMessageMetadata + Data *BaseEntryDetails `json:"data,omitempty"` +} + +type WebSocketStatusMessage struct { + *WebSocketMessageMetadata +} + +type WebSocketMessageMetadata struct { + MessageType WebSocketMessageType `json:"messageType,omitempty"` +} diff --git a/ui/src/components/HarPage.tsx b/ui/src/components/HarPage.tsx index 6e937bcff..83184bb50 100644 --- a/ui/src/components/HarPage.tsx +++ b/ui/src/components/HarPage.tsx @@ -60,18 +60,29 @@ export const HarPage: React.FC = () => { if(ws.current) { ws.current.onmessage = e => { if(!e?.data) return; - const entry = JSON.parse(e.data); - if(connection === ConnectionStatus.Paused) { - setNoMoreDataBottom(false) - return; + const message = JSON.parse(e.data); + + switch (message.messageType) { + case "entry": + const entry = message.data + if(connection === ConnectionStatus.Paused) { + setNoMoreDataBottom(false) + return; + } + if(!focusedEntryId) setFocusedEntryId(entry.id) + let newEntries = [...entries]; + if(entries.length === 1000) { + newEntries = newEntries.splice(1); + setNoMoreDataTop(false); + } + setEntries([...newEntries, entry]) + break + case "updateStatus": + console.log("not implemented yet") + break + default: + console.error(`unsupported websocket message type, Got: ${message.messageType}`) } - if(!focusedEntryId) setFocusedEntryId(entry.id) - let newEntries = [...entries]; - if(entries.length === 1000) { - newEntries = newEntries.splice(1); - setNoMoreDataTop(false); - } - setEntries([...newEntries, entry]) } }