mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-03-18 18:42:44 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c010d336bb | ||
|
|
710411e112 | ||
|
|
274fbeb34a | ||
|
|
38c05a6634 |
@@ -22,7 +22,7 @@ func (e *DefaultEntryStreamerSocketConnector) SendEntry(socketId int, entry *tap
|
|||||||
if params.EnableFullEntries {
|
if params.EnableFullEntries {
|
||||||
message, _ = models.CreateFullEntryWebSocketMessage(entry)
|
message, _ = models.CreateFullEntryWebSocketMessage(entry)
|
||||||
} else {
|
} else {
|
||||||
protocol, ok := protocolsMap[entry.ProtocolId]
|
protocol, ok := protocolsMap[entry.Protocol.ToString()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("protocol not found, protocol: %v", protocol)
|
return fmt.Errorf("protocol not found, protocol: %v", protocol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ func startReadingChannel(outputItems <-chan *tapApi.OutputChannelItem, extension
|
|||||||
serviceMapGenerator.NewTCPEntry(mizuEntry.Source, mizuEntry.Destination, &item.Protocol)
|
serviceMapGenerator.NewTCPEntry(mizuEntry.Source, mizuEntry.Destination, &item.Protocol)
|
||||||
|
|
||||||
oasGenerator := dependency.GetInstance(dependency.OasGeneratorDependency).(oas.OasGeneratorSink)
|
oasGenerator := dependency.GetInstance(dependency.OasGeneratorDependency).(oas.OasGeneratorSink)
|
||||||
oasGenerator.HandleEntry(mizuEntry, &item.Protocol)
|
oasGenerator.HandleEntry(mizuEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,11 +36,13 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var ProtocolHttp = &tapApi.Protocol{
|
var ProtocolHttp = &tapApi.Protocol{
|
||||||
|
ProtocolSummary: tapApi.ProtocolSummary{
|
||||||
Name: "http",
|
Name: "http",
|
||||||
LongName: "Hypertext Transfer Protocol -- HTTP/1.1",
|
|
||||||
Abbreviation: "HTTP",
|
|
||||||
Macro: "http",
|
|
||||||
Version: "1.1",
|
Version: "1.1",
|
||||||
|
Abbreviation: "HTTP",
|
||||||
|
},
|
||||||
|
LongName: "Hypertext Transfer Protocol -- HTTP/1.1",
|
||||||
|
Macro: "http",
|
||||||
BackgroundColor: "#205cf5",
|
BackgroundColor: "#205cf5",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 12,
|
FontSize: 12,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func (e *BasenineEntriesProvider) GetEntries(entriesRequest *models.EntriesReque
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol, ok := app.ProtocolsMap[entry.ProtocolId]
|
protocol, ok := app.ProtocolsMap[entry.Protocol.ToString()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, fmt.Errorf("protocol not found, protocol: %v", protocol)
|
return nil, nil, fmt.Errorf("protocol not found, protocol: %v", protocol)
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ func (e *BasenineEntriesProvider) GetEntry(singleEntryRequest *models.SingleEntr
|
|||||||
return nil, errors.New(string(bytes))
|
return nil, errors.New(string(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol, ok := app.ProtocolsMap[entry.ProtocolId]
|
protocol, ok := app.ProtocolsMap[entry.Protocol.ToString()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("protocol not found, protocol: %v", protocol)
|
return nil, fmt.Errorf("protocol not found, protocol: %v", protocol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type OasGeneratorSink interface {
|
type OasGeneratorSink interface {
|
||||||
HandleEntry(mizuEntry *api.Entry, protocol *api.Protocol)
|
HandleEntry(mizuEntry *api.Entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
type OasGenerator interface {
|
type OasGenerator interface {
|
||||||
@@ -58,12 +58,12 @@ func (g *defaultOasGenerator) IsStarted() bool {
|
|||||||
return g.started
|
return g.started
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *defaultOasGenerator) HandleEntry(mizuEntry *api.Entry, protocol *api.Protocol) {
|
func (g *defaultOasGenerator) HandleEntry(mizuEntry *api.Entry) {
|
||||||
if !g.started {
|
if !g.started {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if protocol.Name == "http" {
|
if mizuEntry.Protocol.Name == "http" {
|
||||||
dest := mizuEntry.Destination.Name
|
dest := mizuEntry.Destination.Name
|
||||||
if dest == "" {
|
if dest == "" {
|
||||||
logger.Log.Debugf("OAS: Unresolved entry %d", mizuEntry.Id)
|
logger.Log.Debugf("OAS: Unresolved entry %d", mizuEntry.Id)
|
||||||
@@ -85,7 +85,7 @@ func (g *defaultOasGenerator) HandleEntry(mizuEntry *api.Entry, protocol *api.Pr
|
|||||||
|
|
||||||
g.handleHARWithSource(entryWSource)
|
g.handleHARWithSource(entryWSource)
|
||||||
} else {
|
} else {
|
||||||
logger.Log.Debugf("OAS: Unsupported protocol in entry %d: %s", mizuEntry.Id, protocol.Name)
|
logger.Log.Debugf("OAS: Unsupported protocol in entry %d: %s", mizuEntry.Id, mizuEntry.Protocol.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func TestEntryAddedCount(t *testing.T) {
|
|||||||
|
|
||||||
entryBucketKey := time.Date(2021, 1, 1, 10, 0, 0, 0, time.UTC)
|
entryBucketKey := time.Date(2021, 1, 1, 10, 0, 0, 0, time.UTC)
|
||||||
valueLessThanBucketThreshold := time.Second * 130
|
valueLessThanBucketThreshold := time.Second * 130
|
||||||
mockSummery := &api.BaseEntry{Protocol: api.Protocol{Name: "mock"}, Method: "mock-method", Timestamp: entryBucketKey.Add(valueLessThanBucketThreshold).UnixNano()}
|
mockSummery := &api.BaseEntry{Protocol: api.Protocol{ProtocolSummary: api.ProtocolSummary{Name: "mock"}}, Method: "mock-method", Timestamp: entryBucketKey.Add(valueLessThanBucketThreshold).UnixNano()}
|
||||||
for _, entriesCount := range tests {
|
for _, entriesCount := range tests {
|
||||||
t.Run(fmt.Sprintf("%d", entriesCount), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", entriesCount), func(t *testing.T) {
|
||||||
for i := 0; i < entriesCount; i++ {
|
for i := 0; i < entriesCount; i++ {
|
||||||
@@ -61,7 +61,7 @@ func TestEntryAddedVolume(t *testing.T) {
|
|||||||
var expectedEntriesCount int
|
var expectedEntriesCount int
|
||||||
var expectedVolumeInGB float64
|
var expectedVolumeInGB float64
|
||||||
|
|
||||||
mockSummery := &api.BaseEntry{Protocol: api.Protocol{Name: "mock"}, Method: "mock-method", Timestamp: time.Date(2021, 1, 1, 10, 0, 0, 0, time.UTC).UnixNano()}
|
mockSummery := &api.BaseEntry{Protocol: api.Protocol{ProtocolSummary: api.ProtocolSummary{Name: "mock"}}, Method: "mock-method", Timestamp: time.Date(2021, 1, 1, 10, 0, 0, 0, time.UTC).UnixNano()}
|
||||||
|
|
||||||
for _, data := range tests {
|
for _, data := range tests {
|
||||||
t.Run(fmt.Sprintf("%d", len(data)), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", len(data)), func(t *testing.T) {
|
||||||
|
|||||||
@@ -50,11 +50,13 @@ var (
|
|||||||
IP: fmt.Sprintf("%s.%s", Ip, UnresolvedNodeName),
|
IP: fmt.Sprintf("%s.%s", Ip, UnresolvedNodeName),
|
||||||
}
|
}
|
||||||
ProtocolHttp = &tapApi.Protocol{
|
ProtocolHttp = &tapApi.Protocol{
|
||||||
|
ProtocolSummary: tapApi.ProtocolSummary{
|
||||||
Name: "http",
|
Name: "http",
|
||||||
LongName: "Hypertext Transfer Protocol -- HTTP/1.1",
|
|
||||||
Abbreviation: "HTTP",
|
|
||||||
Macro: "http",
|
|
||||||
Version: "1.1",
|
Version: "1.1",
|
||||||
|
Abbreviation: "HTTP",
|
||||||
|
},
|
||||||
|
LongName: "Hypertext Transfer Protocol -- HTTP/1.1",
|
||||||
|
Macro: "http",
|
||||||
BackgroundColor: "#205cf5",
|
BackgroundColor: "#205cf5",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 12,
|
FontSize: 12,
|
||||||
@@ -63,11 +65,13 @@ var (
|
|||||||
Priority: 0,
|
Priority: 0,
|
||||||
}
|
}
|
||||||
ProtocolRedis = &tapApi.Protocol{
|
ProtocolRedis = &tapApi.Protocol{
|
||||||
|
ProtocolSummary: tapApi.ProtocolSummary{
|
||||||
Name: "redis",
|
Name: "redis",
|
||||||
LongName: "Redis Serialization Protocol",
|
|
||||||
Abbreviation: "REDIS",
|
|
||||||
Macro: "redis",
|
|
||||||
Version: "3.x",
|
Version: "3.x",
|
||||||
|
Abbreviation: "REDIS",
|
||||||
|
},
|
||||||
|
LongName: "Redis Serialization Protocol",
|
||||||
|
Macro: "redis",
|
||||||
BackgroundColor: "#a41e11",
|
BackgroundColor: "#a41e11",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 11,
|
FontSize: 11,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -14,12 +15,20 @@ const UnknownNamespace = ""
|
|||||||
var UnknownIp = net.IP{0, 0, 0, 0}
|
var UnknownIp = net.IP{0, 0, 0, 0}
|
||||||
var UnknownPort uint16 = 0
|
var UnknownPort uint16 = 0
|
||||||
|
|
||||||
type Protocol struct {
|
type ProtocolSummary struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
LongName string `json:"longName"`
|
|
||||||
Abbreviation string `json:"abbr"`
|
|
||||||
Macro string `json:"macro"`
|
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
|
Abbreviation string `json:"abbr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (protocol *ProtocolSummary) ToString() string {
|
||||||
|
return fmt.Sprintf("%s?%s?%s", protocol.Name, protocol.Version, protocol.Abbreviation)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Protocol struct {
|
||||||
|
ProtocolSummary
|
||||||
|
LongName string `json:"longName"`
|
||||||
|
Macro string `json:"macro"`
|
||||||
BackgroundColor string `json:"backgroundColor"`
|
BackgroundColor string `json:"backgroundColor"`
|
||||||
ForegroundColor string `json:"foregroundColor"`
|
ForegroundColor string `json:"foregroundColor"`
|
||||||
FontSize int8 `json:"fontSize"`
|
FontSize int8 `json:"fontSize"`
|
||||||
@@ -151,7 +160,7 @@ func (e *Emitting) Emit(item *OutputChannelItem) {
|
|||||||
|
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
ProtocolId string `json:"protocol"`
|
Protocol ProtocolSummary `json:"protocol"`
|
||||||
Capture Capture `json:"capture"`
|
Capture Capture `json:"capture"`
|
||||||
Source *TCP `json:"src"`
|
Source *TCP `json:"src"`
|
||||||
Destination *TCP `json:"dst"`
|
Destination *TCP `json:"dst"`
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect14/amqp/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect15/amqp/\* expect
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var protocol = api.Protocol{
|
var protocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "amqp",
|
Name: "amqp",
|
||||||
LongName: "Advanced Message Queuing Protocol 0-9-1",
|
|
||||||
Abbreviation: "AMQP",
|
|
||||||
Macro: "amqp",
|
|
||||||
Version: "0-9-1",
|
Version: "0-9-1",
|
||||||
|
Abbreviation: "AMQP",
|
||||||
|
},
|
||||||
|
LongName: "Advanced Message Queuing Protocol 0-9-1",
|
||||||
|
Macro: "amqp",
|
||||||
BackgroundColor: "#ff6600",
|
BackgroundColor: "#ff6600",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 12,
|
FontSize: 12,
|
||||||
@@ -27,7 +29,7 @@ var protocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var protocolsMap = map[string]*api.Protocol{
|
var protocolsMap = map[string]*api.Protocol{
|
||||||
fmt.Sprintf("%s/%s/%s", protocol.Name, protocol.Version, protocol.Abbreviation): &protocol,
|
protocol.ToString(): &protocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
type dissecting string
|
type dissecting string
|
||||||
@@ -222,7 +224,7 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string,
|
|||||||
|
|
||||||
reqDetails["method"] = request["method"]
|
reqDetails["method"] = request["method"]
|
||||||
return &api.Entry{
|
return &api.Entry{
|
||||||
ProtocolId: fmt.Sprintf("%s/%s/%s", protocol.Name, protocol.Version, protocol.Abbreviation),
|
Protocol: protocol.ProtocolSummary,
|
||||||
Capture: item.Capture,
|
Capture: item.Capture,
|
||||||
Source: &api.TCP{
|
Source: &api.TCP{
|
||||||
Name: resolvedSource,
|
Name: resolvedSource,
|
||||||
@@ -285,7 +287,7 @@ func (d dissecting) Summarize(entry *api.Entry) *api.BaseEntry {
|
|||||||
|
|
||||||
return &api.BaseEntry{
|
return &api.BaseEntry{
|
||||||
Id: entry.Id,
|
Id: entry.Id,
|
||||||
Protocol: *protocolsMap[entry.ProtocolId],
|
Protocol: *protocolsMap[entry.Protocol.ToString()],
|
||||||
Capture: entry.Capture,
|
Capture: entry.Capture,
|
||||||
Summary: summary,
|
Summary: summary,
|
||||||
SummaryQuery: summaryQuery,
|
SummaryQuery: summaryQuery,
|
||||||
@@ -329,7 +331,7 @@ func (d dissecting) Represent(request map[string]interface{}, response map[strin
|
|||||||
|
|
||||||
func (d dissecting) Macros() map[string]string {
|
func (d dissecting) Macros() map[string]string {
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
`amqp`: fmt.Sprintf(`protocol == "%s/%s/%s"`, protocol.Name, protocol.Version, protocol.Abbreviation),
|
`amqp`: fmt.Sprintf(`protocol.name == "%s"`, protocol.Name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func TestRegister(t *testing.T) {
|
|||||||
|
|
||||||
func TestMacros(t *testing.T) {
|
func TestMacros(t *testing.T) {
|
||||||
expectedMacros := map[string]string{
|
expectedMacros := map[string]string{
|
||||||
"amqp": `protocol == "amqp/0-9-1/AMQP"`,
|
"amqp": `protocol.name == "amqp"`,
|
||||||
}
|
}
|
||||||
dissector := NewDissector()
|
dissector := NewDissector()
|
||||||
macros := dissector.Macros()
|
macros := dissector.Macros()
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect14/http/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect15/http/\* expect
|
||||||
|
|||||||
@@ -15,11 +15,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var http10protocol = api.Protocol{
|
var http10protocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "http",
|
Name: "http",
|
||||||
LongName: "Hypertext Transfer Protocol -- HTTP/1.0",
|
|
||||||
Abbreviation: "HTTP",
|
|
||||||
Macro: "http",
|
|
||||||
Version: "1.0",
|
Version: "1.0",
|
||||||
|
Abbreviation: "HTTP",
|
||||||
|
},
|
||||||
|
LongName: "Hypertext Transfer Protocol -- HTTP/1.0",
|
||||||
|
Macro: "http",
|
||||||
BackgroundColor: "#205cf5",
|
BackgroundColor: "#205cf5",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 12,
|
FontSize: 12,
|
||||||
@@ -29,11 +31,13 @@ var http10protocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var http11protocol = api.Protocol{
|
var http11protocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "http",
|
Name: "http",
|
||||||
LongName: "Hypertext Transfer Protocol -- HTTP/1.1",
|
|
||||||
Abbreviation: "HTTP",
|
|
||||||
Macro: "http",
|
|
||||||
Version: "1.1",
|
Version: "1.1",
|
||||||
|
Abbreviation: "HTTP",
|
||||||
|
},
|
||||||
|
LongName: "Hypertext Transfer Protocol -- HTTP/1.1",
|
||||||
|
Macro: "http",
|
||||||
BackgroundColor: "#205cf5",
|
BackgroundColor: "#205cf5",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 12,
|
FontSize: 12,
|
||||||
@@ -43,11 +47,13 @@ var http11protocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var http2Protocol = api.Protocol{
|
var http2Protocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "http",
|
Name: "http",
|
||||||
LongName: "Hypertext Transfer Protocol Version 2 (HTTP/2)",
|
|
||||||
Abbreviation: "HTTP/2",
|
|
||||||
Macro: "http2",
|
|
||||||
Version: "2.0",
|
Version: "2.0",
|
||||||
|
Abbreviation: "HTTP/2",
|
||||||
|
},
|
||||||
|
LongName: "Hypertext Transfer Protocol Version 2 (HTTP/2)",
|
||||||
|
Macro: "http2",
|
||||||
BackgroundColor: "#244c5a",
|
BackgroundColor: "#244c5a",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 11,
|
FontSize: 11,
|
||||||
@@ -57,11 +63,13 @@ var http2Protocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var grpcProtocol = api.Protocol{
|
var grpcProtocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "http",
|
Name: "http",
|
||||||
LongName: "Hypertext Transfer Protocol Version 2 (HTTP/2) [ gRPC over HTTP/2 ]",
|
|
||||||
Abbreviation: "gRPC",
|
|
||||||
Macro: "grpc",
|
|
||||||
Version: "2.0",
|
Version: "2.0",
|
||||||
|
Abbreviation: "gRPC",
|
||||||
|
},
|
||||||
|
LongName: "Hypertext Transfer Protocol Version 2 (HTTP/2) [ gRPC over HTTP/2 ]",
|
||||||
|
Macro: "grpc",
|
||||||
BackgroundColor: "#244c5a",
|
BackgroundColor: "#244c5a",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 11,
|
FontSize: 11,
|
||||||
@@ -71,11 +79,13 @@ var grpcProtocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var graphQL1Protocol = api.Protocol{
|
var graphQL1Protocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "http",
|
Name: "http",
|
||||||
LongName: "Hypertext Transfer Protocol -- HTTP/1.1 [ GraphQL over HTTP/1.1 ]",
|
|
||||||
Abbreviation: "GQL",
|
|
||||||
Macro: "gql",
|
|
||||||
Version: "1.1",
|
Version: "1.1",
|
||||||
|
Abbreviation: "GQL",
|
||||||
|
},
|
||||||
|
LongName: "Hypertext Transfer Protocol -- HTTP/1.1 [ GraphQL over HTTP/1.1 ]",
|
||||||
|
Macro: "gql",
|
||||||
BackgroundColor: "#e10098",
|
BackgroundColor: "#e10098",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 12,
|
FontSize: 12,
|
||||||
@@ -85,11 +95,13 @@ var graphQL1Protocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var graphQL2Protocol = api.Protocol{
|
var graphQL2Protocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "http",
|
Name: "http",
|
||||||
LongName: "Hypertext Transfer Protocol Version 2 (HTTP/2) [ GraphQL over HTTP/2 ]",
|
|
||||||
Abbreviation: "GQL",
|
|
||||||
Macro: "gql",
|
|
||||||
Version: "2.0",
|
Version: "2.0",
|
||||||
|
Abbreviation: "GQL",
|
||||||
|
},
|
||||||
|
LongName: "Hypertext Transfer Protocol Version 2 (HTTP/2) [ GraphQL over HTTP/2 ]",
|
||||||
|
Macro: "gql",
|
||||||
BackgroundColor: "#e10098",
|
BackgroundColor: "#e10098",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 12,
|
FontSize: 12,
|
||||||
@@ -99,12 +111,12 @@ var graphQL2Protocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var protocolsMap = map[string]*api.Protocol{
|
var protocolsMap = map[string]*api.Protocol{
|
||||||
fmt.Sprintf("%s/%s/%s", http10protocol.Name, http10protocol.Version, http10protocol.Abbreviation): &http10protocol,
|
http10protocol.ToString(): &http10protocol,
|
||||||
fmt.Sprintf("%s/%s/%s", http11protocol.Name, http11protocol.Version, http11protocol.Abbreviation): &http11protocol,
|
http11protocol.ToString(): &http11protocol,
|
||||||
fmt.Sprintf("%s/%s/%s", http2Protocol.Name, http2Protocol.Version, http2Protocol.Abbreviation): &http2Protocol,
|
http2Protocol.ToString(): &http2Protocol,
|
||||||
fmt.Sprintf("%s/%s/%s", grpcProtocol.Name, grpcProtocol.Version, grpcProtocol.Abbreviation): &grpcProtocol,
|
grpcProtocol.ToString(): &grpcProtocol,
|
||||||
fmt.Sprintf("%s/%s/%s", graphQL1Protocol.Name, graphQL1Protocol.Version, graphQL1Protocol.Abbreviation): &graphQL1Protocol,
|
graphQL1Protocol.ToString(): &graphQL1Protocol,
|
||||||
fmt.Sprintf("%s/%s/%s", graphQL2Protocol.Name, graphQL2Protocol.Version, graphQL2Protocol.Abbreviation): &graphQL2Protocol,
|
graphQL2Protocol.ToString(): &graphQL2Protocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -294,7 +306,7 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &api.Entry{
|
return &api.Entry{
|
||||||
ProtocolId: fmt.Sprintf("%s/%s/%s", item.Protocol.Name, item.Protocol.Version, item.Protocol.Abbreviation),
|
Protocol: item.Protocol.ProtocolSummary,
|
||||||
Capture: item.Capture,
|
Capture: item.Capture,
|
||||||
Source: &api.TCP{
|
Source: &api.TCP{
|
||||||
Name: resolvedSource,
|
Name: resolvedSource,
|
||||||
@@ -328,7 +340,7 @@ func (d dissecting) Summarize(entry *api.Entry) *api.BaseEntry {
|
|||||||
|
|
||||||
return &api.BaseEntry{
|
return &api.BaseEntry{
|
||||||
Id: entry.Id,
|
Id: entry.Id,
|
||||||
Protocol: *protocolsMap[entry.ProtocolId],
|
Protocol: *protocolsMap[entry.Protocol.ToString()],
|
||||||
Capture: entry.Capture,
|
Capture: entry.Capture,
|
||||||
Summary: summary,
|
Summary: summary,
|
||||||
SummaryQuery: summaryQuery,
|
SummaryQuery: summaryQuery,
|
||||||
@@ -515,10 +527,10 @@ func (d dissecting) Represent(request map[string]interface{}, response map[strin
|
|||||||
|
|
||||||
func (d dissecting) Macros() map[string]string {
|
func (d dissecting) Macros() map[string]string {
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
`http`: fmt.Sprintf(`protocol == "%s/%s/%s" or protocol == "%s/%s/%s"`, http10protocol.Name, http10protocol.Version, http10protocol.Abbreviation, http11protocol.Name, http11protocol.Version, http11protocol.Abbreviation),
|
`http`: fmt.Sprintf(`protocol.abbr == "%s"`, http11protocol.Abbreviation),
|
||||||
`http2`: fmt.Sprintf(`protocol == "%s/%s/%s"`, http2Protocol.Name, http2Protocol.Version, http2Protocol.Abbreviation),
|
`http2`: fmt.Sprintf(`protocol.abbr == "%s"`, http2Protocol.Abbreviation),
|
||||||
`grpc`: fmt.Sprintf(`protocol == "%s/%s/%s"`, grpcProtocol.Name, grpcProtocol.Version, grpcProtocol.Abbreviation),
|
`grpc`: fmt.Sprintf(`protocol.abbr == "%s"`, grpcProtocol.Abbreviation),
|
||||||
`gql`: fmt.Sprintf(`protocol == "%s/%s/%s" or protocol == "%s/%s/%s"`, graphQL1Protocol.Name, graphQL1Protocol.Version, graphQL1Protocol.Abbreviation, graphQL2Protocol.Name, graphQL2Protocol.Version, graphQL2Protocol.Abbreviation),
|
`gql`: fmt.Sprintf(`protocol.abbr == "%s"`, graphQL1Protocol.Abbreviation),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ func TestRegister(t *testing.T) {
|
|||||||
|
|
||||||
func TestMacros(t *testing.T) {
|
func TestMacros(t *testing.T) {
|
||||||
expectedMacros := map[string]string{
|
expectedMacros := map[string]string{
|
||||||
"http": `protocol == "http/1.0/HTTP" or protocol == "http/1.1/HTTP"`,
|
"http": `protocol.abbr == "HTTP"`,
|
||||||
"http2": `protocol == "http/2.0/HTTP/2"`,
|
"http2": `protocol.abbr == "HTTP/2"`,
|
||||||
"grpc": `protocol == "http/2.0/gRPC"`,
|
"grpc": `protocol.abbr == "gRPC"`,
|
||||||
"gql": `protocol == "http/1.1/GQL" or protocol == "http/2.0/GQL"`,
|
"gql": `protocol.abbr == "GQL"`,
|
||||||
}
|
}
|
||||||
dissector := NewDissector()
|
dissector := NewDissector()
|
||||||
macros := dissector.Macros()
|
macros := dissector.Macros()
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect14/kafka/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect15/kafka/\* expect
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _protocol = api.Protocol{
|
var _protocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "kafka",
|
Name: "kafka",
|
||||||
LongName: "Apache Kafka Protocol",
|
|
||||||
Abbreviation: "KAFKA",
|
|
||||||
Macro: "kafka",
|
|
||||||
Version: "12",
|
Version: "12",
|
||||||
|
Abbreviation: "KAFKA",
|
||||||
|
},
|
||||||
|
LongName: "Apache Kafka Protocol",
|
||||||
|
Macro: "kafka",
|
||||||
BackgroundColor: "#000000",
|
BackgroundColor: "#000000",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 11,
|
FontSize: 11,
|
||||||
@@ -25,7 +27,7 @@ var _protocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var protocolsMap = map[string]*api.Protocol{
|
var protocolsMap = map[string]*api.Protocol{
|
||||||
fmt.Sprintf("%s/%s/%s", _protocol.Name, _protocol.Version, _protocol.Abbreviation): &_protocol,
|
_protocol.ToString(): &_protocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
type dissecting string
|
type dissecting string
|
||||||
@@ -70,7 +72,7 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string,
|
|||||||
elapsedTime = 0
|
elapsedTime = 0
|
||||||
}
|
}
|
||||||
return &api.Entry{
|
return &api.Entry{
|
||||||
ProtocolId: fmt.Sprintf("%s/%s/%s", _protocol.Name, _protocol.Version, _protocol.Abbreviation),
|
Protocol: _protocol.ProtocolSummary,
|
||||||
Capture: item.Capture,
|
Capture: item.Capture,
|
||||||
Source: &api.TCP{
|
Source: &api.TCP{
|
||||||
Name: resolvedSource,
|
Name: resolvedSource,
|
||||||
@@ -195,7 +197,7 @@ func (d dissecting) Summarize(entry *api.Entry) *api.BaseEntry {
|
|||||||
|
|
||||||
return &api.BaseEntry{
|
return &api.BaseEntry{
|
||||||
Id: entry.Id,
|
Id: entry.Id,
|
||||||
Protocol: *protocolsMap[entry.ProtocolId],
|
Protocol: *protocolsMap[entry.Protocol.ToString()],
|
||||||
Capture: entry.Capture,
|
Capture: entry.Capture,
|
||||||
Summary: summary,
|
Summary: summary,
|
||||||
SummaryQuery: summaryQuery,
|
SummaryQuery: summaryQuery,
|
||||||
@@ -250,7 +252,7 @@ func (d dissecting) Represent(request map[string]interface{}, response map[strin
|
|||||||
|
|
||||||
func (d dissecting) Macros() map[string]string {
|
func (d dissecting) Macros() map[string]string {
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
`kafka`: fmt.Sprintf(`protocol == "%s/%s/%s"`, _protocol.Name, _protocol.Version, _protocol.Abbreviation),
|
`kafka`: fmt.Sprintf(`protocol.name == "%s"`, _protocol.Name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func TestRegister(t *testing.T) {
|
|||||||
|
|
||||||
func TestMacros(t *testing.T) {
|
func TestMacros(t *testing.T) {
|
||||||
expectedMacros := map[string]string{
|
expectedMacros := map[string]string{
|
||||||
"kafka": `protocol == "kafka/12/KAFKA"`,
|
"kafka": `protocol.name == "kafka"`,
|
||||||
}
|
}
|
||||||
dissector := NewDissector()
|
dissector := NewDissector()
|
||||||
macros := dissector.Macros()
|
macros := dissector.Macros()
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect14/redis/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect15/redis/\* expect
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var protocol = api.Protocol{
|
var protocol = api.Protocol{
|
||||||
|
ProtocolSummary: api.ProtocolSummary{
|
||||||
Name: "redis",
|
Name: "redis",
|
||||||
LongName: "Redis Serialization Protocol",
|
|
||||||
Abbreviation: "REDIS",
|
|
||||||
Macro: "redis",
|
|
||||||
Version: "3.x",
|
Version: "3.x",
|
||||||
|
Abbreviation: "REDIS",
|
||||||
|
},
|
||||||
|
LongName: "Redis Serialization Protocol",
|
||||||
|
Macro: "redis",
|
||||||
BackgroundColor: "#a41e11",
|
BackgroundColor: "#a41e11",
|
||||||
ForegroundColor: "#ffffff",
|
ForegroundColor: "#ffffff",
|
||||||
FontSize: 11,
|
FontSize: 11,
|
||||||
@@ -25,7 +27,7 @@ var protocol = api.Protocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var protocolsMap = map[string]*api.Protocol{
|
var protocolsMap = map[string]*api.Protocol{
|
||||||
fmt.Sprintf("%s/%s/%s", protocol.Name, protocol.Version, protocol.Abbreviation): &protocol,
|
protocol.ToString(): &protocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
type dissecting string
|
type dissecting string
|
||||||
@@ -78,7 +80,7 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string,
|
|||||||
elapsedTime = 0
|
elapsedTime = 0
|
||||||
}
|
}
|
||||||
return &api.Entry{
|
return &api.Entry{
|
||||||
ProtocolId: fmt.Sprintf("%s/%s/%s", protocol.Name, protocol.Version, protocol.Abbreviation),
|
Protocol: protocol.ProtocolSummary,
|
||||||
Capture: item.Capture,
|
Capture: item.Capture,
|
||||||
Source: &api.TCP{
|
Source: &api.TCP{
|
||||||
Name: resolvedSource,
|
Name: resolvedSource,
|
||||||
@@ -123,7 +125,7 @@ func (d dissecting) Summarize(entry *api.Entry) *api.BaseEntry {
|
|||||||
|
|
||||||
return &api.BaseEntry{
|
return &api.BaseEntry{
|
||||||
Id: entry.Id,
|
Id: entry.Id,
|
||||||
Protocol: *protocolsMap[entry.ProtocolId],
|
Protocol: *protocolsMap[entry.Protocol.ToString()],
|
||||||
Capture: entry.Capture,
|
Capture: entry.Capture,
|
||||||
Summary: summary,
|
Summary: summary,
|
||||||
SummaryQuery: summaryQuery,
|
SummaryQuery: summaryQuery,
|
||||||
@@ -151,7 +153,7 @@ func (d dissecting) Represent(request map[string]interface{}, response map[strin
|
|||||||
|
|
||||||
func (d dissecting) Macros() map[string]string {
|
func (d dissecting) Macros() map[string]string {
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
`redis`: fmt.Sprintf(`protocol == "%s/%s/%s"`, protocol.Name, protocol.Version, protocol.Abbreviation),
|
`redis`: fmt.Sprintf(`protocol.name == "%s"`, protocol.Name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func TestRegister(t *testing.T) {
|
|||||||
|
|
||||||
func TestMacros(t *testing.T) {
|
func TestMacros(t *testing.T) {
|
||||||
expectedMacros := map[string]string{
|
expectedMacros := map[string]string{
|
||||||
"redis": `protocol == "redis/3.x/REDIS"`,
|
"redis": `protocol.name == "redis"`,
|
||||||
}
|
}
|
||||||
dissector := NewDissector()
|
dissector := NewDissector()
|
||||||
macros := dissector.Macros()
|
macros := dissector.Macros()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ReactComponent as ReplayIcon } from './replay.svg';
|
|||||||
import styles from './EntryViewer.module.sass';
|
import styles from './EntryViewer.module.sass';
|
||||||
import { Tabs } from "../../UI";
|
import { Tabs } from "../../UI";
|
||||||
import replayRequestModalOpenAtom from "../../../recoil/replayRequestModalOpen";
|
import replayRequestModalOpenAtom from "../../../recoil/replayRequestModalOpen";
|
||||||
|
import entryDetailedConfigAtom, { EntryDetailedConfig } from "../../../recoil/entryDetailedConfig";
|
||||||
|
|
||||||
const enabledProtocolsForReplay = ["http"]
|
const enabledProtocolsForReplay = ["http"]
|
||||||
|
|
||||||
@@ -16,10 +17,11 @@ export enum TabsEnum {
|
|||||||
|
|
||||||
export const AutoRepresentation: React.FC<any> = ({ representation, color, openedTab = TabsEnum.Request, isDisplayReplay = false }) => {
|
export const AutoRepresentation: React.FC<any> = ({ representation, color, openedTab = TabsEnum.Request, isDisplayReplay = false }) => {
|
||||||
const entryData = useRecoilValue(entryDataAtom)
|
const entryData = useRecoilValue(entryDataAtom)
|
||||||
|
const { isReplayEnabled } = useRecoilValue<EntryDetailedConfig>(entryDetailedConfigAtom)
|
||||||
const setIsOpenRequestModal = useSetRecoilState(replayRequestModalOpenAtom)
|
const setIsOpenRequestModal = useSetRecoilState(replayRequestModalOpenAtom)
|
||||||
const isReplayDisplayed = useCallback(() => {
|
const isReplayDisplayed = useCallback(() => {
|
||||||
return enabledProtocolsForReplay.find(x => x === entryData.protocol.name) && isDisplayReplay
|
return enabledProtocolsForReplay.find(x => x === entryData.protocol.name) && isDisplayReplay && isReplayEnabled
|
||||||
}, [entryData.protocol.name, isDisplayReplay])
|
}, [entryData.protocol.name, isDisplayReplay, isReplayEnabled])
|
||||||
|
|
||||||
const { request, response } = JSON.parse(representation);
|
const { request, response } = JSON.parse(representation);
|
||||||
|
|
||||||
@@ -31,12 +33,10 @@ export const AutoRepresentation: React.FC<any> = ({ representation, color, opene
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
arr.push(
|
arr.push({
|
||||||
{
|
|
||||||
tab: 'Response',
|
tab: 'Response',
|
||||||
badge: null
|
badge: null
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return arr
|
return arr
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import leftOffTopAtom from "../../recoil/leftOffTop";
|
|||||||
import { DEFAULT_LEFTOFF, DEFAULT_FETCH, DEFAULT_FETCH_TIMEOUT_MS } from '../../hooks/useWS';
|
import { DEFAULT_LEFTOFF, DEFAULT_FETCH, DEFAULT_FETCH_TIMEOUT_MS } from '../../hooks/useWS';
|
||||||
import ReplayRequestModalContainer from "../modals/ReplayRequestModal/ReplayRequestModal";
|
import ReplayRequestModalContainer from "../modals/ReplayRequestModal/ReplayRequestModal";
|
||||||
import replayRequestModalOpenAtom from "../../recoil/replayRequestModalOpen";
|
import replayRequestModalOpenAtom from "../../recoil/replayRequestModalOpen";
|
||||||
|
import entryDetailedConfigAtom, { EntryDetailedConfig } from "../../recoil/entryDetailedConfig";
|
||||||
|
|
||||||
const useLayoutStyles = makeStyles(() => ({
|
const useLayoutStyles = makeStyles(() => ({
|
||||||
details: {
|
details: {
|
||||||
@@ -51,18 +52,22 @@ interface TrafficViewerProps {
|
|||||||
webSocketUrl: string,
|
webSocketUrl: string,
|
||||||
shouldCloseWebSocket: boolean,
|
shouldCloseWebSocket: boolean,
|
||||||
setShouldCloseWebSocket: (flag: boolean) => void,
|
setShouldCloseWebSocket: (flag: boolean) => void,
|
||||||
isDemoBannerView: boolean
|
isDemoBannerView: boolean,
|
||||||
|
entryDetailedConfig: EntryDetailedConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TrafficViewer: React.FC<TrafficViewerProps> = ({
|
export const TrafficViewer: React.FC<TrafficViewerProps> = ({
|
||||||
trafficViewerApiProp,
|
trafficViewerApiProp,
|
||||||
actionButtons, isShowStatusBar, webSocketUrl,
|
webSocketUrl,
|
||||||
shouldCloseWebSocket, setShouldCloseWebSocket, isDemoBannerView
|
actionButtons,
|
||||||
}) => {
|
isShowStatusBar, isDemoBannerView,
|
||||||
|
shouldCloseWebSocket, setShouldCloseWebSocket,
|
||||||
|
entryDetailedConfig }) => {
|
||||||
|
|
||||||
const classes = useLayoutStyles();
|
const classes = useLayoutStyles();
|
||||||
const setEntries = useSetRecoilState(entriesAtom);
|
const setEntries = useSetRecoilState(entriesAtom);
|
||||||
const setFocusedEntryId = useSetRecoilState(focusedEntryIdAtom);
|
const setFocusedEntryId = useSetRecoilState(focusedEntryIdAtom);
|
||||||
|
const setEntryDetailedConfigAtom = useSetRecoilState(entryDetailedConfigAtom)
|
||||||
const query = useRecoilValue(queryAtom);
|
const query = useRecoilValue(queryAtom);
|
||||||
const setTrafficViewerApiState = useSetRecoilState(trafficViewerApiAtom as RecoilState<TrafficViewerApi>)
|
const setTrafficViewerApiState = useSetRecoilState(trafficViewerApiAtom as RecoilState<TrafficViewerApi>)
|
||||||
const [tappingStatus, setTappingStatus] = useRecoilState(tappingStatusAtom);
|
const [tappingStatus, setTappingStatus] = useRecoilState(tappingStatusAtom);
|
||||||
@@ -183,6 +188,10 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setEntryDetailedConfigAtom(entryDetailedConfig)
|
||||||
|
}, [entryDetailedConfig, setEntryDetailedConfigAtom])
|
||||||
|
|
||||||
const getConnectionIndicator = () => {
|
const getConnectionIndicator = () => {
|
||||||
switch (wsReadyState) {
|
switch (wsReadyState) {
|
||||||
case WebSocket.OPEN:
|
case WebSocket.OPEN:
|
||||||
@@ -258,7 +267,7 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.details} id="rightSideContainer">
|
<div className={classes.details} id="rightSideContainer">
|
||||||
<EntryDetailed/>
|
<EntryDetailed />
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
</div>
|
</div>
|
||||||
@@ -266,15 +275,9 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const MemorizedTrafficViewer = React.memo(TrafficViewer)
|
const MemorizedTrafficViewer = React.memo(TrafficViewer)
|
||||||
const TrafficViewerContainer: React.FC<TrafficViewerProps> = ({
|
const TrafficViewerContainer: React.FC<TrafficViewerProps> = (props) => {
|
||||||
trafficViewerApiProp,
|
|
||||||
actionButtons, isShowStatusBar = true,
|
|
||||||
webSocketUrl, shouldCloseWebSocket, setShouldCloseWebSocket, isDemoBannerView
|
|
||||||
}) => {
|
|
||||||
return <RecoilRoot>
|
return <RecoilRoot>
|
||||||
<MemorizedTrafficViewer actionButtons={actionButtons} isShowStatusBar={isShowStatusBar} webSocketUrl={webSocketUrl}
|
<MemorizedTrafficViewer {...props} />
|
||||||
shouldCloseWebSocket={shouldCloseWebSocket} setShouldCloseWebSocket={setShouldCloseWebSocket} trafficViewerApiProp={trafficViewerApiProp}
|
|
||||||
isDemoBannerView={isDemoBannerView}/>
|
|
||||||
<ToastContainer enableMultiContainer containerId={TOAST_CONTAINER_ID}
|
<ToastContainer enableMultiContainer containerId={TOAST_CONTAINER_ID}
|
||||||
position="bottom-right"
|
position="bottom-right"
|
||||||
autoClose={5000}
|
autoClose={5000}
|
||||||
@@ -284,7 +287,7 @@ const TrafficViewerContainer: React.FC<TrafficViewerProps> = ({
|
|||||||
rtl={false}
|
rtl={false}
|
||||||
pauseOnFocusLoss
|
pauseOnFocusLoss
|
||||||
draggable
|
draggable
|
||||||
pauseOnHover/>
|
pauseOnHover />
|
||||||
<ReplayRequestModalContainer />
|
<ReplayRequestModalContainer />
|
||||||
</RecoilRoot>
|
</RecoilRoot>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ $modalMargin-from-edge : 35px
|
|||||||
width: -moz-available
|
width: -moz-available
|
||||||
width: -webkit-fill-available
|
width: -webkit-fill-available
|
||||||
width: fill-available
|
width: fill-available
|
||||||
|
width: strech
|
||||||
max-width: 200px
|
max-width: 200px
|
||||||
box-shadow: 0px 1px 5px #979797
|
box-shadow: 0px 1px 5px #979797
|
||||||
margin-left: 10px
|
margin-left: 10px
|
||||||
|
|||||||
@@ -2,3 +2,7 @@
|
|||||||
width: 100%
|
width: 100%
|
||||||
display: flex
|
display: flex
|
||||||
justify-content: center
|
justify-content: center
|
||||||
|
|
||||||
|
.axisText
|
||||||
|
font-size: 12px
|
||||||
|
opacity: 0.9
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import styles from "./TimelineBarChart.module.sass";
|
import styles from "./TimelineBarChart.module.sass";
|
||||||
import { ALL_PROTOCOLS, StatsMode } from "../TrafficStatsModal"
|
|
||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import {
|
import {
|
||||||
BarChart,
|
BarChart,
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
} from "recharts";
|
} from "recharts";
|
||||||
import { Utils } from "../../../../helpers/Utils";
|
import { Utils } from "../../../../helpers/Utils";
|
||||||
|
import { ALL_PROTOCOLS, StatsMode } from "../consts";
|
||||||
|
|
||||||
interface TimelineBarChartProps {
|
interface TimelineBarChartProps {
|
||||||
timeLineBarChartMode: string;
|
timeLineBarChartMode: string;
|
||||||
@@ -28,7 +28,7 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
|
|||||||
const prtcNames = [];
|
const prtcNames = [];
|
||||||
data.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1).forEach(protocolObj => {
|
data.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1).forEach(protocolObj => {
|
||||||
let newProtocolObj: { [k: string]: any } = {};
|
let newProtocolObj: { [k: string]: any } = {};
|
||||||
newProtocolObj.timestamp = Utils.getHoursAndMinutes(protocolObj.timestamp);
|
newProtocolObj.timestamp = Utils.formatDate(protocolObj.timestamp);
|
||||||
protocolObj.protocols.forEach(protocol => {
|
protocolObj.protocols.forEach(protocol => {
|
||||||
newProtocolObj[`${protocol.name}`] = protocol[StatsMode[timeLineBarChartMode]];
|
newProtocolObj[`${protocol.name}`] = protocol[StatsMode[timeLineBarChartMode]];
|
||||||
prtcNames.push({ name: protocol.name, color: protocol.color });
|
prtcNames.push({ name: protocol.name, color: protocol.color });
|
||||||
@@ -50,10 +50,10 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
|
|||||||
const protocolsMethods = [];
|
const protocolsMethods = [];
|
||||||
data.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1).forEach(protocolObj => {
|
data.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1).forEach(protocolObj => {
|
||||||
let newMethodObj: { [k: string]: any } = {};
|
let newMethodObj: { [k: string]: any } = {};
|
||||||
newMethodObj.timestamp = Utils.getHoursAndMinutes(protocolObj.timestamp);
|
newMethodObj.timestamp = Utils.formatDate(protocolObj.timestamp);
|
||||||
protocolObj.protocols.find(protocol => protocol.name === selectedProtocol)?.methods.forEach(method => {
|
protocolObj.protocols.find(protocol => protocol.name === selectedProtocol)?.methods.forEach(method => {
|
||||||
newMethodObj[`${method.name}`] = method[StatsMode[timeLineBarChartMode]]
|
newMethodObj[`${method.name}`] = method[StatsMode[timeLineBarChartMode]]
|
||||||
protocolsMethodsNamesAndColors.push({name: method.name, color: method.color});
|
protocolsMethodsNamesAndColors.push({ name: method.name, color: method.color });
|
||||||
})
|
})
|
||||||
protocolsMethods.push(newMethodObj);
|
protocolsMethods.push(newMethodObj);
|
||||||
})
|
})
|
||||||
@@ -68,17 +68,13 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
|
|||||||
|
|
||||||
const renderTick = (tickProps) => {
|
const renderTick = (tickProps) => {
|
||||||
const { x, y, payload } = tickProps;
|
const { x, y, payload } = tickProps;
|
||||||
const { index, value } = payload;
|
const { offset, value } = payload;
|
||||||
|
const pathX = Math.floor(x - offset) + 0.5;
|
||||||
|
|
||||||
if (protocolStats.length > 5) {
|
return <React.Fragment>
|
||||||
if (index % 3 === 0) {
|
<text x={pathX} y={y + 10} textAnchor="middle" className={styles.axisText}>{`${value}`}</text>;
|
||||||
return <text x={x} y={y + 10} textAnchor="end">{`${value}`}</text>;
|
<path d={`M${pathX},${y - 4}v${-10}`} stroke="red" />;
|
||||||
}
|
</React.Fragment>
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return <text x={x} y={y + 10} textAnchor="end">{`${value}`}</text>;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -95,8 +91,8 @@ export const TimelineBarChart: React.FC<TimelineBarChartProps> = ({ timeLineBarC
|
|||||||
bottom: 5
|
bottom: 5
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<XAxis dataKey="timestamp" tick={renderTick} tickLine={false} interval="preserveStart" />
|
<XAxis dataKey="timestamp" tickLine={false} tick={renderTick} interval="preserveStart"/>
|
||||||
<YAxis tickFormatter={(value) => timeLineBarChartMode === "VOLUME" ? Utils.humanFileSize(value) : value} interval="preserveEnd"/>
|
<YAxis tickFormatter={(value) => timeLineBarChartMode === "VOLUME" ? Utils.humanFileSize(value) : value} interval="preserveEnd" />
|
||||||
<Tooltip formatter={(value) => timeLineBarChartMode === "VOLUME" ? Utils.humanFileSize(value) : value + " Requests"} />
|
<Tooltip formatter={(value) => timeLineBarChartMode === "VOLUME" ? Utils.humanFileSize(value) : value + " Requests"} />
|
||||||
{bars}
|
{bars}
|
||||||
</BarChart>}
|
</BarChart>}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import { Cell, Legend, Pie, PieChart, Tooltip } from "recharts";
|
import { Cell, Legend, Pie, PieChart, Tooltip } from "recharts";
|
||||||
import { Utils } from "../../../../helpers/Utils";
|
import { Utils } from "../../../../helpers/Utils";
|
||||||
import { ALL_PROTOCOLS, StatsMode as PieChartMode } from "../TrafficStatsModal"
|
import { ALL_PROTOCOLS ,StatsMode as PieChartMode } from "../consts"
|
||||||
|
|
||||||
const RADIAN = Math.PI / 180;
|
const RADIAN = Math.PI / 180;
|
||||||
const renderCustomizedLabel = ({
|
const renderCustomizedLabel = ({
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { TimelineBarChart } from "./TimelineBarChart/TimelineBarChart";
|
|||||||
import refreshIcon from "assets/refresh.svg";
|
import refreshIcon from "assets/refresh.svg";
|
||||||
import { useCommonStyles } from "../../../helpers/commonStyle";
|
import { useCommonStyles } from "../../../helpers/commonStyle";
|
||||||
import { LoadingWrapper } from "../../UI/withLoading/withLoading";
|
import { LoadingWrapper } from "../../UI/withLoading/withLoading";
|
||||||
|
import { ALL_PROTOCOLS, StatsMode } from "./consts";
|
||||||
|
|
||||||
const modalStyle = {
|
const modalStyle = {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
@@ -22,19 +23,12 @@ const modalStyle = {
|
|||||||
color: '#000',
|
color: '#000',
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum StatsMode {
|
|
||||||
REQUESTS = "entriesCount",
|
|
||||||
VOLUME = "volumeSizeBytes"
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TrafficStatsModalProps {
|
interface TrafficStatsModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
getTrafficStatsDataApi: () => Promise<any>
|
getTrafficStatsDataApi: () => Promise<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ALL_PROTOCOLS = "ALL";
|
|
||||||
|
|
||||||
export const TrafficStatsModal: React.FC<TrafficStatsModalProps> = ({ isOpen, onClose, getTrafficStatsDataApi }) => {
|
export const TrafficStatsModal: React.FC<TrafficStatsModalProps> = ({ isOpen, onClose, getTrafficStatsDataApi }) => {
|
||||||
|
|
||||||
const modes = Object.keys(StatsMode).filter(x => !(parseInt(x) >= 0));
|
const modes = Object.keys(StatsMode).filter(x => !(parseInt(x) >= 0));
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export const ALL_PROTOCOLS = "ALL";
|
||||||
|
export enum StatsMode {
|
||||||
|
REQUESTS = "entriesCount",
|
||||||
|
VOLUME = "volumeSizeBytes"
|
||||||
|
}
|
||||||
@@ -37,6 +37,20 @@ export class Utils {
|
|||||||
return hoursAndMinutes;
|
return hoursAndMinutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static formatDate = (date) => {
|
||||||
|
let d = new Date(date),
|
||||||
|
month = '' + (d.getMonth() + 1),
|
||||||
|
day = '' + d.getDate(),
|
||||||
|
year = d.getFullYear();
|
||||||
|
const hoursAndMinutes = Utils.getHoursAndMinutes(date);
|
||||||
|
if (month.length < 2)
|
||||||
|
month = '0' + month;
|
||||||
|
if (day.length < 2)
|
||||||
|
day = '0' + day;
|
||||||
|
const newDate = [year, month, day].join('-');
|
||||||
|
return [hoursAndMinutes, newDate].join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
static creatUniqueObjArrayByProp = (objArray, prop) => {
|
static creatUniqueObjArrayByProp = (objArray, prop) => {
|
||||||
const map = new Map(objArray.map((item) => [item[prop], item])).values()
|
const map = new Map(objArray.map((item) => [item[prop], item])).values()
|
||||||
return Array.from(map);
|
return Array.from(map);
|
||||||
|
|||||||
@@ -7,6 +7,5 @@ import { ServiceMapModal } from './components/modals/ServiceMapModal/ServiceMapM
|
|||||||
import { TrafficStatsModal } from './components/modals/TrafficStatsModal/TrafficStatsModal';
|
import { TrafficStatsModal } from './components/modals/TrafficStatsModal/TrafficStatsModal';
|
||||||
|
|
||||||
export { CodeEditorWrap as QueryForm } from './components/Filters/Filters';
|
export { CodeEditorWrap as QueryForm } from './components/Filters/Filters';
|
||||||
export { UI, StatusBar, OasModal, ServiceMapModal, TrafficStatsModal }
|
export { UI, StatusBar, OasModal, ServiceMapModal, TrafficStatsModal, TrafficViewer }
|
||||||
export { useWS, DEFAULT_LEFTOFF }
|
export { useWS, DEFAULT_LEFTOFF }
|
||||||
export default TrafficViewer;
|
|
||||||
|
|||||||
12
ui-common/src/recoil/entryDetailedConfig/atom.ts
Normal file
12
ui-common/src/recoil/entryDetailedConfig/atom.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { atom } from "recoil";
|
||||||
|
|
||||||
|
const entryDetailedConfigAtom = atom({
|
||||||
|
key: "entryDetailedConfigAtom",
|
||||||
|
default: null
|
||||||
|
});
|
||||||
|
|
||||||
|
export type EntryDetailedConfig = {
|
||||||
|
isReplayEnabled: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default entryDetailedConfigAtom;
|
||||||
3
ui-common/src/recoil/entryDetailedConfig/index.ts
Normal file
3
ui-common/src/recoil/entryDetailedConfig/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import atom from "./atom"
|
||||||
|
export type { EntryDetailedConfig } from "./atom"
|
||||||
|
export default atom
|
||||||
@@ -5,13 +5,14 @@ import debounce from 'lodash/debounce';
|
|||||||
import { useRecoilState } from "recoil";
|
import { useRecoilState } from "recoil";
|
||||||
import { useCommonStyles } from "../../../helpers/commonStyle"
|
import { useCommonStyles } from "../../../helpers/commonStyle"
|
||||||
import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen";
|
import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen";
|
||||||
import TrafficViewer from "@up9/mizu-common"
|
import { TrafficViewer } from "@up9/mizu-common"
|
||||||
import "@up9/mizu-common/dist/index.css"
|
import "@up9/mizu-common/dist/index.css"
|
||||||
import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom";
|
import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom";
|
||||||
import serviceMap from "../../assets/serviceMap.svg";
|
import serviceMap from "../../assets/serviceMap.svg";
|
||||||
import services from "../../assets/services.svg";
|
import services from "../../assets/services.svg";
|
||||||
import trafficStatsIcon from "../../assets/trafficStats.svg";
|
import trafficStatsIcon from "../../assets/trafficStats.svg";
|
||||||
import trafficStatsModalOpenAtom from "../../../recoil/trafficStatsModalOpen";
|
import trafficStatsModalOpenAtom from "../../../recoil/trafficStatsModalOpen";
|
||||||
|
import { REPLAY_ENABLED } from "../../../consts";
|
||||||
|
|
||||||
const api = Api.getInstance();
|
const api = Api.getInstance();
|
||||||
|
|
||||||
@@ -72,7 +73,9 @@ export const TrafficPage: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TrafficViewer webSocketUrl={MizuWebsocketURL} shouldCloseWebSocket={shouldCloseWebSocket} setShouldCloseWebSocket={setShouldCloseWebSocket}
|
<TrafficViewer webSocketUrl={MizuWebsocketURL} shouldCloseWebSocket={shouldCloseWebSocket} setShouldCloseWebSocket={setShouldCloseWebSocket}
|
||||||
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!(openOasModal || serviceMapModalOpen || trafficStatsModalOpen)} isDemoBannerView={false} />
|
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!(openOasModal || serviceMapModalOpen || trafficStatsModalOpen)} isDemoBannerView={false} entryDetailedConfig={{
|
||||||
|
isReplayEnabled: REPLAY_ENABLED
|
||||||
|
}} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
export const adminUsername = "admin";
|
export const adminUsername = "admin";
|
||||||
export const TOAST_CONTAINER_ID = "Community";
|
export const TOAST_CONTAINER_ID = "Community";
|
||||||
|
export const REPLAY_ENABLED = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user