I'm using Citrus for perform integration tests based on http requests. The test should perform steps as follows:
I've used Citrus httpClient to send the Post Request, and Citrus httpServer to exspose endpoints that the service will call using the callback url. So,
My test code is
parallel().actions(
sequential().actions(
// wait for callback
http(httpActionBuilder -> httpActionBuilder
.server(httpServer)
.receive()
.post("/api/callback")
.contentType("application/json;charset=UTF-8")
.accept("text/plain,application/json,application/*+json,*/*")
),
// callback response
http(httpActionBuilder -> httpActionBuilder
.server(httpServer)
.send()
.response(HttpStatus.OK)
.contentType("application/json")
)),
sequential().actions(
http(httpActionBuilder -> httpActionBuilder
.client(httpClient)
.send()
.post("/externalapi)
.payload("{" +
"\"ret\": \"OK\"" +
"}")
.messageType(MessageType.JSON)
.contentType(ContentType.APPLICATION_JSON.getMimeType())
),
http(httpActionBuilder -> httpActionBuilder
.client(httpClient)
.receive()
.response(HttpStatus.OK)
.messageType(MessageType.JSON)
.payload("{" +
"\"ret\": \"OK\"" +
"}")
)
)
);
My configurations
@Bean
public HttpClient httpClient() {
return CitrusEndpoints
.http()
.client()
.requestUrl("http://localhost:8282")
.build();
}
@Bean
public HttpServer httpServer() throws Exception {
return CitrusEndpoints.http()
.server()
.port(8080)
.endpointAdapter(dispatchingEndpointAdapter())
.timeout(300000)
.autoStart(true)
.build();
}
@Bean
public RequestDispatchingEndpointAdapter dispatchingEndpointAdapter() {
RequestDispatchingEndpointAdapter dispatchingEndpointAdapter = new RequestDispatchingEndpointAdapter();
dispatchingEndpointAdapter.setMappingKeyExtractor(mappingKeyExtractor());
dispatchingEndpointAdapter.setMappingStrategy(mappingStrategy());
return dispatchingEndpointAdapter;
}
@Bean
public HeaderMappingKeyExtractor mappingKeyExtractor() {
HeaderMappingKeyExtractor mappingKeyExtractor = new HeaderMappingKeyExtractor();
mappingKeyExtractor.setHeaderName(HttpMessageHeaders.HTTP_REQUEST_URI);
return mappingKeyExtractor;
}
@Bean
public SimpleMappingStrategy mappingStrategy() {
SimpleMappingStrategy mappingStrategy = new SimpleMappingStrategy();
Map<String, EndpointAdapter> mappings = new HashMap<>();
mappings.put("/api/callback", callbackResponseAdapter());
mappingStrategy.setAdapterMappings(mappings);
return mappingStrategy;
}
@Bean
public EndpointAdapter callbackResponseAdapter() {
StaticResponseEndpointAdapter endpointAdapter = new StaticResponseEndpointAdapter();
endpointAdapter.setMessagePayload("{" +
"\"ret\": \"OK\"," +
"}");
return endpointAdapter;
}
The httpClient steps works fine, but when I add the HttpServer I get this error
com.consol.citrus.exceptions.TestCaseFailedException: Unable to create endpoint for static endpoint adapter type 'class com.consol.citrus.endpoint.adapter.RequestDispatchingEndpointAdapter'
In your http-server configuration you are using both static request dispatcher and test action based dynamic response generation. This is not valid.
Please choose only one approach at a time. Either remove the request dispatcher configuration completely or do not try to receive the incoming requests in your test via receive/send action.
By the way the parallel-sequential blocks you are using may not be required. You can use fork=true option on the 1st client request instead and sequentially wait for the Http requests to arrive. This should simplify the test a lot.