英文:
Wiremock templating fixedDelayMilliseconds
问题
{
"request": {
"method": "POST",
"headers": {
"SOAPAction": {
"matches": "http://redacted"
}
},
"bodyPatterns": [
{
"matchesXPath": {
"expression": "//*[local-name()='family-name']/text()",
"matches": "^delay_([0-9]+)$"
}
}
]
},
"response": {
"status": 200,
"bodyFileName": "verify.xml",
"fixedDelayMilliseconds": "{{soapXPath request.body 'number(substring-after(//*[local-name()=\"family-name\"]/text(), \"delay_\"))'}}"
}
}
Please note that WireMock allows templating in response headers and bodies, as well as the bodyFileName
. However, not all response fields are templatable. The error you're encountering is likely due to WireMock trying to interpret the templated value {{soapXPath request.body 'number(substring-after(//*[local-name()="family-name"]/text(), "timeout_"))'}}
as an integer, which is causing the issue. It seems that the templating might not work in the fixedDelayMilliseconds
field as you're trying to use it.
For more complex transformations, you might need to explore creating custom extensions for WireMock, as you've mentioned. The WireMock documentation on extending WireMock (http://wiremock.org/docs/extending-wiremock/) provides guidance on creating response definition transformers using Java. This could potentially provide a solution to achieving the dynamic delays you're looking for.
If you're unsure about how WireMock handles templating or if it supports dynamic delays through response transformers, reaching out to the WireMock community or checking for updates in the official documentation might provide further insights.
英文:
I am trying to generated a response in wiremock, after a delay, where that delay is derived from the incoming request. e.g the family-name of the user in the request is "delay_10000" then delay by 10000 milliseconds, or delay_20000 then delay by 20000.....
{
"request": {
"method": "POST",
"headers": {
"SOAPAction": {
"matches": "http://redacted"
}
},
"bodyPatterns": [
{
"matchesXPath": {
"expression": "//*[local-name()=\"family-name\"]/text()",
"matches": "^delay_([0-9]+)$"
}
}
]
},
"response": {
"status": 200,
"bodyFileName": "verify.xml",
"fixedDelayMilliseconds": "{{soapXPath request.body 'number(substring-after(//*[local-name()=\"family-name\"]/text(), \"delay_\"))'}}"
}
}
Can anyone confirm whether which fields are able to be templated. The doco suggests "response headers and bodies", and elsewhere bodyFileName (which i have working) but it says nothing about whether or not other response fields can be templated.
Presently i'm seeing
2020-09-22 02:43:24.441 Verbose logging enabled
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" com.github.tomakehurst.wiremock.standalone.MappingFileException: Error loading file /home/wiremock/./mappings/equifax_generic_verify_identity_delay.json:
Cannot deserialize value of type `java.lang.Integer` from String "{{soapXPath request.body 'number(substring-after(//*[local-name()="family-name"]/text(), "timeout_"))'}}": not a valid Integer value
at com.github.tomakehurst.wiremock.standalone.JsonFileMappingsSource.loadMappingsInto(JsonFileMappingsSource.java:121)
at com.github.tomakehurst.wiremock.core.WireMockApp.loadMappingsUsing(WireMockApp.java:204)
at com.github.tomakehurst.wiremock.core.WireMockApp.loadDefaultMappings(WireMockApp.java:200)
at com.github.tomakehurst.wiremock.core.WireMockApp.<init>(WireMockApp.java:103)
at com.github.tomakehurst.wiremock.WireMockServer.<init>(WireMockServer.java:73)
at com.github.tomakehurst.wiremock.standalone.WireMockServerRunner.run(WireMockServerRunner.java:65)
at com.github.tomakehurst.wiremock.standalone.WireMockServerRunner.main(WireMockServerRunner.java:134)
stream closed
Firstly I can see where that is being caught, but not clearly where it's thrown
https://github.com/tomakehurst/wiremock/blob/master/src/main/java/com/github/tomakehurst/wiremock/standalone/JsonFileMappingsSource.java#L121
Secondly, it's unclear to me whether i'm just driving wiremock wrong, and this is NOT possible via a response transformer, but is possible via an extension and a "Response definition transformation" (http://wiremock.org/docs/extending-wiremock/)
I can work around this with a set of fixed delays - but it would be nicer if it were dynamic
Help appreciated !
答案1
得分: 1
所以我的最初假设是这是不可能的,因为对模板的任何使用都将解析为字符串,但 fixedDelayMilliseconds
需要一个数字,所以 WireMock 会抛出错误
我认为你可以通过自定义转换器来扩展 WireMock,该转换器将解析响应体中的延迟,并将其作为数字添加到响应中。有关更多信息,请查看扩展 WireMock 文档。编辑:现在我看到你已经得出了这个假设。我认为你是对的 -- 这最容易通过转换器实现。
英文:
So my initial assumption is that this isn't possible, since any use of the templates will resolve to a string, but fixedDelayMilliseconds
wants a number, so WireMock will throw errors
I think you could extend WireMock with a custom transformer that would parse the delay in the response body and add it as a number in the response. For more information, check out the Extending WireMock documentation. Edit: I see now that you already arrived at this assumption. I think you're right -- this is most easily possible through a transformer.
答案2
得分: 1
我遇到了类似的问题,我创建了一个响应定义扩展,当提供时,它从标头中获取信息。
class InjectDelayFromHeader : ResponseDefinitionTransformer() {
override fun getName() = "InjectDelayFromHeader";
override fun transform(
request: Request,
response: ResponseDefinition,
files: FileSource,
parameters: Parameters
): ResponseDefinition {
val delay = request.getHeader("X-WIREMOCK-DELAY")
if (delay.isNullOrBlank()) {
return response
}
return ResponseDefinitionBuilder.like(response).withFixedDelay(Integer.valueOf(delay)).build()
}
}
英文:
I had a similar issue and I created a response definition extension which takes it from the header when provided.
class InjectDelayFromHeader : ResponseDefinitionTransformer() {
override fun getName() = "InjectDelayFromHeader"
override fun transform(
request: Request,
response: ResponseDefinition,
files: FileSource,
parameters: Parameters
): ResponseDefinition {
val delay = request.getHeader("X-WIREMOCK-DELAY")
if (delay.isNullOrBlank()) {
return response
}
return ResponseDefinitionBuilder.like(response).withFixedDelay(Integer.valueOf(delay)).build()
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论