I need to implement a gateway in php that receives calls in SOAP.
The WSDL of the web service is not very complicated. Next I expose an extract of the same one.
<portType name="DeliveryNotification">
<operation name="notifyDelivery" parameterOrder="parameters platformHeader">
<input message="tns:notifyDelivery"/>
<output message="tns:notifyDeliveryResponse"/>
</operation>
</portType>
<binding name="DeliveryNotificationPortBinding" type="tns:DeliveryNotification">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="notifyDelivery">
<soap:operation soapAction="notifyDelivery"/>
<input>
<soap:body use="literal" parts="parameters"/>
<soap:header message="tns:notifyDelivery" part="platformHeader" use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="DeliveryNotificationService">
<port name="DeliveryNotificationPortBinding" binding="tns:DeliveryNotificationPortBinding">
<soap:address location="http://localhost:8888/soapTest/outbound-test.php"/>
</port>
</service>
The script that processes the service execution request is very simple. I use a separate class to handle this operation and the following:
$server = new Gateway\Debug\DebugSoapServer(OUTBOUND_API_WSDL, array(
'soap_version' => SOAP_1_2
));
$server->setObject(new Gateway\Handlers\OutboundHandlerDecorator(new Gateway\Handlers\OutboundHandler()));
try {
$server->handle();
} catch (Exception $e) {
$server->fault('Sender', $e->getMessage());
}
OutboundHandlerDecorator would act as a proxy to validate access and then delegate to the final handler to process the response.
next I expose its definition:
class OutboundHandlerDecorator
{
private $decorated = null;
public function __construct(OutboundHandler $decorated)
{
$this->decorated = $decorated;
}
public function __call($method, $params)
{
global $methodCalled;
$methodCalled = $method;
if (method_exists($this->decorated, $method)) {
return call_user_func_array(
array($this->decorated, $method), $params);
} else {
throw new \BadMethodCallException();
}
}
}
My problem is the following:
I created the following SOAP message to simulate the call to the notifyDelivery service, using the SOAPUI tool. Next I expose the result:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://test.com/">
<soapenv:Header>
<ws:platformHeader>
<platformCredentials>
<password>myPassword</password>
<userId>myUser</userId>
</platformCredentials>
<platformFlags>
<retry>1</retry>
</platformFlags>
</ws:platformHeader>
</soapenv:Header>
<soapenv:Body>
<ws:notifyDelivery>
<simId>1234567891234567789</simId>
<simIdType>ICCID</simIdType>
</ws:notifyDelivery>
</soapenv:Body>
</soapenv:Envelope>
As a result I get a failed SOAP message, because the BadMethodCallException exception is thrown. Since first of all it tries to find and execute a method called "platformHeader" and for this there is no function defined in the class "OutboundHandler".
If I do not throw this exception, the notifyDelivery method of the "OutboundHandler" class will be executed correctly.
Therefore, my question is: Why does SoapServer identify the header as an operation? From SOAPUI I am configuring the SOAPAction HTTP header to "notifyDelivery". I do not understand this operation.
How could I access the header data independently? In the variable $ params I only have the data of the body of the message.
Thank you very much in advance.
regards