EDIT: It seems that Domino is not sending the security header along with the Soap request. I had access to the log of the service provider and here is what I found out:
2016-06-09 10:27:01 EDT [MED.0050.0239D] Substituted fault reason = Mediator encountered an error:Incoming request does not contain the Authorization header. This service requires the HTTP Basic Authentication token to be present! while executing operation:retraitEquipementServMoCA service:equipementMoCA at time:10:27:01 on date:2016-06-09. The client ip was:10.150.1.34. The current user:Default. The consumer application:null
I have to modify an existing Lotus Notes app that consumes web services. It is all woirking nicely in prod, but in DEV, we have a new WSDL and the end point is also a DEV server.
I have to modify the lines where the locator, stub and service are defined to fit with the new WSDL (port name changed), and I think I've done this right.
I can't figure out what is going on. I read that Domino supports SOAP 1.1 only, so I modifed the WSDL to use soap 1.1 and not 1.2, but I still et the 401 error.
I have rebuilt the web consumer in Domino about 3-4 times now, from the WSDL, and I can't stop getting the 401 error. Here is a part of the log:
2016-06-09 08:26:25 HTTP JVM: DEBUG endpoint: http://bsiesglba1.int.videotron.com:5555/ws/equipementMoCA
2016-06-09 08:26:25 HTTP JVM: DEBUG portname: equipementMoCA.equipementMoCAsoaphttp
2016-06-09 08:26:25 HTTP JVM: ==DEBUG==
2016-06-09 08:26:25 HTTP JVM: URL: http://bsiesglba1.int.videotron.com:5555/ws/equipementMoCA
2016-06-09 08:26:25 HTTP JVM: User: :
2016-06-09 08:26:25 HTTP JVM: Erreur MoCa : Agent MoCaRequest
2016-06-09 08:26:25 HTTP JVM: WebServiceEngineFault
2016-06-09 08:26:25 HTTP JVM: faultCode: {http://www.lotus.com/domino/ws/}HTTP
2016-06-09 08:26:25 HTTP JVM: faultSubcode:
2016-06-09 08:26:25 HTTP JVM: faultString: (401) 401
2016-06-09 08:26:25 HTTP JVM: faultActor:
2016-06-09 08:26:25 HTTP JVM: faultNode:
2016-06-09 08:26:25 HTTP JVM: faultDetail:
2016-06-09 08:26:25 HTTP JVM: {}string:
2016-06-09 08:26:25 HTTP JVM: (401) 401
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.transport.http.HTTPSender.readFromSocket(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.transport.http.HTTPSender.invoke(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.strategies.InvocationStrategy.visit(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.SimpleChain.doVisiting(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.SimpleChain.invoke(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.client.AxisClient.invoke(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.client.Call.invokeEngine(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.client.Call.invoke(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.client.Call.invoke(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.client.Call.invoke(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.axis.client.Call.invoke(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.websvc.client.Call.invoke(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at com.videotron.www.MoCA.gestionEquipement.ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub.retraitEquipementServMoCA(ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub.java:20)
2016-06-09 08:26:25 HTTP JVM: at com.videotron.factory.equipementMoCaFactory.WSClientFactory.wsRemoveEquipment(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at MoCaRequest.NotesMain(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.AgentBase.runNotes(Unknown Source)
2016-06-09 08:26:25 HTTP JVM: at lotus.domino.NotesThread.run(Unknown Source)
Here is the WSDL:
<wsdl:definitions name="equipementMoCA" targetNamespace="http://www.videotron.com/MoCA/gestionEquipement" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:tns="http://www.videotron.com/MoCA/gestionEquipement" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/">
<wsdl:documentation/>
<wsdl:types>
<xsd:schema targetNamespace="http://www.videotron.com/MoCA/gestionEquipement">
<xsd:complexType name="retraitEquipementServMoCA">
<xsd:sequence>
<xsd:element name="noCompteClient" nillable="true" type="xsd:string"/>
<xsd:element name="noSerie" nillable="true" type="xsd:string"/>
<xsd:element name="typeAppareil" nillable="true" type="xsd:string"/>
<xsd:element name="systemeSource" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="cErrorDefRec">
<xsd:sequence>
<xsd:element name="errorNb" nillable="true" type="xsd:string"/>
<xsd:element name="errorText" nillable="true" type="xsd:string"/>
<xsd:element name="severity" nillable="true" type="xsd:string"/>
<xsd:element name="errorType" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ajoutEquipementServMoCA">
<xsd:sequence>
<xsd:element name="noCompteClient" nillable="true" type="xsd:string"/>
<xsd:element name="noSerie" nillable="true" type="xsd:string"/>
<xsd:element name="typeAppareil" nillable="true" type="xsd:string"/>
<xsd:element name="systemeSource" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="ajoutEquipementServMoCA" type="tns:ajoutEquipementServMoCA"/>
<xsd:element name="cErrorDefRec" type="tns:cErrorDefRec"/>
<xsd:element name="retraitEquipementServMoCA" type="tns:retraitEquipementServMoCA"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="equipementMoCA_PortType_retraitEquipementServMoCA">
<wsdl:part name="parameters" element="tns:retraitEquipementServMoCA">
</wsdl:part>
</wsdl:message>
<wsdl:message name="equipementMoCA_PortType_ajoutEquipementServMoCA">
<wsdl:part name="parameters" element="tns:ajoutEquipementServMoCA">
</wsdl:part>
</wsdl:message>
<wsdl:message name="equipementMoCA_PortType_cErrorDefRec">
<wsdl:part name="parameters" element="tns:cErrorDefRec">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="equipementMoCA_PortType">
<wsdl:operation name="ajoutEquipementServMoCA">
<wsdl:input message="tns:equipementMoCA_PortType_ajoutEquipementServMoCA">
</wsdl:input>
<wsdl:output message="tns:equipementMoCA_PortType_cErrorDefRec">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="retraitEquipementServMoCA">
<wsdl:input message="tns:equipementMoCA_PortType_retraitEquipementServMoCA">
</wsdl:input>
<wsdl:output message="tns:equipementMoCA_PortType_cErrorDefRec">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_Binder" type="tns:equipementMoCA_PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ajoutEquipementServMoCA">
<soap:operation soapAction="ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_Binder_ajoutEquipementServMoCA" style="document"/>
<wsdl:input>
<soap:body parts="parameters" use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body parts="parameters" use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="retraitEquipementServMoCA">
<soap:operation soapAction="ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_Binder_retraitEquipementServMoCA" style="document"/>
<wsdl:input>
<soap:body parts="parameters" use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body parts="parameters" use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="equipementMoCA">
<wsdl:port name="equipementMoCAsoaphttp" binding="tns:ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_Binder">
<soap:address location="http://bsiesglba1.int.videotron.com:5555/ws/equipementMoCA"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
And finally, the code for the wsFactory class:
public class WSClientFactory {
private String endPoint;
private String userName;
private String password;
private int timeOutDelayInMilliSec =60000; //default
// ****** propriétées input du ws ********
private String noCompteClient= new String("");
private String noSerie= new String("");
private String typeAppareil= new String("");
private String systemeSource= new String("");
// ****** propriétées output du ws ********
private StringHolder errorNb= new StringHolder("");
private StringHolder errorText= new StringHolder("");
private StringHolder severity= new StringHolder("");
private StringHolder errorType= new StringHolder("");
// ****** propriétés locales
EquipementMoCALocator locator;
ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub stub;
EquipementMoCA_PortType service;
public WSClientFactory(String endPoint, String userName, String password, int timeOutDelayInMilliSec ) throws ServiceException, MalformedURLException {
this.endPoint = endPoint;
this.userName = userName;
this.password = password;
this.timeOutDelayInMilliSec = timeOutDelayInMilliSec;
// The Locator class knows how to access our web service
//ServiceActivationMoCALocator locator = new ServiceActivationMoCALocator();
locator = new EquipementMoCALocator();
//stub = (ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub) locator.getServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_Port(new URL(endPoint));
//service = locator.getServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_Port();
stub = (ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub) locator.getEquipementMoCAsoaphttp(new URL(endPoint));
service = locator.getEquipementMoCAsoaphttp();
System.out.print("DEBUG endpoint: " + stub.getEndpoint());
System.out.print("DEBUG portname: " + stub.getPortName());
// setting du timeout pour la durée maxi avant output du ws
stub.setTimeout(timeOutDelayInMilliSec);
// Authentication
if (!userName.equals("")){
stub._setProperty(lotus.domino.axis.client.Call.USERNAME_PROPERTY, userName);
stub._setProperty(lotus.domino.axis.client.Call.PASSWORD_PROPERTY, password);
}
}
public WSClientFactory(String endPoint, String userName, String password)throws ServiceException, MalformedURLException {
this.endPoint = endPoint;
this.userName = userName;
this.password = password;
// The Locator class knows how to access our web service
//ServiceActivationMoCALocator locator = new ServiceActivationMoCALocator();
locator = new EquipementMoCALocator();
//stub = (ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub) locator.getServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_Port(new URL(endPoint));
//service = locator.getServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_Port();
stub = (ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub) locator.getEquipementMoCAsoaphttp(new URL(endPoint));
service = locator.getEquipementMoCAsoaphttp();
// setting du timeout pour la durée maxi avant output du ws
stub.setTimeout(timeOutDelayInMilliSec);
// Authentication
if (!userName.equals("")){
stub._setProperty(lotus.domino.axis.client.Call.USERNAME_PROPERTY, userName);
stub._setProperty(lotus.domino.axis.client.Call.PASSWORD_PROPERTY, password);
}
}
/*
* Methode permettant de faire l'ajout d'un appareil (noSerie) au comtpe client(noCompteClient) dans le dépôt MoCa
*/
public boolean wsAddEquipment(String noCompteClient, String noSerie, String typeAppareil, String systemeSource) throws MalformedURLException, ServiceException, RemoteException{
service.ajoutEquipementServMoCA(noCompteClient, noSerie, typeAppareil, systemeSource,
this.errorNb, this.errorText, this.severity, this.errorType);
// dans la réponse du ws, si la valeur de erroNb = 0, c'est que ça a fonctionné
if (this.errorNb.equals("0")){
return true;
}else {
return false;
}
}
/*
* Methode permettant de faire la suppression d'un appareil (noSerie) au comtpe client(noCompteClient) dans le dépôt MoCa
*/
public boolean wsRemoveEquipment(String noCompteClient, String noSerie, String typeAppareil, String systemeSource) throws MalformedURLException, ServiceException, RemoteException{
service.retraitEquipementServMoCA(noCompteClient, noSerie, typeAppareil, systemeSource,
this.errorNb, this.errorText, this.severity, this.errorType);
// dans la réponse du ws, si la valeur de erroNb = 0, c'est que ça a fonctionné
if (this.errorNb.equals("0")){
return true;
}else {
return false;
}
}
And the stub class:
package com.videotron.www.MoCA.gestionEquipement;
public class ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub extends lotus.domino.websvc.client.Stub implements com.videotron.www.MoCA.gestionEquipement.EquipementMoCA_PortType {
public ServiceConfActMngt_HomeNetworking_webservices_equipementMoCA_BinderStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws lotus.domino.types.Fault {
super(endpointURL, service);
}
public void ajoutEquipementServMoCA(java.lang.String noCompteClient, java.lang.String noSerie, java.lang.String typeAppareil, java.lang.String systemeSource, javax.xml.rpc.holders.StringHolder errorNb, javax.xml.rpc.holders.StringHolder errorText, javax.xml.rpc.holders.StringHolder severity, javax.xml.rpc.holders.StringHolder errorType) throws java.rmi.RemoteException {
lotus.domino.websvc.client.Call _call = createCall("ajoutEquipementServMoCA");
java.lang.Object _resp = _call.invoke(new java.lang.Object[] {noCompteClient, noSerie, typeAppareil, systemeSource});
errorNb.value = (java.lang.String) _call.convertOutputParam("", "errorNb", java.lang.String.class);
errorText.value = (java.lang.String) _call.convertOutputParam("", "errorText", java.lang.String.class);
severity.value = (java.lang.String) _call.convertOutputParam("", "severity", java.lang.String.class);
errorType.value = (java.lang.String) _call.convertOutputParam("", "errorType", java.lang.String.class);
}
public void retraitEquipementServMoCA(java.lang.String noCompteClient, java.lang.String noSerie, java.lang.String typeAppareil, java.lang.String systemeSource, javax.xml.rpc.holders.StringHolder errorNb, javax.xml.rpc.holders.StringHolder errorText, javax.xml.rpc.holders.StringHolder severity, javax.xml.rpc.holders.StringHolder errorType) throws java.rmi.RemoteException {
lotus.domino.websvc.client.Call _call = createCall("retraitEquipementServMoCA");
java.lang.Object _resp = _call.invoke(new java.lang.Object[] {noCompteClient, noSerie, typeAppareil, systemeSource});
errorNb.value = (java.lang.String) _call.convertOutputParam("", "errorNb", java.lang.String.class);
errorText.value = (java.lang.String) _call.convertOutputParam("", "errorText", java.lang.String.class);
severity.value = (java.lang.String) _call.convertOutputParam("", "severity", java.lang.String.class);
errorType.value = (java.lang.String) _call.convertOutputParam("", "errorType", java.lang.String.class);
}
}
I don't know if you need more info, but I will add them if needed.
I have successfully connected to the web service with SoapUI, so I know it works on the provider side.
The code is running Domino Release 9.0.1FP4 HF525
Well, I managed to find the solution, and it was just under my nose...
If you look at the "JMP 105 – XML and Web Services Jumpstart" slides (can be found here: http://www.nnsu.com/nnsusite.nsf/xsp/.ibmmodres/domino/OpenAttachment/nnsusite.nsf/6343B286B9778CE6862576B60062BB1F/Content/JMP105.pdf), there are a couple of slides that tell you where to add the credentials. Nothing fancy, you just need to add them in the stub's code generated by Designer from the WSDL file of he web service you want to consume. It's on page 114 for LotusScript and on page 120 for Java.
That fixed my issue!!!