@@ -31,7 +31,7 @@ public class OpenAPIValidator
3131
3232 private OpenApiInteractionValidator validator ;
3333
34- private MaxSizeHashMap <String , String > exposurePath2SpecifiedPathMap = new MaxSizeHashMap <String , String >();
34+ private MaxSizeHashMap <String , Object > exposurePath2SpecifiedPathMap = new MaxSizeHashMap <String , Object >();
3535
3636 private int payloadLogMaxLength = 40 ;
3737
@@ -96,7 +96,7 @@ public boolean isValidRequest(String payload, String verb, String path, QueryStr
9696 Utils .traceMessage ("Validate request: [verb: " +verb +", path: '" +path +"', payload: '" +Utils .getContentStart (payload , payloadLogMaxLength , true )+"']" , TraceLevel .INFO );
9797 ValidationReport validationReport = null ;
9898 String originalPath = path ;
99- // The given path might be the FE-API exposed path which is not always part of the API-Specification.
99+ // The given path might be the FE-API exposure path which is not guaranteed to be part of the API-Specification.
100100 // If for example the Petstore is exposed with /petstore/v3 the path we get might be /petstore/v3/store/order/78787
101101 // and with that, the validation fails, as the specification doesn't contain this path.
102102 // The following code nevertheless tries to find the matching API path by removing the first part of the path and
@@ -105,11 +105,19 @@ public boolean isValidRequest(String payload, String verb, String path, QueryStr
105105 boolean cachePath = false ;
106106 // Perhaps the path has already looked up and matched to the specified path (e.g. /petstore/v3/store/order/78787 --> /store/order/{orderId}
107107 if (exposurePath2SpecifiedPathMap .containsKey (path )) {
108- // In that case perform the validation based on the cached path
109- validationReport = validateRequest (payload , verb , exposurePath2SpecifiedPathMap .get (path ), queryParams , headers );
108+ if (exposurePath2SpecifiedPathMap .get (path ) instanceof ValidationReport ) {
109+ // Previously with the given we got a validation error, just return the same again
110+ validationReport = (ValidationReport )exposurePath2SpecifiedPathMap .get (path );
111+ } else {
112+ // In that case perform the validation based on the cached path
113+ validationReport = validateRequest (payload , verb , (String )exposurePath2SpecifiedPathMap .get (path ), queryParams , headers );
114+ }
110115 } else {
111116 // Otherwise try to find the belonging specified path
112117 for (int i =0 ; i <5 ;i ++) {
118+ if (cachePath ) {
119+ Utils .traceMessage ("Retrying validation with reduced path: '" +path +"']' (" +i +"/5)" , TraceLevel .INFO );
120+ }
113121 validationReport = validateRequest (payload , verb , path , queryParams , headers );
114122 if (validationReport .hasErrors ()) {
115123 if (validationReport .getMessages ().toString ().contains ("No API path found that matches request" )) {
@@ -125,7 +133,12 @@ public boolean isValidRequest(String payload, String verb, String path, QueryStr
125133 }
126134 }
127135 if (cachePath ) {
128- exposurePath2SpecifiedPathMap .put (originalPath , path );
136+ if (validationReport .hasErrors () && validationReport .getMessages ().toString ().contains ("No API path found that matches request" )) {
137+ // Finally no match found, cache the returned validation report
138+ exposurePath2SpecifiedPathMap .put (originalPath , validationReport );
139+ } else {
140+ exposurePath2SpecifiedPathMap .put (originalPath , path );
141+ }
129142 }
130143 }
131144
@@ -248,7 +261,7 @@ public void setMaxSize(int maxSize) {
248261 }
249262 }
250263
251- public MaxSizeHashMap <String , String > getExposurePath2SpecifiedPathMap () {
264+ public MaxSizeHashMap <String , Object > getExposurePath2SpecifiedPathMap () {
252265 return exposurePath2SpecifiedPathMap ;
253266 }
254267}
0 commit comments