kubeshark/tap/extensions/kafka/helpers.go

912 lines
24 KiB
Go

package kafka
import (
"encoding/json"
"fmt"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"reflect"
"sort"
"strconv"
"strings"
"github.com/fatih/camelcase"
"github.com/ohler55/ojg/jp"
"github.com/ohler55/ojg/oj"
"github.com/up9inc/mizu/tap/api"
)
type KafkaPayload struct {
Data interface{}
}
type KafkaPayloader interface {
MarshalJSON() ([]byte, error)
}
func (h KafkaPayload) MarshalJSON() ([]byte, error) {
return json.Marshal(h.Data)
}
type KafkaWrapper struct {
Method string `json:"method"`
Url string `json:"url"`
Details interface{} `json:"details"`
}
func representRequestHeader(data map[string]interface{}, rep []interface{}) []interface{} {
requestHeader, _ := json.Marshal([]api.TableData{
{
Name: "ApiKey",
Value: apiNames[int(data["apiKey"].(float64))],
Selector: `request.apiKey`,
},
{
Name: "ApiVersion",
Value: fmt.Sprintf("%d", int(data["apiVersion"].(float64))),
Selector: `request.apiVersion`,
},
{
Name: "Client ID",
Value: data["clientID"].(string),
Selector: `request.clientID`,
},
{
Name: "Correlation ID",
Value: fmt.Sprintf("%d", int(data["correlationID"].(float64))),
Selector: `request.correlationID`,
},
{
Name: "Size",
Value: fmt.Sprintf("%d", int(data["size"].(float64))),
Selector: `request.size`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Request Header",
Data: string(requestHeader),
})
return rep
}
func representResponseHeader(data map[string]interface{}, rep []interface{}) []interface{} {
requestHeader, _ := json.Marshal([]api.TableData{
{
Name: "Correlation ID",
Value: fmt.Sprintf("%d", int(data["correlationID"].(float64))),
Selector: `response.correlationID`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Response Header",
Data: string(requestHeader),
})
return rep
}
func representMetadataRequest(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representRequestHeader(data, rep)
payload := data["payload"].(map[string]interface{})
topics := ""
allowAutoTopicCreation := ""
includeClusterAuthorizedOperations := ""
includeTopicAuthorizedOperations := ""
if payload["topics"] != nil {
x, _ := json.Marshal(payload["topics"].([]interface{}))
topics = string(x)
}
if payload["allowAutoTopicCreation"] != nil {
allowAutoTopicCreation = strconv.FormatBool(payload["allowAutoTopicCreation"].(bool))
}
if payload["includeClusterAuthorizedOperations"] != nil {
includeClusterAuthorizedOperations = strconv.FormatBool(payload["includeClusterAuthorizedOperations"].(bool))
}
if payload["includeTopicAuthorizedOperations"] != nil {
includeTopicAuthorizedOperations = strconv.FormatBool(payload["includeTopicAuthorizedOperations"].(bool))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Topics",
Value: topics,
Selector: `request.payload.topics`,
},
{
Name: "Allow Auto Topic Creation",
Value: allowAutoTopicCreation,
Selector: `request.payload.allowAutoTopicCreation`,
},
{
Name: "Include Cluster Authorized Operations",
Value: includeClusterAuthorizedOperations,
Selector: `request.payload.includeClusterAuthorizedOperations`,
},
{
Name: "Include Topic Authorized Operations",
Value: includeTopicAuthorizedOperations,
Selector: `request.payload.includeTopicAuthorizedOperations`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Payload",
Data: string(repPayload),
})
return rep
}
func representMetadataResponse(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representResponseHeader(data, rep)
payload := data["payload"].(map[string]interface{})
topics := ""
if payload["topics"] != nil {
_topics, _ := json.Marshal(payload["topics"].([]interface{}))
topics = string(_topics)
}
brokers := ""
if payload["brokers"] != nil {
_brokers, _ := json.Marshal(payload["brokers"].([]interface{}))
brokers = string(_brokers)
}
controllerID := ""
clusterID := ""
throttleTimeMs := ""
clusterAuthorizedOperations := ""
if payload["controllerID"] != nil {
controllerID = fmt.Sprintf("%d", int(payload["controllerID"].(float64)))
}
if payload["clusterID"] != nil {
clusterID = payload["clusterID"].(string)
}
if payload["throttleTimeMs"] != nil {
throttleTimeMs = fmt.Sprintf("%d", int(payload["throttleTimeMs"].(float64)))
}
if payload["clusterAuthorizedOperations"] != nil {
clusterAuthorizedOperations = fmt.Sprintf("%d", int(payload["clusterAuthorizedOperations"].(float64)))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Throttle Time (ms)",
Value: throttleTimeMs,
Selector: `response.payload.throttleTimeMs`,
},
{
Name: "Brokers",
Value: brokers,
Selector: `response.payload.brokers`,
},
{
Name: "Cluster ID",
Value: clusterID,
Selector: `response.payload.clusterID`,
},
{
Name: "Controller ID",
Value: controllerID,
Selector: `response.payload.controllerID`,
},
{
Name: "Topics",
Value: topics,
Selector: `response.payload.topics`,
},
{
Name: "Cluster Authorized Operations",
Value: clusterAuthorizedOperations,
Selector: `response.payload.clusterAuthorizedOperations`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Payload",
Data: string(repPayload),
})
return rep
}
func representApiVersionsRequest(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representRequestHeader(data, rep)
payload := data["payload"].(map[string]interface{})
clientSoftwareName := ""
clientSoftwareVersion := ""
if payload["clientSoftwareName"] != nil {
clientSoftwareName = payload["clientSoftwareName"].(string)
}
if payload["clientSoftwareVersion"] != nil {
clientSoftwareVersion = payload["clientSoftwareVersion"].(string)
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Client Software Name",
Value: clientSoftwareName,
Selector: `request.payload.clientSoftwareName`,
},
{
Name: "Client Software Version",
Value: clientSoftwareVersion,
Selector: `request.payload.clientSoftwareVersion`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Payload",
Data: string(repPayload),
})
return rep
}
func representApiVersionsResponse(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representResponseHeader(data, rep)
payload := data["payload"].(map[string]interface{})
apiKeys := ""
if payload["apiKeys"] != nil {
x, _ := json.Marshal(payload["apiKeys"].([]interface{}))
apiKeys = string(x)
}
throttleTimeMs := ""
if payload["throttleTimeMs"] != nil {
throttleTimeMs = fmt.Sprintf("%d", int(payload["throttleTimeMs"].(float64)))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Error Code",
Value: fmt.Sprintf("%d", int(payload["errorCode"].(float64))),
Selector: `response.payload.errorCode`,
},
{
Name: "ApiKeys",
Value: apiKeys,
Selector: `response.payload.apiKeys`,
},
{
Name: "Throttle Time (ms)",
Value: throttleTimeMs,
Selector: `response.payload.throttleTimeMs`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Payload",
Data: string(repPayload),
})
return rep
}
func representProduceRequest(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representRequestHeader(data, rep)
payload := data["payload"].(map[string]interface{})
topicData := payload["topicData"]
transactionalID := ""
if payload["transactionalID"] != nil {
transactionalID = payload["transactionalID"].(string)
}
repTransactionDetails, _ := json.Marshal([]api.TableData{
{
Name: "Transactional ID",
Value: transactionalID,
Selector: `request.payload.transactionalID`,
},
{
Name: "Required Acknowledgements",
Value: fmt.Sprintf("%d", int(payload["requiredAcks"].(float64))),
Selector: `request.payload.requiredAcks`,
},
{
Name: "Timeout",
Value: fmt.Sprintf("%d", int(payload["timeout"].(float64))),
Selector: `request.payload.timeout`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Transaction Details",
Data: string(repTransactionDetails),
})
if topicData != nil {
for _, _topic := range topicData.([]interface{}) {
topic := _topic.(map[string]interface{})
topicName := topic["topic"].(string)
partitions := topic["partitions"].(map[string]interface{})
partitionsJson, err := json.Marshal(partitions)
if err != nil {
return rep
}
repPartitions, _ := json.Marshal([]api.TableData{
{
Name: "Length",
Value: partitions["length"],
Selector: `request.payload.transactionalID`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Partitions (topic: %s)", topicName),
Data: string(repPartitions),
})
obj, err := oj.ParseString(string(partitionsJson))
if err != nil {
return rep
}
recordBatchPath, err := jp.ParseString(`partitionData.records.recordBatch`)
if err != nil {
return rep
}
recordBatchresults := recordBatchPath.Get(obj)
if len(recordBatchresults) > 0 {
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Record Batch (topic: %s)", topicName),
Data: representMapAsTable(recordBatchresults[0].(map[string]interface{}), `request.payload.topicData.partitions.partitionData.records.recordBatch`, []string{"record"}),
})
}
recordsPath, err := jp.ParseString(`partitionData.records.recordBatch.record`)
if err != nil {
return rep
}
recordsResults := recordsPath.Get(obj)
if len(recordsResults) > 0 {
if recordsResults[0] != nil {
records := recordsResults[0].([]interface{})
for i, _record := range records {
record := _record.(map[string]interface{})
value := record["value"]
delete(record, "value")
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Record [%d] Details (topic: %s)", i, topicName),
Data: representMapAsTable(record, fmt.Sprintf(`request.payload.topicData.partitions.partitionData.records.recordBatch.record[%d]`, i), []string{"value"}),
})
rep = append(rep, api.SectionData{
Type: api.BODY,
Title: fmt.Sprintf("Record [%d] Value", i),
Data: value.(string),
Selector: fmt.Sprintf(`request.payload.topicData.partitions.partitionData.records.recordBatch.record[%d].value`, i),
})
}
}
}
}
}
return rep
}
func representProduceResponse(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representResponseHeader(data, rep)
payload := data["payload"].(map[string]interface{})
responses := payload["responses"]
throttleTimeMs := ""
if payload["throttleTimeMs"] != nil {
throttleTimeMs = fmt.Sprintf("%d", int(payload["throttleTimeMs"].(float64)))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Throttle Time (ms)",
Value: throttleTimeMs,
Selector: `response.payload.throttleTimeMs`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Transaction Details",
Data: string(repPayload),
})
if responses != nil {
for i, _response := range responses.([]interface{}) {
response := _response.(map[string]interface{})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Response [%d]", i),
Data: representMapAsTable(response, fmt.Sprintf(`response.payload.responses[%d]`, i), []string{"partitionResponses"}),
})
for j, _partitionResponse := range response["partitionResponses"].([]interface{}) {
partitionResponse := _partitionResponse.(map[string]interface{})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Response [%d] Partition Response [%d]", i, j),
Data: representMapAsTable(partitionResponse, fmt.Sprintf(`response.payload.responses[%d].partitionResponses[%d]`, i, j), []string{}),
})
}
}
}
return rep
}
func representFetchRequest(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representRequestHeader(data, rep)
payload := data["payload"].(map[string]interface{})
topics := payload["topics"]
replicaId := ""
if payload["replicaId"] != nil {
replicaId = fmt.Sprintf("%d", int(payload["replicaId"].(float64)))
}
maxBytes := ""
if payload["maxBytes"] != nil {
maxBytes = fmt.Sprintf("%d", int(payload["maxBytes"].(float64)))
}
isolationLevel := ""
if payload["isolationLevel"] != nil {
isolationLevel = fmt.Sprintf("%d", int(payload["isolationLevel"].(float64)))
}
sessionId := ""
if payload["sessionId"] != nil {
sessionId = fmt.Sprintf("%d", int(payload["sessionId"].(float64)))
}
sessionEpoch := ""
if payload["sessionEpoch"] != nil {
sessionEpoch = fmt.Sprintf("%d", int(payload["sessionEpoch"].(float64)))
}
forgottenTopicsData := ""
if payload["forgottenTopicsData"] != nil {
x, _ := json.Marshal(payload["forgottenTopicsData"].(map[string]interface{}))
forgottenTopicsData = string(x)
}
rackId := ""
if payload["rackId"] != nil {
rackId = payload["rackId"].(string)
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Replica ID",
Value: replicaId,
Selector: `request.payload.replicaId`,
},
{
Name: "Maximum Wait (ms)",
Value: fmt.Sprintf("%d", int(payload["maxWaitMs"].(float64))),
Selector: `request.payload.maxWaitMs`,
},
{
Name: "Minimum Bytes",
Value: fmt.Sprintf("%d", int(payload["minBytes"].(float64))),
Selector: `request.payload.minBytes`,
},
{
Name: "Maximum Bytes",
Value: maxBytes,
Selector: `request.payload.maxBytes`,
},
{
Name: "Isolation Level",
Value: isolationLevel,
Selector: `request.payload.isolationLevel`,
},
{
Name: "Session ID",
Value: sessionId,
Selector: `request.payload.sessionId`,
},
{
Name: "Session Epoch",
Value: sessionEpoch,
Selector: `request.payload.sessionEpoch`,
},
{
Name: "Forgotten Topics Data",
Value: forgottenTopicsData,
Selector: `request.payload.forgottenTopicsData`,
},
{
Name: "Rack ID",
Value: rackId,
Selector: `request.payload.rackId`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Transaction Details",
Data: string(repPayload),
})
if topics != nil {
for i, _topic := range topics.([]interface{}) {
topic := _topic.(map[string]interface{})
topicName := topic["topic"].(string)
for j, _partition := range topic["partitions"].([]interface{}) {
partition := _partition.(map[string]interface{})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Partition [%d] (topic: %s)", j, topicName),
Data: representMapAsTable(partition, fmt.Sprintf(`request.payload.topics[%d].partitions[%d]`, i, j), []string{}),
})
}
}
}
return rep
}
func representFetchResponse(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representResponseHeader(data, rep)
payload := data["payload"].(map[string]interface{})
responses := payload["responses"]
throttleTimeMs := ""
if payload["throttleTimeMs"] != nil {
throttleTimeMs = fmt.Sprintf("%d", int(payload["throttleTimeMs"].(float64)))
}
errorCode := ""
if payload["errorCode"] != nil {
errorCode = fmt.Sprintf("%d", int(payload["errorCode"].(float64)))
}
sessionId := ""
if payload["sessionId"] != nil {
sessionId = fmt.Sprintf("%d", int(payload["sessionId"].(float64)))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Throttle Time (ms)",
Value: throttleTimeMs,
Selector: `response.payload.throttleTimeMs`,
},
{
Name: "Error Code",
Value: errorCode,
Selector: `response.payload.errorCode`,
},
{
Name: "Session ID",
Value: sessionId,
Selector: `response.payload.sessionId`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Transaction Details",
Data: string(repPayload),
})
if responses != nil {
for i, _response := range responses.([]interface{}) {
response := _response.(map[string]interface{})
topicName := response["topic"].(string)
for j, _partitionResponse := range response["partitionResponses"].([]interface{}) {
partitionResponse := _partitionResponse.(map[string]interface{})
recordSet := partitionResponse["recordSet"].(map[string]interface{})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Response [%d] Partition Response [%d] (topic: %s)", i, j, topicName),
Data: representMapAsTable(partitionResponse, fmt.Sprintf(`response.payload.responses[%d].partitionResponses[%d]`, i, j), []string{"recordSet"}),
})
recordBatch := recordSet["recordBatch"].(map[string]interface{})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Response [%d] Partition Response [%d] Record Batch (topic: %s)", i, j, topicName),
Data: representMapAsTable(recordBatch, fmt.Sprintf(`response.payload.responses[%d].partitionResponses[%d].recordSet.recordBatch`, i, j), []string{"record"}),
})
if recordBatch["record"] != nil {
for k, _record := range recordBatch["record"].([]interface{}) {
record := _record.(map[string]interface{})
value := record["value"]
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Response [%d] Partition Response [%d] Record [%d] (topic: %s)", i, j, k, topicName),
Data: representMapAsTable(record, fmt.Sprintf(`response.payload.responses[%d].partitionResponses[%d].recordSet.recordBatch.record[%d]`, i, j, k), []string{"value"}),
})
rep = append(rep, api.SectionData{
Type: api.BODY,
Title: fmt.Sprintf("Response [%d] Partition Response [%d] Record [%d] Value (topic: %s)", i, j, k, topicName),
Data: value.(string),
Selector: fmt.Sprintf(`response.payload.responses[%d].partitionResponses[%d].recordSet.recordBatch.record[%d].value`, i, j, k),
})
}
}
}
}
}
return rep
}
func representListOffsetsRequest(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representRequestHeader(data, rep)
payload := data["payload"].(map[string]interface{})
topics := ""
if payload["topics"] != nil {
_topics, _ := json.Marshal(payload["topics"].([]interface{}))
topics = string(_topics)
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Replica ID",
Value: fmt.Sprintf("%d", int(payload["replicaId"].(float64))),
Selector: `request.payload.replicaId`,
},
{
Name: "Topics",
Value: topics,
Selector: `request.payload.topics`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Payload",
Data: string(repPayload),
})
return rep
}
func representListOffsetsResponse(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representResponseHeader(data, rep)
payload := data["payload"].(map[string]interface{})
topics, _ := json.Marshal(payload["topics"].([]interface{}))
throttleTimeMs := ""
if payload["throttleTimeMs"] != nil {
throttleTimeMs = fmt.Sprintf("%d", int(payload["throttleTimeMs"].(float64)))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Throttle Time (ms)",
Value: throttleTimeMs,
Selector: `response.payload.throttleTimeMs`,
},
{
Name: "Topics",
Value: string(topics),
Selector: `response.payload.topics`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Payload",
Data: string(repPayload),
})
return rep
}
func representCreateTopicsRequest(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representRequestHeader(data, rep)
payload := data["payload"].(map[string]interface{})
validateOnly := ""
if payload["validateOnly"] != nil {
validateOnly = strconv.FormatBool(payload["validateOnly"].(bool))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Timeout (ms)",
Value: fmt.Sprintf("%d", int(payload["timeoutMs"].(float64))),
Selector: `request.payload.timeoutMs`,
},
{
Name: "Validate Only",
Value: validateOnly,
Selector: `request.payload.validateOnly`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Transaction Details",
Data: string(repPayload),
})
if payload["topics"] == nil {
return rep
}
for i, _topic := range payload["topics"].([]interface{}) {
topic := _topic.(map[string]interface{})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Topic [%d]", i),
Data: representMapAsTable(topic, fmt.Sprintf(`request.payload.topics[%d]`, i), []string{}),
})
}
return rep
}
func representCreateTopicsResponse(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representResponseHeader(data, rep)
payload := data["payload"].(map[string]interface{})
throttleTimeMs := ""
if payload["throttleTimeMs"] != nil {
throttleTimeMs = fmt.Sprintf("%d", int(payload["throttleTimeMs"].(float64)))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Throttle Time (ms)",
Value: throttleTimeMs,
Selector: `response.payload.throttleTimeMs`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Transaction Details",
Data: string(repPayload),
})
if payload["topics"] == nil {
return rep
}
for i, _topic := range payload["topics"].([]interface{}) {
topic := _topic.(map[string]interface{})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: fmt.Sprintf("Topic [%d]", i),
Data: representMapAsTable(topic, fmt.Sprintf(`response.payload.topics[%d]`, i), []string{}),
})
}
return rep
}
func representDeleteTopicsRequest(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representRequestHeader(data, rep)
payload := data["payload"].(map[string]interface{})
topics := ""
if payload["topics"] != nil {
x, _ := json.Marshal(payload["topics"].([]interface{}))
topics = string(x)
}
topicNames := ""
if payload["topicNames"] != nil {
x, _ := json.Marshal(payload["topicNames"].([]interface{}))
topicNames = string(x)
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "TopicNames",
Value: string(topicNames),
Selector: `request.payload.topicNames`,
},
{
Name: "Topics",
Value: string(topics),
Selector: `request.payload.topics`,
},
{
Name: "Timeout (ms)",
Value: fmt.Sprintf("%d", int(payload["timeoutMs"].(float64))),
Selector: `request.payload.timeoutMs`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Payload",
Data: string(repPayload),
})
return rep
}
func representDeleteTopicsResponse(data map[string]interface{}) []interface{} {
rep := make([]interface{}, 0)
rep = representResponseHeader(data, rep)
payload := data["payload"].(map[string]interface{})
responses, _ := json.Marshal(payload["responses"].([]interface{}))
throttleTimeMs := ""
if payload["throttleTimeMs"] != nil {
throttleTimeMs = fmt.Sprintf("%d", int(payload["throttleTimeMs"].(float64)))
}
repPayload, _ := json.Marshal([]api.TableData{
{
Name: "Throttle Time (ms)",
Value: throttleTimeMs,
Selector: `response.payload.throttleTimeMs`,
},
{
Name: "Responses",
Value: string(responses),
Selector: `response.payload.responses`,
},
})
rep = append(rep, api.SectionData{
Type: api.TABLE,
Title: "Payload",
Data: string(repPayload),
})
return rep
}
func contains(s []string, str string) bool {
for _, v := range s {
if v == str {
return true
}
}
return false
}
func representMapAsTable(mapData map[string]interface{}, selectorPrefix string, ignoreKeys []string) (representation string) {
var table []api.TableData
for key, value := range mapData {
if contains(ignoreKeys, key) {
continue
}
switch reflect.ValueOf(value).Kind() {
case reflect.Map:
fallthrough
case reflect.Slice:
x, err := json.Marshal(value)
value = string(x)
if err != nil {
continue
}
}
selector := fmt.Sprintf("%s[\"%s\"]", selectorPrefix, key)
caser := cases.Title(language.Und, cases.NoLower)
table = append(table, api.TableData{
Name: strings.Join(camelcase.Split(caser.String(key)), " "),
Value: value,
Selector: selector,
})
}
sort.Slice(table, func(i, j int) bool {
return table[i].Name < table[j].Name
})
obj, _ := json.Marshal(table)
representation = string(obj)
return
}