New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAXParseException when sending SOAP request with empty payload or header #439

Closed
ceazy79 opened this Issue Jul 26, 2018 · 2 comments

Comments

Projects
None yet
2 participants
@ceazy79
Copy link
Contributor

ceazy79 commented Jul 26, 2018

Citrus Version

Tested with 2.7.4 and 2.7.6

Expected behavior

Calling the send method for a SOAP request with empty body or header sends the request and the test is successful.

The action call in the test looks like this (see also attached sources):
soap(b -> b.client(CLIENT_ENDPOINT).send().payload(""));

Actual behavior

Calling the send method for a SOAP request with empty body or header throws a SAXParseException, does not send the request and fails the test.

Leaving the header empty results in a stacktrace that looks nearly the same except for part "...SOAP body..." :-)

The stacktrace from the exception:

com.consol.citrus.exceptions.TestCaseFailedException: Failed to write SOAP body payload

	at com.consol.citrus.dsl.testng.TestNGCitrusTest.invokeTestMethod(TestNGCitrusTest.java:142)
	at com.consol.citrus.dsl.testng.TestNGCitrusTest.run(TestNGCitrusTest.java:110)
	at com.consol.citrus.dsl.testng.TestNGCitrusTest.run(TestNGCitrusTest.java:56)
	at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:221)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:657)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
	at org.testng.TestRunner.privateRun(TestRunner.java:744)
	at org.testng.TestRunner.run(TestRunner.java:602)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
	at org.testng.SuiteRunner.run(SuiteRunner.java:289)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
	at org.testng.TestNG.runSuites(TestNG.java:1144)
	at org.testng.TestNG.run(TestNG.java:1115)
	at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
	at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: com.consol.citrus.exceptions.TestCaseFailedException: Failed to write SOAP body payload
	at com.consol.citrus.TestCase.executeAction(TestCase.java:241)
	at com.consol.citrus.dsl.runner.DefaultTestRunner.run(DefaultTestRunner.java:198)
	at com.consol.citrus.dsl.runner.DefaultTestRunner.soap(DefaultTestRunner.java:549)
	at com.consol.citrus.dsl.testng.TestNGCitrusTestRunner.soap(TestNGCitrusTestRunner.java:375)
	at citrus.soap.test.SoapTest.testSoapRequest(SoapTest.java:32)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:216)
	at com.consol.citrus.dsl.testng.TestNGCitrusTest.invokeTestMethod(TestNGCitrusTest.java:139)
	... 22 more
Caused by: com.consol.citrus.exceptions.CitrusRuntimeException: Failed to write SOAP body payload
	at com.consol.citrus.ws.message.converter.SoapMessageConverter.convertOutbound(SoapMessageConverter.java:98)
	at com.consol.citrus.ws.message.converter.SoapMessageConverter.convertOutbound(SoapMessageConverter.java:65)
	at com.consol.citrus.ws.message.callback.SoapRequestMessageCallback.doWithMessage(SoapRequestMessageCallback.java:62)
	at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:590)
	at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
	at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:531)
	at com.consol.citrus.ws.client.WebServiceClient.send(WebServiceClient.java:126)
	at com.consol.citrus.actions.SendMessageAction.doExecute(SendMessageAction.java:125)
	at com.consol.citrus.actions.AbstractTestAction.execute(AbstractTestAction.java:46)
	at com.consol.citrus.dsl.actions.DelegatingTestAction.doExecute(DelegatingTestAction.java:54)
	at com.consol.citrus.actions.AbstractTestAction.execute(AbstractTestAction.java:46)
	at com.consol.citrus.TestCase.executeAction(TestCase.java:234)
	... 32 more
Caused by: javax.xml.transform.TransformerException: org.xml.sax.SAXParseException; Premature end of file.
	at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:502)
	at com.consol.citrus.ws.message.converter.SoapMessageConverter.convertOutbound(SoapMessageConverter.java:96)
	... 43 more
Caused by: org.xml.sax.SAXParseException; Premature end of file.
	at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
	at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:485)
	... 44 more

Test case sample

I attached a test and Spring-Context configuration file.

SoapTest.zip

Temp. Workaround (maybe fix?)

Without deeper knowledge of the internals of the framework I found a workaround by modifying a Citrus class (using the 2.7.6 sources):
in com.consol.citrus.ws.message.converter.SoapMessageConverter
I changed the block beginnig at line 94 to

String payload = soapMessage.getPayload(String.class));
if (payload != null && !payload.isEmpty()) {
    try {
        Transformer transformer = transformerFactory.newTransformer();
        transformer.transform(new StringSource(payload, soapRequest.getSoapBody().getPayloadResult());
    } catch (TransformerException e) {
        throw new CitrusRuntimeException("Failed to write SOAP body payload", e);
    }
}

The problem is I'm not sure if this leads to problems at other places in the code or other usecases.

@svettwer

This comment has been minimized.

Copy link
Member

svettwer commented Jul 30, 2018

Hi @ceazy79!

Thx for the detailed description! This is always very helpful.
I haven't checked whether your provided fix would have worked, so maybe you could fork citrus, apply your changes and provide a PR? This would be great!

BR,
Sven

@svettwer svettwer added TO REVIEW and removed READY labels Sep 13, 2018

svettwer added a commit that referenced this issue Sep 27, 2018

svettwer added a commit that referenced this issue Sep 27, 2018

svettwer added a commit that referenced this issue Sep 27, 2018

svettwer added a commit that referenced this issue Sep 27, 2018

svettwer added a commit that referenced this issue Sep 27, 2018

svettwer added a commit that referenced this issue Sep 27, 2018

@svettwer

This comment has been minimized.

Copy link
Member

svettwer commented Sep 27, 2018

Closed with eb2e1ec

@svettwer svettwer closed this Sep 27, 2018

@svettwer svettwer added this to the v2.7.8 milestone Sep 27, 2018

@svettwer svettwer modified the milestones: v2.7.8, v2.8 Oct 12, 2018

@svettwer svettwer removed the TO REVIEW label Jan 28, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment