Arieh Markel
12/05/2024, 9:52 AMmockServer.stubFor(
put(urlPathTemplate("/v1/defs/{name}"))
.willReturn(putResp)
I am not sure how to define the GET stub to effectively cause the return of the body of the PUT request.
I have read the Extensions documentation and I have configured my wireMock as follows:
CaffeineStore store = new CaffeineStore();
options().templatingEnabled(true).globalTemplating(true).extensions(new StateExtension(store));
WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(port));
From the documentation examples, which are json (and not Java) I find it hard to map those json definitions to the java counterpart to set in the stub.
It seemed to me that involving a .withServeEventListener()
invocation in the stub should achieve that but I could not figure out the exact incantation.
Any help or pointer will be welcome.Arieh Markel
12/05/2024, 10:05 AMArieh Markel
12/05/2024, 10:35 AMpublic static void configureStubs(WireMockServer mockServer) {
ResponseDefinitionBuilder putResp = aResponse().withStatus(HttpStatus.SC_NO_CONTENT);
mockServer.stubFor(
put(urlPathTemplate("/v1/defs/{name}"))
.willReturn(putResp)
.withServeEventListener("recordState",
Parameters.from(
Map.of(
"context", "{{request.path}}",
"state", Map.of(
"statePayload", "{{request.body}}")
))));
ResponseDefinitionBuilder getResp = aResponse().withStatus(HttpStatus.SC_OK);
mockServer.stubFor(
get(urlPathTemplate("/v1/defs/{name}"))
.andMatching("state-matcher",
Parameters.from(
Map.of("hasContext", "{{request.path}}")
))
.willReturn(
WireMock.ok()
.withHeader("content-type", "application/json")
.withBody("{{state context=request.path}}")
)
);
}
I would appreciate some input to indicate whether I am in the right directionLee Turner
12/05/2024, 10:47 AMArieh Markel
12/05/2024, 10:57 AMjava.lang.NoSuchMethodError: 'java.util.Map com.github.tomakehurst.wiremock.extension.responsetemplating.TemplateEngine.buildModelForRequest(com.github.tomakehurst.wiremock.http.Request)'
Lee Turner
12/05/2024, 11:03 AMArieh Markel
12/05/2024, 11:05 AMArieh Markel
12/05/2024, 11:08 AMLee Turner
12/05/2024, 11:09 AMLee Turner
12/05/2024, 11:10 AM3.10.0
was released recentlyArieh Markel
12/05/2024, 11:38 AMMap.of(
"context",
"{{request.path}}",
"state",
Map.of("statePayload", "{{request.body}}"))
• In the GET
Parameters.from(Map.of("hasContext", "{{request.path}}")))
.willReturn(
WireMock.ok()
.withHeader("content-type", "application/json")
.withBody("{{state context=request.path}}")));
I am wondering if I am missing using the 'statePayload' field in the Map for the population of the bodyArieh Markel
12/05/2024, 11:40 AM{state context=request.path property='statePayload'}
Arieh Markel
12/05/2024, 11:44 AMRequest was not matched
=======================
-----------------------------------------------------------------------------------------------------------------------
| Closest stub | Request |
-----------------------------------------------------------------------------------------------------------------------
|
PUT | GET <<<<< HTTP method does not match
[path template] | /v1/defs/DiagnosticAction
/v1/defs/{name} |
|
|
-----------------------------------------------------------------------------------------------------------------------
Is it implying it did not insert the stub for GET or that it does not recognize it ?
Any problem with the GET stub definition ?Dirk Bolte
12/05/2024, 11:57 AM.notifier(new ConsoleNotifier(true))
Arieh Markel
12/05/2024, 12:21 PM2024-12-05 12:09:04.053 Request received:
127.0.0.1 - PUT /v1/defs/DiagnosticAction
Accept: [application/json]
X-Workflow-Client-Version: [13.0.4]
X-Workflow-Client-Host: [<http://amarkel.xxxxxxx.com|amarkel.xxxxxxx.com>]
x-wfaas-domain: [localhost]
opc-client-retries: [false]
opc-request-id: [CC9F11D273854B518C6FAE1266FDC44B]
Content-Type: [application/json]
User-Agent: [Oracle-JavaSDK/2.76.0 (Linux/5.4.17-2136.314.6.3.el7uek.x86_64; Java/17.0.5; Java HotSpot(TM) 64-Bit Server VM/17.0.5+9-LTS-191)]
opc-client-info: [Oracle-JavaSDK/2.76.0]
Host: [localhost:39000]
Connection: [keep-alive]
Content-Length: [1443]
{"<JSON-PAYLOAD>"}
Matched response definition:
{
"status" : 204
}
Response:
HTTP/1.1 204
Matched-Stub-Id: [92dc08fc-102e-4978-835a-1fb5eeaba509]
2024-12-05 12:09:04.281 Context '/v1/defs/DiagnosticAction': created
2024-12-05 12:09:04.282 Context '/v1/defs/DiagnosticAction': property 'statePayload' updated
• GET retrieval
2024-12-05 12:09:04.373 Context '/v1/definitions/DiagnosticAction/2/0': hasContext matched
2024-12-05 12:09:04.395 Request received:
127.0.0.1 - GET /v1/defs/DiagnosticAction
Accept: [application/json]
X-Workflow-Client-Version: [13.0.4]
X-Workflow-Client-Host: [<http://amarkel.xxxxxx.com|amarkel.xxxxxx.com>]
x-wfaas-domain: [localhost]
opc-client-retries: [false]
opc-request-id: [071F0836DB734F7AB08EA22040C5D536]
User-Agent: [Oracle-JavaSDK/2.76.0 (Linux/5.4.17-2136.314.6.3.el7uek.x86_64; Java/17.0.5; Java HotSpot(TM) 64-Bit Server VM/17.0.5+9-LTS-191)]
opc-client-info: [Oracle-JavaSDK/2.76.0]
Host: [localhost:39000]
Connection: [keep-alive]
Matched response definition:
{
"status" : 200,
"jsonBody" : "{{state context=request.path} property='statePayload'}",
"headers" : {
"content-type" : "application/json"
}
}
Response:
HTTP/1.1 200
content-type: [application/json]
Matched-Stub-Id: [c2a14f1f-9bf0-4ead-b64c-98edb66a2607]
What seems evident is that there is no 'handlebar' transformation/extraction of the 'statePayload' property
here are the updated definitions:
PUT:
ResponseDefinitionBuilder putResp = aResponse().withStatus(HttpStatus.SC_NO_CONTENT);
mockServer.stubFor(
put(urlPathTemplate("/v1/defs/{name}"))
.willReturn(putResp)
.withServeEventListener(
"recordState",
Parameters.from(
Map.of(
"context",
"{{request.path}}",
"state",
Map.of("statePayload", "{{request.body}}")))));
GET:
mockServer.stubFor(
get(urlPathTemplate("/v1/defs/{name}"))
.andMatching(
"state-matcher",
Parameters.from(Map.of("hasContext", "{{request.path}}")))
.willReturn(
WireMock.ok()
.withHeader("content-type", "application/json")
.withJsonBody(
MAPPER.readTree(
MAPPER.writeValueAsString(
"{{state context=request.path} property='statePayload'}")))));
I can now see my mistake - the double handlebar incorrect in the GET stubArieh Markel
12/05/2024, 12:22 PM"{{state context=request.path property='statePayload'}}")
Arieh Markel
12/05/2024, 12:32 PM.withJsonBody(
MAPPER.readTree(
captureValue(
MAPPER.writeValueAsString(
"{{state context=request.path property='statePayload'}}"))))));
But in 'captureValue' I don't see the content extracted from state, but the same string in the quotes.Arieh Markel
12/05/2024, 12:51 PMMap.of("statePayload", "{{request.body}}"))))
be
Map.of("statePayload", "{{request.body $}}"))))
Inspecting with the debugger in the IDE shows that the store has not cached any valuesArieh Markel
12/05/2024, 1:01 PMstatePayload => {{jsonPath request.body '$'}}
I am not sure about the magic incantation to stick the request.body into the state MapArieh Markel
12/05/2024, 1:15 PMTo record a complete response body, use (ATTENTION: tripple {{{):
Arieh Markel
12/05/2024, 1:21 PMArieh Markel
12/05/2024, 1:22 PMmockServer.stubFor(
put(urlPathTemplate("/v1/defs/{name}"))
.willReturn(putResp)
.withServeEventListener(
"recordState",
Parameters.from(
Map.of(
"context",
"{{request.path}}",
"state",
captureValue(
Map.of(
"statePayload",
"{{{jsonPath response.body '$'}}}"))))));
The body is not extracted and the Map just has the stringArieh Markel
12/05/2024, 2:06 PMReceiver class org.wiremock.extensions.state.extensions.StateHandlerbarHelper does not define or inherit an implementation of the resolved method 'abstract java.lang.Object apply(java.lang.Object, wiremock.com.github.jknack.handlebars.Options)' of interface wiremock.com.github.jknack.handlebars.Helper.
Not clear what it means, what causes it and how to resolve.Arieh Markel
12/05/2024, 2:45 PMArieh Markel
12/05/2024, 2:46 PMDirk Bolte
12/05/2024, 3:35 PMArieh Markel
12/05/2024, 4:31 PMDirk Bolte
12/05/2024, 8:45 PM{name}
, you have to use request.pathSegments.[name]
(request.path
probably caused the error you saw)
• thus all contexts had to be: request.pathSegments.[name]
• the get stub doesn't need the mapper - this is only needed when you use withJsonBody
. For returning the plain input, using .withBody("{{{state context=request.pathSegments.[name] property='statePayload' }}}")))
was sufficient
the test still fails but just for the purpose on showing requests and responses.Arieh Markel
12/06/2024, 3:09 AM