@@ -129,6 +129,9 @@ type Scenario struct {
129129
130130 // Matches actual request with interaction requests.
131131 Matcher `yaml:"-"`
132+
133+ // Fields keeps track between old values(in recorded yaml file) and new values(in replay request)
134+ Fields map [string ]string
132135}
133136
134137// Implementations of sort.Interface to give us different orderings.
@@ -168,6 +171,7 @@ func NewScenario(name string) *Scenario {
168171 Version : scenarioFormatV1 ,
169172 Interactions : make (Interactions , 0 ),
170173 sortedInteractions : make (Interactions , 0 ),
174+ Fields : make (map [string ]string ),
171175 }
172176
173177 return s
@@ -197,24 +201,18 @@ func Load(name string) (*Scenario, error) {
197201
198202var calls = 0
199203
200- func transformer (req * Request , i Interaction , res * Response ) {
204+ func ( s * Scenario ) transformer (req * Request , i Interaction , res * Response ) {
201205 if req .BodyParsed != nil {
202- updateFieldMap (req , & i )
203- }
204-
205- for oldVal , changedVal := range fields {
206- if len (req .URL ) >= len (changedVal ) && strings .Contains (req .URL , oldVal ) {
207- req .URL = strings .Replace (req .URL , oldVal , changedVal , - 1 )
208- }
206+ s .updateFieldMap (req , & i )
209207 }
210208
211- if res .BodyParsed != nil && len (fields ) > 0 {
212- updateResFromFieldMap (res )
209+ if res .BodyParsed != nil && len (s . Fields ) > 0 {
210+ s . updateResFromFieldMap (res )
213211 }
214212 saveOrLog (req , fmt .Sprintf ("/tmp/%d-request.yaml" , calls ))
215213 saveOrLog (i , fmt .Sprintf ("/tmp/%d-interaction.yaml" , calls ))
216214 saveOrLog (res , fmt .Sprintf ("/tmp/%d-response.yaml" , calls ))
217- saveOrLog (fields , fmt .Sprintf ("/tmp/%d-fields-map.yaml" , calls ))
215+ saveOrLog (s . Fields , fmt .Sprintf ("/tmp/%d-fields-map.yaml" , calls ))
218216 calls ++
219217}
220218
@@ -228,7 +226,7 @@ func (s *Scenario) AddInteraction(i *Interaction) {
228226}
229227
230228func (s * Scenario ) GetInteractionWithFullPath (r Request ) (* Interaction , error ) {
231- newRequest , err := ConverRequestWithFullPath (r )
229+ newRequest , err := s . ConverRequestWithFullPath (r )
232230 if err != nil {
233231 return nil , err
234232 }
@@ -413,56 +411,6 @@ func (s *Scenario) GetInteractionWithBodyFromList(r Request, list []*Interaction
413411 return iMax , nil
414412}
415413
416- func getBodyMatchCredit (iBody jsonObj , rBody jsonObj ) int {
417- totalCredit := 0
418- for key , rUnk := range rBody {
419- if rStringVal , ok := rUnk .(string ); ok {
420- if iUnk , ok := iBody [key ]; ok {
421- if iStringVal , ok := iUnk .(string ); ok {
422- if iStringVal == rStringVal {
423- totalCredit ++
424- }
425- }
426- }
427- } else if rBoolVal , ok := rUnk .(bool ); ok {
428- if iUnk , ok := iBody [key ]; ok {
429- if iBoolVal , ok := iUnk .(bool ); ok {
430- if iBoolVal == rBoolVal {
431- totalCredit ++
432- }
433- }
434- }
435- } else if rJsonNumberVal , ok := rUnk .(json.Number ); ok {
436- if iUnk , ok := iBody [key ]; ok {
437- if iJsonNumberVal , ok := iUnk .(json.Number ); ok {
438- if iJsonNumberVal == rJsonNumberVal {
439- totalCredit ++
440- }
441- }
442- }
443- } else if rStringMapVal , ok := rUnk .(map [string ]interface {}); ok {
444- if iUnk , ok := iBody [key ]; ok {
445- if iStringMapVal , ok := iUnk .(map [string ]interface {}); ok {
446- totalCredit += getBodyMatchCredit (iStringMapVal , rStringMapVal )
447- }
448- }
449- } else if rArrayVal , ok := rUnk .([]interface {}); ok {
450- for _ , rObj := range rArrayVal {
451- if rJsonObj , ok := rObj .(jsonObj ); ok {
452- if iUnk , ok := iBody [key ]; ok {
453- if iJsonObj , ok := iUnk .(jsonObj ); ok {
454- totalCredit += getBodyMatchCredit (iJsonObj , rJsonObj )
455- }
456- }
457- }
458- }
459- } else {
460- debugLogf ("unsupported type in match: %v, %v" , reflect .TypeOf (rUnk ), rUnk )
461- }
462- }
463- return totalCredit
464- }
465-
466414// Reset returns us to the beginning of the scenario
467415func (s * Scenario ) Reset () {
468416 for index := range s .Interactions {
@@ -530,10 +478,8 @@ func (s *Scenario) Save() error {
530478 return nil
531479}
532480
533- var fields = make (map [string ]string )
534-
535- func ConverRequestWithFullPath (r Request ) (Request , error ) {
536- for key , value := range fields {
481+ func (s * Scenario ) ConverRequestWithFullPath (r Request ) (Request , error ) {
482+ for key , value := range s .Fields {
537483 if strings .Contains (r .URL , value ) {
538484 r .URL = strings .Replace (r .URL , value , key , - 1 )
539485 return r , nil
@@ -542,68 +488,118 @@ func ConverRequestWithFullPath(r Request) (Request, error) {
542488 return r , ErrInteractionNotFound
543489}
544490
545- func updateFieldMap (req * Request , i * Interaction ) {
491+ func getBodyMatchCredit (iBody jsonObj , rBody jsonObj ) int {
492+ totalCredit := 0
493+ for key , rUnk := range rBody {
494+ if rStringVal , ok := rUnk .(string ); ok {
495+ if iUnk , ok := iBody [key ]; ok {
496+ if iStringVal , ok := iUnk .(string ); ok {
497+ if iStringVal == rStringVal {
498+ totalCredit ++
499+ }
500+ }
501+ }
502+ } else if rBoolVal , ok := rUnk .(bool ); ok {
503+ if iUnk , ok := iBody [key ]; ok {
504+ if iBoolVal , ok := iUnk .(bool ); ok {
505+ if iBoolVal == rBoolVal {
506+ totalCredit ++
507+ }
508+ }
509+ }
510+ } else if rJsonNumberVal , ok := rUnk .(json.Number ); ok {
511+ if iUnk , ok := iBody [key ]; ok {
512+ if iJsonNumberVal , ok := iUnk .(json.Number ); ok {
513+ if iJsonNumberVal == rJsonNumberVal {
514+ totalCredit ++
515+ }
516+ }
517+ }
518+ } else if rStringMapVal , ok := rUnk .(map [string ]interface {}); ok {
519+ if iUnk , ok := iBody [key ]; ok {
520+ if iStringMapVal , ok := iUnk .(map [string ]interface {}); ok {
521+ totalCredit += getBodyMatchCredit (iStringMapVal , rStringMapVal )
522+ }
523+ }
524+ } else if rArrayVal , ok := rUnk .([]interface {}); ok {
525+ for _ , rObj := range rArrayVal {
526+ if rJsonObj , ok := rObj .(jsonObj ); ok {
527+ if iUnk , ok := iBody [key ]; ok {
528+ if iJsonObj , ok := iUnk .(jsonObj ); ok {
529+ totalCredit += getBodyMatchCredit (iJsonObj , rJsonObj )
530+ }
531+ }
532+ }
533+ }
534+ } else {
535+ debugLogf ("unsupported type in match: %v, %v" , reflect .TypeOf (rUnk ), rUnk )
536+ }
537+ }
538+ return totalCredit
539+ }
540+
541+ func (s * Scenario ) updateFieldMap (req * Request , i * Interaction ) {
546542 if body , ok := req .BodyParsed .(jsonObj ); ok {
547543 if iBody , ok := i .Request .BodyParsed .(jsonObj ); ok {
548- updateInternalFieldMap (iBody , body )
544+ s . updateInternalFieldMap (iBody , body )
549545 }
550546 }
551547}
552548
553- func updateInternalFieldMap (oldValue , newValue interface {}) {
549+ func ( s * Scenario ) updateInternalFieldMap (oldValue , newValue interface {}) {
554550 if stringOldValue , ok := oldValue .(string ); ok {
555551 stringNewValue , _ := newValue .(string )
556552 if strings .EqualFold (stringOldValue , stringNewValue ) == false {
557- fields [stringOldValue ] = stringNewValue
553+ s . Fields [stringOldValue ] = stringNewValue
558554 }
559555 } else if boolOldValue , ok := oldValue .(bool ); ok {
560556 boolNewValue , _ := newValue .(bool )
561557 if boolOldValue != boolNewValue {
562- fields [strconv .FormatBool (boolOldValue )] = strconv .FormatBool (boolNewValue )
558+ s . Fields [strconv .FormatBool (boolOldValue )] = strconv .FormatBool (boolNewValue )
563559 }
564560 } else if jsonNumberOldValue , ok := oldValue .(json.Number ); ok {
565561 jsonNumberNewValue , _ := newValue .(json.Number )
566562 if jsonNumberNewValue .String () != jsonNumberOldValue .String () {
567- fields [jsonNumberOldValue .String ()] = jsonNumberNewValue .String ()
563+ s . Fields [jsonNumberOldValue .String ()] = jsonNumberNewValue .String ()
568564 }
569565 } else if mapOldValue , ok := oldValue .(jsonObj ); ok {
570566 mapNewValue , _ := newValue .(jsonObj )
571567 for k , v := range mapOldValue {
572- updateInternalFieldMap (v , mapNewValue [k ])
568+ s . updateInternalFieldMap (v , mapNewValue [k ])
573569 }
574570 } else if mapOldValue , ok := oldValue .(map [string ]interface {}); ok {
575571 mapNewValue , _ := newValue .(map [string ]interface {})
576572 for k , v := range mapOldValue {
577- updateInternalFieldMap (v , mapNewValue [k ])
573+ s . updateInternalFieldMap (v , mapNewValue [k ])
578574 }
579575 } else if arrayOldValue , ok := oldValue .([]interface {}); ok {
580576 arrayNewValue , _ := newValue .([]interface {})
581577 for i := range arrayOldValue {
582- updateInternalFieldMap (arrayOldValue [i ], arrayNewValue [i ])
578+ s . updateInternalFieldMap (arrayOldValue [i ], arrayNewValue [i ])
583579 }
584580 } else {
585581 debugLogf ("HttpReplay will ignore the type match for type %s" , reflect .TypeOf (oldValue ))
586582 }
587583}
588584
589- func updateBody (body jsonObj ) {
585+ func ( s * Scenario ) updateBody (body jsonObj ) {
590586 for key , unkVal := range body {
591587 if unkVal == nil {
592588 continue
593589 } else if val , ok := unkVal .(string ); ok {
594- bodyValueHandle (body , val , key )
590+ s . bodyValueHandle (body , val , key )
595591 } else if val , ok := unkVal .(bool ); ok {
596- bodyValueHandle (body , strconv .FormatBool (val ), key )
592+ s . bodyValueHandle (body , strconv .FormatBool (val ), key )
597593 } else if val , ok := unkVal .(json.Number ); ok {
598- bodyValueHandle (body , val .String (), key )
594+ s . bodyValueHandle (body , val .String (), key )
599595 } else if val , ok := unkVal .(map [string ]interface {}); ok {
600- updateBody (val )
596+ s . updateBody (val )
601597 } else if val , ok := unkVal .([]interface {}); ok {
602598 for _ , item := range val {
603599 if jsonItem , ok := item .(map [string ]interface {}); ok {
604- updateBody (jsonItem )
600+ s . updateBody (jsonItem )
605601 } else if strItem , ok := item .(string ); ok {
606- bodyValueHandle (body , strItem , key )
602+ s . bodyValueHandle (body , strItem , key )
607603 }
608604 }
609605 } else {
@@ -612,21 +608,21 @@ func updateBody(body jsonObj) {
612608 }
613609}
614610
615- func bodyValueHandle (body jsonObj , val string , key string ) {
616- for oldVal , changedVal := range fields {
617- if len (val ) >= len (changedVal ) && strings .Contains (val , oldVal ) {
611+ func ( s * Scenario ) bodyValueHandle (body jsonObj , val string , key string ) {
612+ for oldVal , changedVal := range s . Fields {
613+ if len (changedVal ) > 1 && len ( val ) >= len (changedVal ) && strings .Contains (val , oldVal ) {
618614 body [key ] = strings .Replace (val , oldVal , changedVal , - 1 )
619615 }
620616 }
621617}
622618
623- func updateResFromFieldMap (res * Response ) {
619+ func ( s * Scenario ) updateResFromFieldMap (res * Response ) {
624620 if body , ok := res .BodyParsed .(jsonObj ); ok {
625- updateBody (body )
621+ s . updateBody (body )
626622 }
627623 if iBodyArr , ok := res .BodyParsed .(jsonArr ); ok {
628624 for objIndex := range iBodyArr {
629- updateBody (iBodyArr [objIndex ])
625+ s . updateBody (iBodyArr [objIndex ])
630626 }
631627 }
632628}
0 commit comments