Wiremock templating `fixedDelayMilliseconds`

huangapple go评论78阅读模式
英文:

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 templating `fixedDelayMilliseconds`

我认为你可以通过自定义转换器来扩展 WireMock,该转换器将解析响应体中的延迟,并将其作为数字添加到响应中。有关更多信息,请查看扩展 WireMock 文档。编辑:现在我看到你已经得出了这个假设。我认为你是对的 Wiremock templating `fixedDelayMilliseconds` -- 这最容易通过转换器实现。

英文:

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 Wiremock templating `fixedDelayMilliseconds`

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 Wiremock templating `fixedDelayMilliseconds` -- 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()
  }
}

huangapple
  • 本文由 发表于 2020年9月22日 12:31:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/64003118.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定