From 42f2c245f7b94dd528275f29fef92d8bb51401d4 Mon Sep 17 00:00:00 2001 From: Andrey Pokhilko Date: Fri, 25 Feb 2022 20:48:03 +0300 Subject: [PATCH] Tracks historical IDs --- agent/pkg/oas/merger.go | 119 ++++++++++++++++++++++++++++++++++++ agent/pkg/oas/specgen.go | 1 + agent/pkg/oas/utils.go | 79 ------------------------ agent/pkg/oas/utils_test.go | 6 +- 4 files changed, 124 insertions(+), 81 deletions(-) create mode 100644 agent/pkg/oas/merger.go diff --git a/agent/pkg/oas/merger.go b/agent/pkg/oas/merger.go new file mode 100644 index 000000000..05b1d925e --- /dev/null +++ b/agent/pkg/oas/merger.go @@ -0,0 +1,119 @@ +package oas + +import ( + "github.com/chanced/openapi" + "github.com/up9inc/mizu/shared/logger" +) + +func mergePathObj(po *openapi.PathObj, other *openapi.PathObj) { + // merge parameters + mergeParamLists(&po.Parameters, &other.Parameters) + + // merge ops + mergeOps(&po.Get, &other.Get) + mergeOps(&po.Put, &other.Put) + mergeOps(&po.Options, &other.Options) + mergeOps(&po.Patch, &other.Patch) + mergeOps(&po.Delete, &other.Delete) + mergeOps(&po.Head, &other.Head) + mergeOps(&po.Trace, &other.Trace) + mergeOps(&po.Post, &other.Post) +} + +func mergeParamLists(params **openapi.ParameterList, other **openapi.ParameterList) { + if *other == nil { + return + } + + if *params == nil { + *params = new(openapi.ParameterList) + } + +outer: + for _, o := range **other { + oParam, err := o.ResolveParameter(paramResolver) + if err != nil { + logger.Log.Warningf("Failed to resolve reference: %s", err) + continue + } + + for _, p := range **params { + param, err := p.ResolveParameter(paramResolver) + if err != nil { + logger.Log.Warningf("Failed to resolve reference: %s", err) + continue + } + + if param.In == oParam.In && param.Name == oParam.Name { + // TODO: merge examples? transfer schema pattern? + continue outer + } + } + + **params = append(**params, oParam) + } +} + +func mergeOps(op **openapi.Operation, other **openapi.Operation) { + if *other == nil { + return + } + + if *op == nil { + *op = *other + } else { + // merge parameters + mergeParamLists(&(*op).Parameters, &(*other).Parameters) + + // merge responses + mergeOpResponses(&(*op).Responses, &(*other).Responses) + + // merge request body + mergeOpReqBodies(&(*op).RequestBody, &(*other).RequestBody) + + // historical OpIDs + appendHistoricalIds(op, other) + + // merge kpis + } +} + +func loadHistoricalIds(op *openapi.Operation) []string { + res := make([]string, 0) + if _, ok := op.Extensions.Extension(HistoricalIDs); ok { + err := op.Extensions.DecodeExtension(HistoricalIDs, &res) + if err != nil { + logger.Log.Warningf("Failed to decode extension %s: %s", HistoricalIDs, err) + } + } + return res +} + +func appendHistoricalIds(op **openapi.Operation, other **openapi.Operation) { + mIDs := loadHistoricalIds(*op) + oIDs := loadHistoricalIds(*other) + mIDs = append(mIDs, oIDs...) + mIDs = append(mIDs, (*other).OperationID) + + if (*op).Extensions == nil { + (*op).Extensions = make(openapi.Extensions) + } + + if len(mIDs) > 1 { + logger.Log.Debugf("") + } + + err := (*op).Extensions.SetExtension(HistoricalIDs, mIDs) + if err != nil { + logger.Log.Warningf("Failed to set extension %s: %s", HistoricalIDs, err) + return + } +} + +func mergeOpReqBodies(r *openapi.RequestBody, r2 *openapi.RequestBody) { + +} + +func mergeOpResponses(r *openapi.Responses, o *openapi.Responses) { + +} diff --git a/agent/pkg/oas/specgen.go b/agent/pkg/oas/specgen.go index 60f9cf75f..90e057307 100644 --- a/agent/pkg/oas/specgen.go +++ b/agent/pkg/oas/specgen.go @@ -27,6 +27,7 @@ const LastSeenTS = "x-last-seen-ts" const CountersTotal = "x-counters-total" const CountersPerSource = "x-counters-per-source" const SampleId = "x-sample-entry" +const HistoricalIDs = "x-historical-ids" type reqResp struct { // hello, generics in Go Req *har.Request diff --git a/agent/pkg/oas/utils.go b/agent/pkg/oas/utils.go index 4205c29ef..59fb0849b 100644 --- a/agent/pkg/oas/utils.go +++ b/agent/pkg/oas/utils.go @@ -474,82 +474,3 @@ func intersectSliceWithMap(required []string, names map[string]struct{}) []strin } return required } - -func mergePathObj(po *openapi.PathObj, other *openapi.PathObj) { - // merge parameters - mergeParamLists(&po.Parameters, &other.Parameters) - - // merge ops - mergeOps(&po.Get, &other.Get) - mergeOps(&po.Put, &other.Put) - mergeOps(&po.Options, &other.Options) - mergeOps(&po.Patch, &other.Patch) - mergeOps(&po.Delete, &other.Delete) - mergeOps(&po.Head, &other.Head) - mergeOps(&po.Trace, &other.Trace) - mergeOps(&po.Post, &other.Post) -} - -func mergeParamLists(params **openapi.ParameterList, other **openapi.ParameterList) { - if *other == nil { - return - } - - if *params == nil { - *params = new(openapi.ParameterList) - } - -outer: - for _, o := range **other { - oParam, err := o.ResolveParameter(paramResolver) - if err != nil { - logger.Log.Warningf("Failed to resolve reference: %s", err) - continue - } - - for _, p := range **params { - param, err := p.ResolveParameter(paramResolver) - if err != nil { - logger.Log.Warningf("Failed to resolve reference: %s", err) - continue - } - - if param.In == oParam.In && param.Name == oParam.Name { - // TODO: merge examples? transfer schema pattern? - continue outer - } - } - - **params = append(**params, oParam) - } -} - -func mergeOps(op **openapi.Operation, other **openapi.Operation) { - if *other == nil { - return - } - - if *op == nil { - *op = *other - } else { - // merge parameters - mergeParamLists(&(*op).Parameters, &(*other).Parameters) - - // merge responses - mergeOpResponses(&(*op).Responses, &(*other).Responses) - - // merge request body - mergeOpReqBodies(&(*op).RequestBody, &(*other).RequestBody) - - // historical OpIDs - // merge kpis - } -} - -func mergeOpReqBodies(r *openapi.RequestBody, r2 *openapi.RequestBody) { - -} - -func mergeOpResponses(r *openapi.Responses, o *openapi.Responses) { - -} diff --git a/agent/pkg/oas/utils_test.go b/agent/pkg/oas/utils_test.go index 4813926de..b0abc6019 100644 --- a/agent/pkg/oas/utils_test.go +++ b/agent/pkg/oas/utils_test.go @@ -1,6 +1,7 @@ package oas import ( + "encoding/json" "github.com/chanced/openapi" "reflect" "testing" @@ -72,7 +73,7 @@ func TestOpMerging(t *testing.T) { { &openapi.Operation{OperationID: "op1"}, &openapi.Operation{OperationID: "op2"}, - &openapi.Operation{OperationID: "op1"}, + &openapi.Operation{OperationID: "op1", Extensions: openapi.Extensions{}}, }, // has historicIds } @@ -80,7 +81,8 @@ func TestOpMerging(t *testing.T) { mergeOps(&tc.op1, &tc.op2) if !reflect.DeepEqual(tc.op1, tc.res) { - t.Errorf("Does not match expected") + txt, _ := json.Marshal(tc.op1) + t.Errorf("Does not match expected: %s", txt) } } }