spring-cloud-contract
spring-cloud-contract copied to clipboard
Add better support for WireMock's RequestMatcherExtension
With RequestMatcherExtension
we could consider allowing giving the users the option to pass in their own, custom matching options. Sth like this:
class DefaultRequestMatcher extends RequestMatcherExtension {
private static final String GROOVY_EXPRESSION = "groovy-expression";
@Override
public MatchResult match(Request request, Parameters parameters) {
if (!parameters.containsKey(GROOVY_EXPRESSION)) {
return MatchResult.exactMatch();
}
String expression = parameters.getString(GROOVY_EXPRESSION);
GroovyShell groovyShell = new GroovyShell();
groovyShell.setVariable("body", request.getBody());
return MatchResult.of(groovyShell.evaluate(expression) != null);
}
@Override
public String getName() {
return GROOVY_EXPRESSION;
}
}
the WireMock stub could look like this:
{
"request" : {
"customMatcher" : {
"name" : "groovy-expression",
"parameters" : {
"groovy-expression" : "new JsonSlurper(body.asString()).findAll {it.name == 'foo'}"
}
}
},
"response" : {
"status" : 422
}
}
then in the DSL one could call:
bodyMatchers {
expression('new JsonSlurper(body.asString()).findAll {it.name == 'foo'}')
}
To consider:
- security issues (you can run an arbitrary Groovy code)
- maybe SPeL would be enough
- passing in slurped body (either json or xml) instead of WireMock's body
As per our (@marcingrzejszczak and I) discussion yesterday:
Tim: I’d suggest to start with a custom matcher based on SPeL, and make a separate one for groovy? Like you said, it has a lot of security implications. Marcin: I wonder if Spel is actually good enough to do the slurping etc. cause the body would need to be converted to a map or sth for spel to work. otoh we already parse groovy scripts that can contain all sort of crap. Tim: That’s also true 😂 But passing the slurped body to both custom matchers should make your life easier I guess. Marcin: I think that it could be a map - then Spel would work Tim: Let me add these comments to github later today, so others can see our new thoughts :)