Tracks historical IDs

This commit is contained in:
Andrey Pokhilko
2022-02-25 20:48:03 +03:00
parent a9c5be1ba4
commit 42f2c245f7
4 changed files with 124 additions and 81 deletions

119
agent/pkg/oas/merger.go Normal file
View File

@@ -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) {
}

View File

@@ -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

View File

@@ -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) {
}

View File

@@ -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)
}
}
}