vihar naik
vihar naik

Reputation: 17

What is the best practice to create a mock service with Citrus Automation Framework for multiple responses?

I've got Component Integration Test suite setup with Citrus Framework. In order to create a mock service for different components. I've been using simple mapping strategy with the help of XPathPayloadMappingKeyExtractor.

The challenge I've got is to create a multiple responses for different soap requests.

I've been struggling to understand the way it's responding. Any experienced person who can help me out on Citrus and Spring please ?

My Context file:

<citrus-ws:client id="ClientEndpoint"
                  request-url="http://localhost:8085/"/>




<citrus-ws:server id="BS_Customer_Information"
                  port="8085"
                  auto-start="true"/>

My Test Method:

 @CitrusTest
public void testingServer() {

    soap().client(ClientEndpoint)
            .send()
            .soapAction("urn:RetrieveAddressBookOP_01")
            .payload(new ClassPathResource("Requests/Sample1.xml"));



    soap().server(BS_Customer_Information)
            .receive()
            .soapAction("urn:RetrieveAddressBookOP_01");

    soap().server(BS_Customer_Information)
            .send()
            .payload(new ClassPathResource("AtomicResponses/Response1.xml"));


    soap().client(ClientEndpoint)
            .receive()
            .messageType(MessageType.XML);

}

Issue 1: My Soap Client times out and could not get the response

Question 1: Should the server response be parsed into Soap Env and Body ?

Question 2: Why Would it still call go to Channel Endpoint.inbound when I've already defined my response?

Console Log:

2521   DEBUG gEndpointInterceptor| Received SOAP request:
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<RetrieveAddressBookOP_01"/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

2527   DEBUG r.WebServiceEndpoint| Received SOAP request:
SOAPMESSAGE [payload: <?xml version="1.0" encoding="UTF-8"?><au:RetrieveAddressBookOP_01 xmlns:au="au.com.teysau.dataservice"/>][headers: {citrus_message_id=e1311140-6ee3-415a-815e-0d162cbc03c1, citrus_message_timestamp=1490649843807, citrus_soap_action=urn:RetrieveAddressBookOP_01, citrus_http_request_uri=/, citrus_http_context_path=, citrus_http_query_params=, citrus_http_method=POST}][header-data: [<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>]][attachments: []]
2527   DEBUG annelEndpointAdapter| Forwarding request to message channel ...
2527   DEBUG t.TestContextFactory| Created new test context - using global variables: '{}'
2527   DEBUG ltCorrelationManager| Saving correlation key for 'citrus_message_correlator_ChannelEndpointAdapter:producer'
2527   DEBUG  context.TestContext| Setting variable: citrus_message_correlator_ChannelEndpointAdapter:producer with value: 'citrus_message_id = 'e1311140-6ee3-415a-815e-0d162cbc03c1''
2527   DEBUG .ChannelSyncProducer| Sending message to channel: 'BS_Customer_Information.inbound'
2527   DEBUG .ChannelSyncProducer| Message to send is:
SOAPMESSAGE [payload: <?xml version="1.0" encoding="UTF-8"?><RetrieveAddressBookOP_01"/>][headers: {citrus_message_id=e1311140-6ee3-415a-815e-0d162cbc03c1, citrus_message_timestamp=1490649843807, citrus_soap_action=urn:RetrieveAddressBookOP_01, citrus_http_request_uri=/, citrus_http_context_path=, citrus_http_query_params=, citrus_http_method=POST}][header-data: [<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>]][attachments: []]
2527   INFO  .ChannelSyncProducer| Message was sent to channel: 'BS_Customer_Information.inbound'
3539   WARN  annelEndpointAdapter| Reply timed out after 1000ms. Did not receive reply message on reply channel
3540   DEBUG annelEndpointAdapter| Did not receive reply message - no response is simulated
3540   DEBUG r.WebServiceEndpoint| No reply message from endpoint adapter 'com.consol.citrus.channel.ChannelEndpointAdapter@6dbd0a41'
3540   WARN  r.WebServiceEndpoint| No SOAP response for calling client
3542   DEBUG ageDispatcherServlet| Successfully completed request
3546   DEBUG        server.Server| RESPONSE /  202 handled=true
3546   DEBUG ver.HttpChannelState| HttpChannelState@244a4722{s=DISPATCHED i=true a=null} unhandle DISPATCHED
3553   DEBUG erver.HttpConnection| org.eclipse.jetty.server.HttpConnection$SendCallback@27d2cb2e[PROCESSING][i=ResponseInfo{HTTP/1.1 202 null,-1,false},cb=org.eclipse.jetty.server.HttpChannel$CommitCallback@2f1ea019] generate: NEED_HEADER (null,[p=0,l=0,c=0,r=0],true)@START
3556   DEBUG erver.HttpConnection| org.eclipse.jetty.server.HttpConnection$SendCallback@27d2cb2e[PROCESSING][i=ResponseInfo{HTTP/1.1 202 null,-1,false},cb=org.eclipse.jetty.server.HttpChannel$CommitCallback@2f1ea019] generate: FLUSH ([p=0,l=114,c=8192,r=114],[p=0,l=0,c=0,r=0],true)@COMPLETING
3556   DEBUG      io.WriteFlusher| write: WriteFlusher@76f08437{IDLE} [HeapByteBuffer@2c34f7c0[p=0,l=114,c=8192,r=114]={<<<HTTP/1.1 202 Acce....v20160210)\r\n\r\n>>>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}]
3557   DEBUG      io.WriteFlusher| update WriteFlusher@76f08437{WRITING}:IDLE-->WRITING
3562   INFO  ent.WebServiceClient| SOAP message was sent to endpoint: 'http://localhost:8085/'
3562   INFO  ent.WebServiceClient| Received no SOAP response from endpoint: 'http://localhost:8085/'
3562   INFO         citrus.Citrus| 
3562   DEBUG        citrus.Citrus| TEST STEP 1/4 SUCCESS
3562   INFO         citrus.Citrus| 
3562   DEBUG        citrus.Citrus| TEST STEP 2/4: receive
3563   DEBUG   io.ChannelEndPoint| flushed 114 SelectChannelEndPoint@1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,W,1092/30000,HttpConnection}{io=0,kio=0,kro=1}
3566   DEBUG nnel.ChannelConsumer| Receiving message from: BS_Customer_Information.inbound
3567   DEBUG nnel.ChannelConsumer| Received message from: BS_Customer_Information.inbound
3567   DEBUG ltCorrelationManager| Saving correlation key for 'citrus_message_correlator_BS_Customer_Information:consumer'
3567   DEBUG  context.TestContext| Setting variable: citrus_message_correlator_BS_Customer_Information:consumer with value: 'citrus_message_id = 'e1311140-6ee3-415a-815e-0d162cbc03c1''
3567   DEBUG ltCorrelationManager| Saving correlated object for 'citrus_message_id = 'e1311140-6ee3-415a-815e-0d162cbc03c1''
3567   DEBUG ageValidatorRegistry| Found 3 message validators for message type: XML
3567   DEBUG mXmlMessageValidator| Start message validation ...
3567   DEBUG mXmlMessageValidator| Start XML message validation
3569   DEBUG mXmlMessageValidator| Starting XML schema validation ...
3569   WARN  mXmlMessageValidator| Neither schema instance nor schema repository defined - skipping XML schema validation
3569   INFO  mXmlMessageValidator| XML message validation successful: All values OK
3569   DEBUG mXmlMessageValidator| Start message header validation ...
3570   DEBUG      io.WriteFlusher| update WriteFlusher@76f08437{IDLE}:WRITING-->IDLE
3570   DEBUG erver.HttpConnection| org.eclipse.jetty.server.HttpConnection$SendCallback@27d2cb2e[PROCESSING][i=ResponseInfo{HTTP/1.1 202 null,-1,false},cb=org.eclipse.jetty.server.HttpChannel$CommitCallback@2f1ea019] generate: DONE ([p=114,l=114,c=8192,r=0],[p=0,l=0,c=0,r=0],true)@END
3570   DEBUG mXmlMessageValidator| Validating header element: citrus_soap_action='urn:RetrieveAddressBookOP_01': OK.
3571   INFO  mXmlMessageValidator| Message header validation successful: All properties OK
3571   INFO  mXmlMessageValidator| Message validation successful: All values OK
3571   INFO         citrus.Citrus| 
3571   DEBUG        citrus.Citrus| TEST STEP 2/4 SUCCESS
3571   INFO         citrus.Citrus| 
3571   DEBUG        citrus.Citrus| TEST STEP 3/4: send
3571   DEBUG ngCorrelationManager| Get correlation key for 'citrus_message_correlator_BS_Customer_Information:consumer'
3571   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = 'e1311140-6ee3-415a-815e-0d162cbc03c1''
3571   DEBUG .ChannelSyncConsumer| Sending message to reply channel: 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@66f66866'
3571   DEBUG .ChannelSyncConsumer| Message to send is:
SOAPMESSAGE [payload: <AddressBook>
            <Address>
                <Address_Number>14</Address_Number>
                <Long_Address>Willis Street</Long_Address>
                <Tax_ID>7987398</Tax_ID>
                <Alpha_Name>what is alpha</Alpha_Name>
                <Code>UN_</Code>
                <Mailing_Name>James Bond</Mailing_Name>
                <Address_Line1>take the first part of the long address</Address_Line1>
                <Address_Line2>You may take the second part not</Address_Line2>
                <Postal_Code>8900</Postal_Code>
                <City>WLN</City>
                <Country>NZ</Country>
                <Prefix>233</Prefix>
                <Phone_Number>025364</Phone_Number>
                <Prefix_2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
                <Phone_Number2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
                <userID>s3b9d</userID>
                <BatchNumber>jkdhj59</BatchNumber>
                <Tansaction_Number>jkd3j29</Tansaction_Number>
                <Line_Number>291597</Line_Number>
            </Address>
        </AddressBook>][headers: {citrus_message_id=fd946a46-f67a-405d-b118-b1b6b3d562c1, citrus_message_timestamp=1490649843443}][attachments: []]
3572   WARN  emporaryReplyChannel| Reply message received but the receiving thread has exited due to a timeout:GenericMessage [payload=SOAPMESSAGE [payload: <AddressBook>
            <Address>
                <Address_Number>14</Address_Number>
                <Long_Address>Willis Street</Long_Address>
                <Tax_ID>7987398</Tax_ID>
                <Alpha_Name>what is alpha</Alpha_Name>
                <Code>UN_</Code>
                <Mailing_Name>James Bond</Mailing_Name>
                <Address_Line1>take the first part of the long address</Address_Line1>
                <Address_Line2>You may take the second part not</Address_Line2>
                <Postal_Code>8900</Postal_Code>
                <City>WLN</City>
                <Country>NZ</Country>
                <Prefix>233</Prefix>
                <Phone_Number>025364</Phone_Number>
                <Prefix_2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
                <Phone_Number2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
                <userID>s3b9d</userID>
                <BatchNumber>jkdhj59</BatchNumber>
                <Tansaction_Number>jkd3j29</Tansaction_Number>
                <Line_Number>291597</Line_Number>
            </Address>
        </AddressBook>][headers: {citrus_message_id=fd946a46-f67a-405d-b118-b1b6b3d562c1, citrus_message_timestamp=1490649843443}][attachments: []], headers={id=cfc4eeaa-eac8-8f00-2f45-2e3fcb16fdb6, timestamp=1490649844854}]
3572   INFO  .ChannelSyncConsumer| Message was sent to reply channel: 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@66f66866'
3572   INFO         citrus.Citrus| 
3572   DEBUG        citrus.Citrus| TEST STEP 3/4 SUCCESS
3572   INFO         citrus.Citrus| 
3572   DEBUG        citrus.Citrus| TEST STEP 4/4: receive
3572   DEBUG ngCorrelationManager| Get correlation key for 'citrus_message_correlator_ClientEndpoint'
3572   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
3572   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
3575   DEBUG      http.HttpParser| reset HttpParser{s=END,214 of 214}
3576   DEBUG      http.HttpParser| END --> START
3576   DEBUG   server.HttpChannel| HttpChannelOverHttp@4820529f{r=1,c=false,a=IDLE,uri=} handle exit, result COMPLETE
3576   DEBUG   io.ChannelEndPoint| filled 0 SelectChannelEndPoint@1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}
3576   DEBUG   io.ChannelEndPoint| filled 0 SelectChannelEndPoint@1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}
3576   DEBUG      http.HttpParser| parseNext s=START HeapByteBuffer@6b681750[p=0,l=0,c=16384,r=0]={<<<>>>POST / HTTP/1.1\r\n...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}
3576   DEBUG o.AbstractConnection| fillInterested HttpConnection@2c01adea[FILLING,SelectChannelEndPoint@1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},c=HttpChannelOverHttp@4820529f{r=1,c=false,a=IDLE,uri=}]
3576   DEBUG o.AbstractConnection| FILLING-->FILLING_FILL_INTERESTED HttpConnection@2c01adea[FILLING_FILL_INTERESTED,SelectChannelEndPoint@1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},c=HttpChannelOverHttp@4820529f{r=1,c=false,a=IDLE,uri=}]
3577   DEBUG o.AbstractConnection| FILLING_FILL_INTERESTED-->FILL_INTERESTED HttpConnection@2c01adea[FILL_INTERESTED,SelectChannelEndPoint@1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},c=HttpChannelOverHttp@4820529f{r=1,c=false,a=IDLE,uri=}]
3577   DEBUG electChannelEndPoint| Local interests updating 0 -> 1 for SelectChannelEndPoint@1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,R,-,0/30000,HttpConnection}{io=1,kio=0,kro=1}
3577   DEBUG   io.SelectorManager| Queued change org.eclipse.jetty.io.SelectChannelEndPoint$1@67e66c5c
3578   DEBUG   io.SelectorManager| Selector loop woken up from select, 0/1 selected
3578   DEBUG   io.SelectorManager| Running change org.eclipse.jetty.io.SelectChannelEndPoint$1@67e66c5c
3578   DEBUG electChannelEndPoint| Key interests updated 0 -> 1 on SelectChannelEndPoint@1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,R,-,1/30000,HttpConnection}{io=1,kio=1,kro=1}
3578   DEBUG   io.SelectorManager| Selector loop waiting on select
4072   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
4072   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
4573   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
4573   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
5073   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
5073   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
5574   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
5574   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
6075   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
6075   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
6575   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
6575   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
7075   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
7075   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
7576   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
7576   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
8076   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
8076   DEBUG   citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
8576   DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
8580   INFO   report.JIRAConsumer| Invoking JIRA API...
works.integration.jira.exceptions.ServiceBindingException: Missing Required Properties - SUMMARY, EXMESSAGE, DETAILEDEXCEPTION, PROJECT

Upvotes: 0

Views: 988

Answers (1)

Christoph Deppisch
Christoph Deppisch

Reputation: 2216

You have to add a fork(true) option to the first `soap().client().send()' action because the Http SOAP protocol is synchronous by nature. The first action in your test waits for a synchronous response and blocks the rest of the test case execution.

Obviously your test needs to receive some other messages before that client response with soap().server(). That is why you need to fork the client send action in the first place so the server actions can perform before the client response has arrived.

In general the SOAP components in Citrus automatically handle SOAP Envelope and SOAP body. So you just need to define the pure body content as payload. SOAP Envelope is added automatically.

Hope this is more clear now.

Upvotes: 1

Related Questions