SOAP call to a webservice with Talend for ESB and SOAPUI - web-services

I query to a webservice with this operation:
public schema.cupservices.Output callService(
#WebParam(partName = "inputMessage", name = "inputMessage", targetNamespace = "http://schema/cupServices") schema.cupservices.Input inputMessage);
inputMessage is of a type "Input":
public abstract class Input {
#XmlElement(required = true)
protected LoginData loginData;
public LoginData getLoginData() {
return loginData;
}
public void setLoginData(LoginData value) {
this.loginData = value;
}
}
when I try to call the service on Talend using the TSOAP component and with SOAPUI, both take as input:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cup="http://schema/cupServices">
<soapenv:Header/>
<soapenv:Body>
<cup:inputMessage>
<cup:loginData>
<cup:username>user</cup:username>
<cup:password>123</cup:password>
</cup:loginData>
</cup:inputMessage>
</soapenv:Body>
</soapenv:Envelope>
I get this error:
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>javax.xml.bind.UnmarshalException
- with linked exception:
[javax.xml.bind.UnmarshalException: Unable to create an instance of schema.cupservices.Input
- with linked exception:
[java.lang.InstantiationException]]</faultstring>
I know that Input is an abstract class, but the wsdl of the webservice is set in this way...
How can I resolve this problem?
Thanks

Related

com.sun.xml.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?

I am consuming SOAP service where sending request to soap url and getting the response. But when i try to connect using WebServiceTemplate getting a nested exception as
com.sun.xml.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
Below is the code where i am sending the request to soap client
soapClient.sendEmail(request); - From the service to soap client
Below is the soap client code to connect and send the request
#Service
public class SoapClient {
#Autowired
private Jaxb2Marshaller marshaller;
private WebServiceTemplate template;
#Value("${email.url}")
String emailUrl;
#Value("${email.vaultQuery}")
String querytaken;
#Value("${email.valtQu}")
String queryp;
public MessageResponse sendEmail(MessageRequest request) {
template = new WebServiceTemplate(marshaller);
String plainCredentials = querytaken + ":" + queryp;
String base64Credentials = new String(Base64.encodeBase64(plainCredentials.getBytes()));
return (MessageResponse) template.marshalSendAndReceive(emailUrl, request,new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException {
TransportContext context = TransportContextHolder.getTransportContext();
HttpUrlConnection connection = (HttpUrlConnection) context.getConnection();
connection.getConnection().setRequestProperty("Authorization", "Basic " + base64Credentials);
}
});
}
}
Can anyone help me out for my issue

invoking wsdl operations through c#

I need to create a win forms app in VS 2013, which will take a wsdl file as a webReference. It will invoke an wsdl:operation "Init" which will send the following xml to the web service :
The Wsdl contains the operation:
<wsdl:operation name="Init">
<wsdl:input message="wl:InitRequest"/>
<wsdl:output message="wl:InitResponse"/>
</wsdl:operation>
The Init SOAP xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.asdfgh.org/lala/log">
<soapenv:Header/>
<soapenv:Body>
<web:Init>
<web:Phase>`TST`</web:Phase>
</web:Init>
</soapenv:Body>
</soapenv:Envelope>
It will send a response back InitResponse:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.asdfgh.org/lala/log">
<soapenv:Header/>
<soapenv:Body>
<wl:InitResponse xmlns:wl="http://www.asdfgh.org/lala/log">
<Data>
<NUMBER>1234</NUMBER>
<TEXT1>ABCDEF</TEXT1>
<TEXT2>QWERTY</TEXT2>
</Data>
</wl:InitResponse>
</soapenv:Body>
</soapenv:Envelope>
How to I read the response back and show the ouput in a MessageBox.Show();
Below is the class formed by the wsdl on the Init.
public partial class Init {
private string phaseField;
/// <remarks/>
public string Phase {
get {
return this.phaseField;
}
set {
this.phaseField = value;
}
}
}
Below is the class formed by the wsdl on InitResponse(funny thing is, it did not create any class named InitResponse. It has created InitResponseData -- I wonder why)
public partial class InitDSDResponseData {
private string NUMBERField;
private string TEXT1Field;
private string TEXT2Field;
/// <remarks/>
public string NUMBER {
get {
return this.NUMBERField;
}
set {
this.NUMBERField = value;
}
}
/// <remarks/>
public string TEXT1 {
get {
return this.TEXT1Field;
}
set {
this.TEXT1Field = value;
}
}
/// <remarks/>
public string TEXT2 {
get {
return this.TEXT2Field;
}
set {
this.TEXT2Field = value;
}
}
}
On a button click event, I want to show the response xml in a Message Box as a string. How should I proceed? How do I invoke the Init operation through c#?

Retrieving credentials from SOAP header

This a sample SOAP request I'm sending to a WS which is deployed in WAS 8.5
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xmlns.scania.com/logistics/schema/transport/v1">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-37" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
password
</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<v1:TransportInformationRequest>
<!--1 or more repetitions:-->
<v1:ChassisNumber>2105909</v1:ChassisNumber>
</v1:TransportInformationRequest>
</soapenv:Body>
</soapenv:Envelope>
What I want is to retrieve the username and password sent in the above request. I flipped through the Java EE api but couldn't find the correct way to do the same. I have written a painful code in the SOAPHandler as below :
#Override
public boolean handleMessage(SOAPMessageContext context) {
// TODO Auto-generated method stub
Boolean isOutbound = (Boolean) context
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
log.info("In TransportHandler.handleMessage(...) " + isOutbound);
if (!isOutbound) {
SOAPMessage soapMsg = context.getMessage();
SOAPEnvelope soapEnv;
try {
soapEnv = soapMsg.getSOAPPart().getEnvelope();
SOAPHeader soapHeader = soapEnv.getHeader();
Iterator<SOAPElement> securityHeaderElements = soapHeader
.getChildElements(new QName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"Security", "wsse"));
if (securityHeaderElements.hasNext()) {
SOAPElement securityHeaderElement = securityHeaderElements
.next();
log.info("*****securityHeaderElement : "
+ securityHeaderElement + " type is "
+ securityHeaderElement.getClass().getName());
Iterator<Node> securityHeaderChildren = securityHeaderElement
.getChildElements();
while (securityHeaderChildren.hasNext()) {
Node securityElement = securityHeaderChildren.next();
log.info("*****securityElement : "
+ securityElement.getClass().getName());
if (securityElement instanceof com.ibm.ws.webservices.engine.xmlsoap.SOAPElement) {
com.ibm.ws.webservices.engine.xmlsoap.SOAPElement securitySOAPElement = (com.ibm.ws.webservices.engine.xmlsoap.SOAPElement) securityElement;
log.info("*****securitySOAPElement "
+ securitySOAPElement);
Iterator<Node> securitySOAPElementChildren = securitySOAPElement
.getChildElements();
while (securitySOAPElementChildren.hasNext()) {
Node securitySOAPElementChild = securitySOAPElementChildren
.next();
log.info("*****securitySOAPElementChild : "
+ securitySOAPElementChild);
if (securitySOAPElementChild instanceof com.ibm.ws.webservices.engine.xmlsoap.SOAPElement) {
com.ibm.ws.webservices.engine.xmlsoap.SOAPElement securitySOAPChildElement = (com.ibm.ws.webservices.engine.xmlsoap.SOAPElement) securitySOAPElementChild;
log.info("*****securitySOAPChildElement "
+ securitySOAPChildElement);
}
}
}
}
}
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
log.info("Returning from TransportHandler.handleMessage(...)");
return true;
}
What is the efficient way to get the username and password ?

Issue invoking web service within websphere 6.1 environment

I'm trying to invoke a SOAP web service from within WebSphere 6.1. I can run the code fine using Apache Tomcat 6.0.36 runtime. However, with WebSphere 6.1, I get the following error:
Jan 5, 2015 7:19:23 PM com.ibm.ws.ssl.config.SSLConfigManager INFO:ssl.disable.url.hostname.verification.CWPKI0027I
Jan 5, 2015 7:19:24 PM com.ibm.ws.channel.framework.impl.WSChannelFrameworkImpl AUDIT: chain.started
Jan 5, 2015 7:19:25 PM com.ibm.ws.webservices.engine.PivotHandlerWrapper invoke WARNING:
WSWS3734W: Warning: Exception caught from invocation to com.ibm.ws.webservices.engine.transport.http.HTTPSender:
WebServicesFault faultCode:
HTTP faultString: ( 401 ) Unauthorized faultActor: http://server.customer.com:80
faultDetail: null:
WSWS3192E: Error: return code: ( 401 ) Unauthorized
Here's the code I'm running, which works fine in Apache Tomcat:
public class Test {
public void submitOrder()
{
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
String url = "http://server.customer.com/serviceEndpoint";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
// Process the SOAP Response
printSOAPResponse(soapResponse);
soapConnection.close();
} catch (Exception e) {
System.err.println("Error occurred while sending SOAP Request to Server");
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
MimeHeaders hd = soapMessage.getMimeHeaders();
String username = "xxxxx";
String password = "xxxxx";
byte [] auth = (username+":"+password).getBytes();
String authorization = new String ( Base64.encodeBase64(auth) );
System.out.println ( "authorization = " + authorization );
hd.addHeader("Authorization", "Basic " + authorization);
SOAPPart soapPart = soapMessage.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement ordersElem = soapBody.addChildElement("Orders");
// Need to add two attributes to this node!
SOAPElement orderElem = ordersElem.addChildElement("Order");
Name codeAttributeName = envelope.createName("code");
orderElem.addAttribute(codeAttributeName, "00001");
Name timeAttributeName = envelope.createName("time");
orderElem.addAttribute(timeAttributeName, "2015-01-04 12:00:00 PM");
SOAPElement salesOrderConfElem = orderElem.addChildElement("SalesOrderConfirmationCode");
salesOrderConfElem.addTextNode("16041");
SOAPElement statusElem = orderElem.addChildElement("Status");
Name statusCodeAttributeName = envelope.createName("code");
statusElem.addAttribute(statusCodeAttributeName, "COMPLETE");
SOAPElement entriesElem = orderElem.addChildElement("Entries");
SOAPElement entryElem = entriesElem.addChildElement("Entry");
SOAPElement entryNumElem = entryElem.addChildElement("EntryNumber");
entryNumElem.addTextNode("1");
SOAPElement productElem = entryElem.addChildElement("ProductCode");
productElem.addTextNode("738053571");
SOAPElement qtyElem = entryElem.addChildElement("Quantity");
qtyElem.addTextNode("1");
SOAPElement shippedElem = entryElem.addChildElement("Shipped");
shippedElem.addTextNode("1");
SOAPElement backOrderElem = entryElem.addChildElement("Backordered");
backOrderElem.addTextNode("1");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", "http://sap.com/xi/WebService/soap1.1");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
/**
* Method used to print the SOAP Response
*/
private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Source sourceContent = soapResponse.getSOAPPart().getContent();
System.out.print("\nResponse SOAP Message = ");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
}
/**
* #param args
*/
public static void main(String[] args) {
Test t = new Test();
t.submitOrder();
}
}
CORRECTION: the SOAP envelopes being created by Tomcat and WebSphere are not the same. Tomcat, using Java 1.6, creates the following:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<Orders>
while WebSphere, using IBM's version of 1.5, creates the following:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<Orders>
How would I get WebSphere to create the same SOAP envelop as Tomcat?

JBoss 7.1.1 Webservice programatic JAAS authentication

I have a simple POJO as a webservice that is mapped to, lets say /public/authenticate :
WebService
#SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public class AuthWS{
#WebMethod
public boolean doAuthenticate(String securityToken) {
....
}
}
This webservice doesn't requre authentication and is not a protected resource.
I do have other private webservices mapped to path : /private/ws/*;
For the moment I use a security-domain that has a Database login module setup. It works fine, but user first needs to authenticate trought a web form based that makes a post request to /j_security_check. Only after this step user can use other private webservices.
I want to perform a programatically authentication after client calls this doAuthenticate method. So that client to be able to invoke other /private/ws/* webservice methods.
I'll type what I want to achieve:
#WebService
#SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public class AuthWS{
#WebMethod
public boolean doAuthenticate(String securityToken) {
SomeSecurityManager manager= SomeSecurityManager.getDefaultManager()
Map<String,Object> map = new HashMap<String, Object>();
map.put("MY_CUSTOM_SECURITY_TOKEN",securityToken);
manager.doLogin(map);
// after webservice method returns, client should now be able to invoke other private webservice
// this means that the manager should associate with this session an authenticated user.
// in order that authorization to work.
}
}
And my CustomLoginModule :
class CustomLogModule implements LoginModule {
...
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
// store what's needed
}
public boolean login(){
// get securityToken send from the SomeSecurityManager and validate it.
// get user information from that token and store into Subject object.
}
}
And in my CustomLoginModule that implements JAAS LoginModule to check that securityToken with a custom logic, verify if it right signed with a public key for example. That securityToken contains information about principal.
If you need more details, feel free to ask.
Thanks.
EDITED
1.) Created custom-login-module.jar together with module.xml
<module xmlns="urn:jboss:module:1.1" name="custom.login.module">
<resources>
<resource-root path="custom-login-module.jar"/>
</resources>
<dependencies>
<module name="org.picketbox"/>
<module name="javax.api"/>
<module name="org.slf4j"/>
</dependencies>
</module>
2.) Added custom-login-module.jar and module.xml into jboss-as-7.1.1.Final\modules\custom\login\module
3.) custom-login-module.jar contains :
public class CustomCallbackHandler implements CallbackHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomCallbackHandler.class);
private String token;
public CustomCallbackHandler(String token) {
this.token= token;
}
public String getToken() {
return token;
}
#Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof TokenCallback) {
((TokenCallback) callback).setToken(token);
}
}
}
}
public class TokenCallback implements Callback {
private static final Logger LOGGER = LoggerFactory.getLogger(TokenCallback.class);
private String token;
public TokenCallback() {
}
public String getToken() {
return token;
}
public void setToken(String token) {
LOGGER.info("Setting token = " + token);
this.token = token;
}
}
public class CustomLoginModule extends AbstractServerLoginModule {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomLoginModule.class);
#Override
public boolean login() throws LoginException {
LOGGER.info("Doing login()");
boolean login = super.login();
super.loginOk = true;
return login;
}
#Override
protected Principal getIdentity() {
return new UserPrincipal("some user");
}
#Override
protected Group[] getRoleSets() throws LoginException {
return new Group[]{new MyGroup()}; // that and has name 'dummy'
}
}
These are only dummy implementations.
My web application is deployed from within a .war archive. And it Contains following :
jboss-web.xml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE jboss-web
PUBLIC -//JBoss//DTD Web Application 2.3V2//EN
http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd>
<jboss-web>
<security-domain>custom-auth</security-domain>
</jboss-web>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>WebApp</display-name>
<session-config>
<session-timeout>120</session-timeout>
</session-config>
<security-constraint>
<web-resource-collection>
<web-resource-name>All resources</web-resource-name>
<description>Protects all private resources</description>
<url-pattern>/private/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>dummy</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-role>
<role-name>dummy</role-name>
</security-role>
<servlet>
<servlet-name>Private</servlet-name>
<servlet-class>com.company.private.PrivateWs</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Private</servlet-name>
<url-pattern>/private/PrivateWs</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>AuthWS</servlet-name>
<servlet-class>com.company.auth.AuthWS</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AuthWS</servlet-name>
<url-pattern>/AuthWS</url-pattern>
</servlet-mapping>
</web-app>
#WebService
#SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public class AuthWS{
private static final Logger LOGGER = LoggerFactory.getLogger(AuthWS.class);
#WebMethod
public boolean doAuthenticate(String token) {
tryProgrammaticLogin(token);
return true;
}
private void tryProgrammaticLogin(String token) {
LoginContext loginContext = null;
try {
loginContext = new LoginContext("custom-auth", new CustomCallbackHandler(token));
loginContext.login();
} catch (LoginException e) {
LOGGER.info("Some problem occured when trying to custom login.", e);
}
}
}
The call to doAuthenticate from my ws client works but the problem is that after try ProgrammaticLogin an exception occurs. And the PrivateWS is not accesible by client.
17:33:40,901 INFO [com.mycompany.AuthWS] (http--0.0.0.0-8080-1) Some problem occured when trying to custom login.: javax.security.auth.login.LoginException: Login Failure: all modules ignored
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:921) [rt.jar:1.6.0_26]
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186) [rt.jar:1.6.0_26]
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683) [rt.jar:1.6.0_26]
at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.6.0_26]
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) [rt.jar:1.6.0_26]
at javax.security.auth.login.LoginContext.login(LoginContext.java:579) [rt.jar:1.6.0_26]
standalone.xml from jboss configuration directory contains:
<security-domain name="custom-auth">
<authentication>
<login-module code="com.mycompany.CustomLoginModule" flag="required" module="custom.login.module"/>
</authentication>
</security-domain>
Please tell me if the way of doing authentication with creating a new LoginContext object is the right way of doing. I can't understand why this problem occurs.