Skip to content

Commit

Permalink
Docs cleanup and defined constants
Browse files Browse the repository at this point in the history
  • Loading branch information
akash4393 authored and daveshanley committed Feb 20, 2025
1 parent ca77a85 commit ba38352
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 19 deletions.
14 changes: 12 additions & 2 deletions cmd/handle_http_traffic.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,21 @@ import (
"github.com/pb33f/ranch/model"
"github.com/pb33f/wiretap/daemon"
"github.com/pb33f/wiretap/shared"
"github.com/pb33f/wiretap/staticMock"
staticMock "github.com/pb33f/wiretap/static-mock"
"github.com/pterm/pterm"
)

func handleHttpTraffic(wiretapConfig *shared.WiretapConfiguration, wtService *daemon.WiretapService, staticMockService *staticMock.StaticMockService) {
type HandleHttpTraffic struct {
WiretapConfig *shared.WiretapConfiguration
WiretapService *daemon.WiretapService
StaticMockService *staticMock.StaticMockService
}

func handleHttpTraffic(hht *HandleHttpTraffic) {
wiretapConfig := hht.WiretapConfig
wtService := hht.WiretapService
staticMockService := hht.StaticMockService

go func() {
handleTraffic := func(w http.ResponseWriter, r *http.Request) {
id, _ := uuid.NewUUID()
Expand Down
9 changes: 7 additions & 2 deletions cmd/run_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/pb33f/wiretap/report"
"github.com/pb33f/wiretap/shared"
"github.com/pb33f/wiretap/specs"
"github.com/pb33f/wiretap/staticMock"
staticMock "github.com/pb33f/wiretap/static-mock"
)

func runWiretapService(wiretapConfig *shared.WiretapConfiguration, doc libopenapi.Document) (server.PlatformServer, error) {
Expand Down Expand Up @@ -116,7 +116,12 @@ func runWiretapService(wiretapConfig *shared.WiretapConfiguration, doc libopenap
bootedMessage(wiretapConfig)

// boot the http handler
handleHttpTraffic(wiretapConfig, wtService, staticMockService)
hht := HandleHttpTraffic{
WiretapConfig: wiretapConfig,
WiretapService: wtService,
StaticMockService: staticMockService,
}
handleHttpTraffic(&hht)

// boot the monitor
serveMonitor(wiretapConfig)
Expand Down
14 changes: 7 additions & 7 deletions shared/json_utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/pterm/pterm"
)

// Function to check if json is a subset of superSet
// IsSubset method to check if json (interface{}) is a subset of a superSet
func IsSubset(json, superSet interface{}) bool {
// Check if json is an object
if obj, ok := json.(map[string]interface{}); ok {
Expand Down Expand Up @@ -45,7 +45,7 @@ func IsSubset(json, superSet interface{}) bool {
return json == superSet
}

// Helper function to check if objOne is a subset of objTwo
// isMapSubset Helper function to check if objOne (map[string]interface{}) is a subset of objTwo
func isMapSubset(objOne, objTwo map[string]interface{}) bool {
for key, valueObjOne := range objOne {
// Check if the key exists in objTwo
Expand All @@ -60,7 +60,7 @@ func isMapSubset(objOne, objTwo map[string]interface{}) bool {
return true
}

// Helper function to check if arrOne is a subset of arrTwo
// isSliceSubset Helper function to check if arrOne ([]interface{}) is a subset of arrTwo
func isSliceSubset(arrOne, arrTwo []interface{}) bool {
// Check if all elements of arrOne exist in arrTwo
for _, elementOne := range arrOne {
Expand All @@ -78,7 +78,7 @@ func isSliceSubset(arrOne, arrTwo []interface{}) bool {
return true
}

// Function to check if a string contains regex-specific characters
// isPotentialRegex Function to check if a string contains regex-specific characters
func isPotentialRegex(s string) bool {
// Regex characters to check for
regexChars := []string{".", "*", "+", "?", "^", "$", "[", "]", "(", ")", "|", "{", "}"}
Expand All @@ -92,7 +92,7 @@ func isPotentialRegex(s string) bool {
return false
}

// Helper function to compare strings. Since mock definitions support
// StringCompare Helper function to compare strings. Since mock definitions support
// regex, we need to check if the string is a regex and if so, compare it
func StringCompare(patternOrStr, str string) bool {
// Try to compile the pattern to check if it's a valid regex
Expand All @@ -115,7 +115,7 @@ func StringCompare(patternOrStr, str string) bool {
return patternOrStr == str
}

// Helper function to get the value based on a JSON path (dot notation or array index).
// getValueByPath Helper function to get the value based on a JSON path (dot notation or array index).
func getValueByPath(data interface{}, path string) (interface{}, error) {
// Split the path by dots and array indices (i.e., "[7]")
re := regexp.MustCompile(`\.`)
Expand Down Expand Up @@ -157,7 +157,7 @@ func getValueByPath(data interface{}, path string) (interface{}, error) {
return data, nil
}

// Function to replace template variables in JSON path format
// ReplaceTemplateVars Function to replace template variables in JSON path format
func ReplaceTemplateVars(jsonStr string, vars interface{}) (string, error) {
// Regular expression to match the ${var} format (full path)
re := regexp.MustCompile(`\$\{([a-zA-Z0-9._\[\]]+)\}`)
Expand Down
1 change: 1 addition & 0 deletions staticMock/README.md → static-mock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,4 @@ With this configuration, when Wiretap receives a `GET` request to `/test`, it wi

- If no mock definition is found that matches an incoming request, Wiretap will forward the request to the wiretap's request handler and let it return a response.
- The mock definitions can contain either a single object or an array of objects. In the case of an array, each object represents a separate mock definition.
g
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import (
"github.com/pb33f/wiretap/shared"
)

// getBodyFromMockDefinition returns the body from the matched static mock
func (sms *StaticMockService) getBodyFromMockDefinition(matchedMockDefinition StaticMockDefinition, request *http.Request) string {
bodyStr := matchedMockDefinition.Response.Body

// If the BodyJsonPath is defined then set the body to contents of the file
if matchedMockDefinition.Response.BodyJsonFilename != "" {
bodyJsonFilePath := sms.wiretapService.StaticMockDir + "/body-jsons/" + matchedMockDefinition.Response.BodyJsonFilename
bodyJsonFilePath := sms.wiretapService.StaticMockDir + MockBodyJsonsPath + matchedMockDefinition.Response.BodyJsonFilename

file, err := os.ReadFile(bodyJsonFilePath)
if err != nil {
Expand Down Expand Up @@ -68,6 +69,7 @@ func (sms *StaticMockService) getBodyFromMockDefinition(matchedMockDefinition St
return templateReplacedBodyStr
}

// getHeadersFromMockDefinition returns headers from the matched static mock
func (sms *StaticMockService) getHeadersFromMockDefinition(matchedMockDefinition StaticMockDefinition) http.Header {
header := http.Header{}
// wiretap needs to work from anywhere, so allow everything.
Expand All @@ -88,6 +90,7 @@ func (sms *StaticMockService) getHeadersFromMockDefinition(matchedMockDefinition
return header
}

// getStaticMockResponse returns response from the matched static mock
func (sms *StaticMockService) getStaticMockResponse(matchedMockDefinition StaticMockDefinition, request *http.Request) *http.Response {
body := sms.getBodyFromMockDefinition(matchedMockDefinition, request)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/pb33f/wiretap/shared"
)

// getBodyFromHttpRequest reads the body of the incoming request and returns it as an interface{}
func (sms *StaticMockService) getBodyFromHttpRequest(request *http.Request) interface{} {
bodyBytes, err := io.ReadAll(request.Body)
if err != nil {
Expand All @@ -30,13 +31,14 @@ func (sms *StaticMockService) getBodyFromHttpRequest(request *http.Request) inte

err = json.Unmarshal(bodyBytes, &bodyJsonObj)
if err != nil {
sms.logger.Error("Error decoding JSON of incoming request")
sms.logger.Error("Error decoding JSON of incoming request. JSON => \n%s", string(bodyBytes), err)
panic(err)
}

return bodyJsonObj
}

// compareJsonBody compares the JSON body of the incoming request with the mock definition
func (sms *StaticMockService) compareJsonBody(mock StaticMockDefinitionRequest, request *http.Request) bool {
// Mock body is JSON but incoming body is not JSON
if request.Header.Get("Content-Type") != "application/json" {
Expand All @@ -49,7 +51,7 @@ func (sms *StaticMockService) compareJsonBody(mock StaticMockDefinitionRequest,
return shared.IsSubset(mock.Body, incomingBody)
}

// Function to transform []string values to []interface{}(string)
// transStrArrToInterfaceArr transforms a string array to an interface array (helper method)
func (sms *StaticMockService) transStrArrToInterfaceArr(strArr []string) []interface{} {
strArrTransformedValues := make([]interface{}, 0)
for _, value := range strArr {
Expand All @@ -58,7 +60,7 @@ func (sms *StaticMockService) transStrArrToInterfaceArr(strArr []string) []inter
return strArrTransformedValues
}

// Function to compare headers
// compareHeaders compares the headers of the incoming request with the mock definition
func (sms *StaticMockService) compareHeaders(mockHeaders map[string]any, incoming *http.Request) bool {
found := true
// Check if all headers in mockHeaders are subset of incoming headers
Expand All @@ -74,6 +76,7 @@ func (sms *StaticMockService) compareHeaders(mockHeaders map[string]any, incomin
return found
}

// compareQueryParams compares the query parameters of the incoming request with the mock definition
func (sms *StaticMockService) compareQueryParams(mockQueryParams map[string]any, incomingQueries url.Values) bool {
found := true
// Check if all headers in mockHeaders are subset of incoming headers
Expand All @@ -89,6 +92,7 @@ func (sms *StaticMockService) compareQueryParams(mockQueryParams map[string]any,
return found
}

// compareBody compares the body of the incoming request with the mock definition
func (sms *StaticMockService) compareBody(mock StaticMockDefinitionRequest, incoming *http.Request) bool {
switch mb := mock.Body.(type) {
case string: // Case string body
Expand Down Expand Up @@ -116,7 +120,7 @@ func (sms *StaticMockService) compareBody(mock StaticMockDefinitionRequest, inco
return true
}

// Function to check if two requests are identical
// isRequestMatch checks if the incoming request matches a mock definition
func (sms *StaticMockService) isRequestMatch(mock StaticMockDefinitionRequest, incoming *http.Request) bool {
// Compare Host if defined
if mock.Host != "" && !shared.StringCompare(mock.Host, incoming.Host) {
Expand Down Expand Up @@ -158,6 +162,7 @@ func (sms *StaticMockService) isRequestMatch(mock StaticMockDefinitionRequest, i
return true
}

// checkStaticMockExists checks if a static mock definition exists for the incoming request.
func (sms *StaticMockService) checkStaticMockExists(request *http.Request) *StaticMockDefinition {
var matchedMockDefinition *StaticMockDefinition
// check for a static mock definition.
Expand All @@ -172,6 +177,7 @@ func (sms *StaticMockService) checkStaticMockExists(request *http.Request) *Stat
return matchedMockDefinition
}

// handleStaticMockRequest handles incoming requests and checks against static mock definitions.
func (sms *StaticMockService) handleStaticMockRequest(request *model.Request) {
defer func() {
if r := recover(); r != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
const (
StaticMockServiceChan = "static-mock-service"
IncomingHttpRequest = "incoming-http-request"
MockDefinitionsPath = "/mock-definitions"
MockBodyJsonsPath = "/body-jsons/"
)

type StaticMockDefinitionRequest struct {
Expand Down Expand Up @@ -57,6 +59,7 @@ func NewStaticMockService(wiretapService *daemon.WiretapService, logger *slog.Lo
}
}

// getDefinitionFromJson converts a JSON object to a StaticMockDefinition
func getDefinitionFromJson(mockInterface map[string]interface{}) (StaticMockDefinition, error) {
var mockDefinition StaticMockDefinition

Expand All @@ -73,9 +76,10 @@ func getDefinitionFromJson(mockInterface map[string]interface{}) (StaticMockDefi
return mockDefinition, nil
}

// loadStaticMockRequestsAndResponses loads the static mock definitions from the JSON files
func loadStaticMockRequestsAndResponses(wiretapService *daemon.WiretapService, logger *slog.Logger) []StaticMockDefinition {
var staticMockDefinitions []StaticMockDefinition
mocksPath := wiretapService.StaticMockDir + "/mock-definitions"
mocksPath := wiretapService.StaticMockDir + MockDefinitionsPath

files, err := os.ReadDir(mocksPath)
if err != nil {
Expand All @@ -97,7 +101,7 @@ func loadStaticMockRequestsAndResponses(wiretapService *daemon.WiretapService, l

err = json.Unmarshal(data, &mockDefinitions)
if err != nil {
logger.Error(err.Error())
logger.Error("Error parsing json file %s: %v\n", filePath, err)
continue
}

Expand Down Expand Up @@ -125,7 +129,7 @@ func loadStaticMockRequestsAndResponses(wiretapService *daemon.WiretapService, l

default:
// If it's neither an object nor an array
logger.Error("JSON not in the right format.")
logger.Error("JSON not in the right format. \nFile => %s\n JSON => \n%s", file.Name(), string(data))
}
}
}
Expand Down

0 comments on commit ba38352

Please sign in to comment.