1919import com .amazon .aoc .exception .BaseException ;
2020import com .amazon .aoc .exception .ExceptionCode ;
2121import com .amazon .aoc .fileconfigs .FileConfig ;
22- import com .amazon .aoc .helpers .MustacheHelper ;
23- import com .amazon .aoc .helpers .RetryHelper ;
2422import com .amazon .aoc .models .Context ;
2523import com .amazon .aoc .models .SampleAppResponse ;
2624import com .amazon .aoc .services .XRayService ;
2725import com .amazonaws .services .xray .model .Trace ;
26+ import com .github .wnameless .json .flattener .JsonFlattener ;
2827import lombok .extern .log4j .Log4j2 ;
28+ import org .json .simple .JSONObject ;
29+ import org .json .simple .parser .JSONParser ;
2930
30- import java .util .Arrays ;
31- import java .util .Comparator ;
32- import java .util .List ;
33- import java .util .stream .Collectors ;
31+ import java .io .FileReader ;
32+ import java .util .*;
33+ import java .util .concurrent .TimeUnit ;
3434
3535@ Log4j2
3636public class TraceValidator implements IValidator {
37- private MustacheHelper mustacheHelper = new MustacheHelper ();
38- private static int MAX_RETRY_COUNT = 60 ;
39- private Context context ;
37+ private static int MAX_RETRY_COUNT = 3 ;
4038 private XRayService xrayService ;
4139 private ICaller caller ;
4240 private FileConfig expectedTrace ;
4341
44- @ Override
45- public void init (Context context , ICaller caller , FileConfig expectedTrace ) throws Exception {
46- this .context = context ;
47- this .xrayService = new XRayService (context .getRegion ());
48- this .caller = caller ;
49- this .expectedTrace = expectedTrace ;
50- }
51-
52- @ Override
53- public void validate () throws Exception {
54- List <Trace > expectedTraceList = this .getExpectedTrace ();
55- expectedTraceList .sort (Comparator .comparing (Trace ::getId ));
56- RetryHelper .retry (
57- MAX_RETRY_COUNT ,
58- () -> {
59- List <Trace > traceList =
60- xrayService .listTraceByIds (
61- expectedTraceList .stream ()
62- .map (trace -> trace .getId ())
63- .collect (Collectors .toList ()));
64-
65- traceList .sort (Comparator .comparing (Trace ::getId ));
66-
67- log .info ("expectedTraceList: {}" , expectedTraceList );
68- log .info ("traceList got from backend: {}" , traceList );
69- if (expectedTraceList .size () != traceList .size ()) {
70- throw new BaseException (ExceptionCode .TRACE_LIST_NOT_MATCHED );
71- }
72-
73- for (int i = 0 ; i != expectedTraceList .size (); ++i ) {
74- Trace trace = traceList .get (i );
75- compareTwoTraces (expectedTraceList .get (i ), trace );
76- }
77- });
78- }
79-
80- private void compareTwoTraces (Trace trace1 , Trace trace2 ) throws BaseException {
81- // check trace id
82- if (!trace1 .getId ().equals (trace2 .getId ())) {
83- throw new BaseException (ExceptionCode .TRACE_ID_NOT_MATCHED );
42+ @ Override
43+ public void init (Context context , ICaller caller , FileConfig expectedTrace ) throws Exception {
44+ this .xrayService = new XRayService (context .getRegion ());
45+ this .caller = caller ;
46+ this .expectedTrace = expectedTrace ;
8447 }
8548
86- /*
87- if (trace1.getSegments().size() != trace2.getSegments().size()) {
88- throw new BaseException(ExceptionCode.TRACE_SPAN_LIST_NOT_MATCHED);
49+ @ Override
50+ public void validate () throws Exception {
51+ // get stored trace
52+ Map <String , Object > storedTrace = this .getStoredTrace ();
53+
54+ // create trace id list to retrieve trace from x-ray service
55+ String traceId = (String ) storedTrace .get ("trace_id" );
56+ List <String > traceIdList = Collections .singletonList (traceId );
57+
58+ // get retrieved trace from x-ray service
59+ Map <String , Object > retrievedTrace = this .getRetrievedTrace (traceIdList );
60+
61+ // validation of trace id
62+ if (!storedTrace .get ("trace_id" ).equals (retrievedTrace .get ("trace_id" ))) {
63+ throw new BaseException (ExceptionCode .TRACE_ID_NOT_MATCHED );
64+ }
65+
66+ // data model validation of other fields of segment document
67+ for (Map .Entry <String , Object > entry : storedTrace .entrySet ()) {
68+ if (!entry .getValue ().equals (retrievedTrace .get (entry .getKey ()))) {
69+ log .info ("mis matched data model field list" );
70+ log .info ("value of stored trace map: {}" , entry .getValue ());
71+ log .info ("value of retrieved map: {}" ,retrievedTrace .get (entry .getKey ()));
72+ log .info ("==========================================" );
73+ throw new BaseException (ExceptionCode .DATA_MODEL_NOT_MATCHED );
74+ }
75+ }
8976 }
90- trace1.getSegments().sort(Comparator.comparing(Segment::getId));
91- trace2.getSegments().sort(Comparator.comparing(Segment::getId));
92-
93- for (int i = 0; i != trace1.getSegments().size(); ++i) {
94- // check span id
95- if (!trace1.getSegments().get(i).getId()
96- .equals(trace2.getSegments().get(i).getId())) {
97- throw new BaseException(ExceptionCode.TRACE_SPAN_NOT_MATCHED);
98- }
99- }*/
100- }
101-
102- // this endpoint will be a http endpoint including the path with get method
103- private List <Trace > getExpectedTrace () throws Exception {
104- SampleAppResponse sampleAppResponse = this .caller .callSampleApp ();
105-
106- // convert the trace data into xray format
107- Trace trace = new Trace ();
108- trace .setId (sampleAppResponse .getTraceId ());
109-
110- // todo: construct the trace data from the template file
111-
112- // we can support multi expected trace id to validate if need
113- return Arrays .asList (trace );
114- }
115- }
77+
78+ // this method will hit get trace from x-ray service and get retrieved trace
79+ private Map <String , Object > getRetrievedTrace (List <String > traceIdList ) throws Exception {
80+ Map <String , Object > flattenedJsonMapForRetrievedTrace = null ;
81+
82+ // retrieve trace from x-ray service
83+ TimeUnit .SECONDS .sleep (15 );
84+ List <Trace > retrieveTraceList = xrayService .listTraceByIds (traceIdList );
85+
86+ try {
87+ // flattened JSON object to a map
88+ flattenedJsonMapForRetrievedTrace = JsonFlattener .flattenAsMap (retrieveTraceList .get (0 ).getSegments ().get (0 ).getDocument ());
89+ } catch (Exception e ) {
90+ e .printStackTrace ();
91+ }
92+
93+ return flattenedJsonMapForRetrievedTrace ;
94+ }
95+
96+ // this method will hit a http endpoints of sample web apps and get stored trace
97+ private Map <String , Object > getStoredTrace () throws Exception {
98+ String PATH = "src/main/resources" ;
99+ Map <String , Object > flattenedJsonMapForStoredTraces = null ;
100+
101+ SampleAppResponse sampleAppResponse = this .caller .callSampleApp ();
102+
103+ JSONParser parser = new JSONParser ();
104+ try {
105+ Object obj = parser .parse (new FileReader (PATH + this .expectedTrace .getPath ()));
106+ JSONObject jsonObject = (JSONObject ) obj ;
107+
108+ // flattened JSON object to a map
109+ flattenedJsonMapForStoredTraces = JsonFlattener .flattenAsMap (jsonObject .toString ());
110+ flattenedJsonMapForStoredTraces .put ("trace_id" , sampleAppResponse .getTraceId ());
111+ } catch (Exception e ) {
112+ e .printStackTrace ();
113+ }
114+
115+ return flattenedJsonMapForStoredTraces ;
116+ }
117+ }
0 commit comments