From fe20c14987a33772ec19e6f4e665e191d2919ac6 Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Tue, 31 May 2016 22:30:00 +0200 Subject: [PATCH] Further implementation of error checks in ResponseHandler - do not throw soapfaults anymore - provide message version in Session Handler SendResult - #2 --- src/Amadeus/Client/ResponseHandler/Base.php | 44 +++++++++++- src/Amadeus/Client/Result.php | 4 ++ src/Amadeus/Client/Session/Handler/Base.php | 45 ++++++++++++- .../Client/Session/Handler/SendResult.php | 18 +++++ .../Client/ResponseHandler/BaseTest.php | 67 +++++++++++++++++++ .../dummySecurityAuthenticateReply.txt | 1 + .../dummySecurityAuthenticateReplyError.txt | 19 ++++++ .../testfiles/dummySoapFault.txt | 1 + .../testfiles/dummySoapFaultSession.txt | 1 + .../Session/Handler/SoapHeader2Test.php | 1 + .../Session/Handler/SoapHeader4Test.php | 17 +++-- 11 files changed, 208 insertions(+), 10 deletions(-) create mode 100644 tests/Amadeus/Client/ResponseHandler/testfiles/dummySecurityAuthenticateReply.txt create mode 100644 tests/Amadeus/Client/ResponseHandler/testfiles/dummySecurityAuthenticateReplyError.txt create mode 100644 tests/Amadeus/Client/ResponseHandler/testfiles/dummySoapFault.txt create mode 100644 tests/Amadeus/Client/ResponseHandler/testfiles/dummySoapFaultSession.txt diff --git a/src/Amadeus/Client/ResponseHandler/Base.php b/src/Amadeus/Client/ResponseHandler/Base.php index 17fb49155..39e39d16a 100644 --- a/src/Amadeus/Client/ResponseHandler/Base.php +++ b/src/Amadeus/Client/ResponseHandler/Base.php @@ -55,7 +55,9 @@ public function analyzeResponse($sendResult, $messageName) { $methodName = 'analyze' . str_replace('_', '', ucfirst($messageName)).'Response'; - if (method_exists($this, $methodName)) { + if (!empty($sendResult->exception)) { + return $this->makeResultForException($sendResult); + } elseif (method_exists($this, $methodName)) { return $this->$methodName( $sendResult ); @@ -252,7 +254,9 @@ protected function analyzeSimpleResponseErrorCodeAndMessage($response) $errorCodeNode = $domDoc->getElementsByTagName("errorCode")->item(0); if (!is_null($errorCodeNode)) { - $analyzeResponse->status = Result::STATUS_WARN; + $errorCatNode = $domDoc->getElementsByTagName("errorCategory")->item(0); + $analyzeResponse->status = $this->makeStatusFromErrorQualifier($errorCatNode->nodeValue); + $errorCode = $errorCodeNode->nodeValue; $errorTextNodeList = $domDoc->getElementsByTagName("freeText"); @@ -388,4 +392,40 @@ function($item) { ) ); } + + /** + * @param SendResult $sendResult + * @return Result + */ + protected function makeResultForException($sendResult) + { + $result = new Result($sendResult, Result::STATUS_FATAL); + + $result->messages[] = $this->makeMessageFromException($sendResult->exception); + + return $result; + } + + /** + * @param \Exception $exception + * @return Result\NotOk + * @throws Exception + */ + protected function makeMessageFromException(\Exception $exception) + { + $message = new Result\NotOk(); + + if ($exception instanceof \SoapFault) { + $info = explode('|', $exception->getMessage()); + $message->code = $info[0]; + if (count($info) === 3) { + $message->level = $info[1]; + $message->text = $info[2]; + } + } else { + throw new Exception('Did not implement other exceptions than soapfaults'); + } + + return $message; + } } diff --git a/src/Amadeus/Client/Result.php b/src/Amadeus/Client/Result.php index 2d32d5043..0f1a35634 100644 --- a/src/Amadeus/Client/Result.php +++ b/src/Amadeus/Client/Result.php @@ -49,6 +49,10 @@ class Result * Status indicator for an error response. */ const STATUS_ERROR = 'ERR'; + /** + * Status indicator for a FATAL error response. + */ + const STATUS_FATAL = 'FATAL'; /** * Status indicator for a response which could not be checked for warnings/errors. */ diff --git a/src/Amadeus/Client/Session/Handler/Base.php b/src/Amadeus/Client/Session/Handler/Base.php index 4b5a37680..43fec9f52 100644 --- a/src/Amadeus/Client/Session/Handler/Base.php +++ b/src/Amadeus/Client/Session/Handler/Base.php @@ -138,6 +138,11 @@ abstract class Base implements HandlerInterface, LoggerAwareInterface */ protected $wsdlDomXpath; + /** + * @var array + */ + protected $messagesAndVersions; + /** * Get the session parameters of the active session * @@ -197,7 +202,9 @@ public function __construct(SessionHandlerParams $params) */ public function sendMessage($messageName, Client\Struct\BaseWsMessage $messageBody, $messageOptions = []) { - $result = new SendResult(); + $result = new SendResult( + $this->getActiveVersionFor($messageName) + ); $this->prepareForNextMessage($messageName, $messageOptions); @@ -216,9 +223,10 @@ public function sendMessage($messageName, Client\Struct\BaseWsMessage $messageBo " line " . $ex->getLine() . ": \n" . $ex->getTraceAsString() ); $this->logRequestAndResponse($messageName); - //TODO We must be able to handle certain soapfaults inside the client, so maybe pass through after logging? - throw $ex; + $result->exception = $ex; } catch (\Exception $ex) { + // We should only come here when the XSL extension is not enabled or the XSLT transformation file + // is unreadable $this->log( LogLevel::ERROR, "EXCEPTION while sending message " . $messageName . ": " . @@ -294,6 +302,20 @@ public function getOriginatorOffice() * @return array */ public function getMessagesAndVersions() + { + if (empty($this->messagesAndVersions)) { + $this->messagesAndVersions = $this->loadMessagesAndVersions(); + } + + return $this->messagesAndVersions; + } + + /** + * Loads messages & versions from WSDL. + * + * @return array + */ + protected function loadMessagesAndVersions() { $this->loadWsdlXpath($this->params->wsdl); @@ -355,6 +377,23 @@ protected function loadWsdlXpath($wsdlFilePath) } } + /** + * Get the version number active in the WSDL for the given message + * + * @param $messageName + * @return float|string|null + */ + protected function getActiveVersionFor($messageName) + { + $msgAndVer = $this->getMessagesAndVersions(); + + if (isset($msgAndVer[$messageName])) { + return $msgAndVer[$messageName]; + } + + return null; + } + /** * @return \SoapClient diff --git a/src/Amadeus/Client/Session/Handler/SendResult.php b/src/Amadeus/Client/Session/Handler/SendResult.php index 0e8a16f08..71dd3d118 100644 --- a/src/Amadeus/Client/Session/Handler/SendResult.php +++ b/src/Amadeus/Client/Session/Handler/SendResult.php @@ -25,6 +25,8 @@ /** * SendResult * + * An object used to return the result of the Session Handler sendMessage() + * * @package Amadeus\Client\Session\Handler * @author Dieter Devlieghere */ @@ -50,4 +52,20 @@ class SendResult * @var string */ public $messageVersion; + + /** + * Exception that occurred while sending + * @var \Exception + */ + public $exception; + + /** + * SendResult constructor. + * + * @param string|float|null $messageVersion + */ + public function __construct($messageVersion = null) + { + $this->messageVersion = $messageVersion; + } } diff --git a/tests/Amadeus/Client/ResponseHandler/BaseTest.php b/tests/Amadeus/Client/ResponseHandler/BaseTest.php index 7d1193ba9..6e491a8bf 100644 --- a/tests/Amadeus/Client/ResponseHandler/BaseTest.php +++ b/tests/Amadeus/Client/ResponseHandler/BaseTest.php @@ -168,4 +168,71 @@ public function testCanFindAirFlightInfoError() $this->assertEquals('AUE', $result->messages[0]->code); $this->assertEquals("FLIGHT CANCELLED", $result->messages[0]->text); } + + public function testCanParseSecurityAuthenticateReplyOk() + { + $respHandler = new ResponseHandler\Base(); + + $sendResult = new SendResult(); + $sendResult->responseXml = $this->getTestFile('dummySecurityAuthenticateReply.txt'); + $sendResult->messageVersion = '6.1'; + + $result = $respHandler->analyzeResponse($sendResult, 'Security_Authenticate'); + + $this->assertEquals(Result::STATUS_OK, $result->status); + $this->assertEquals(0, count($result->messages)); + } + + public function testCanParseSecurityAuthenticateReplyErr() + { + $respHandler = new ResponseHandler\Base(); + + $sendResult = new SendResult(); + $sendResult->responseXml = $this->getTestFile('dummySecurityAuthenticateReplyError.txt'); + $sendResult->messageVersion = '6.1'; + + $result = $respHandler->analyzeResponse($sendResult, 'Security_Authenticate'); + + $this->assertEquals(Result::STATUS_ERROR, $result->status); + $this->assertEquals(1, count($result->messages)); + $this->assertEquals('You are not authorized to login in this area.', $result->messages[0]->text); + $this->assertEquals('', $result->messages[0]->level); + $this->assertEquals('16199', $result->messages[0]->code); + } + + public function testCanHandleSoapFault() + { + $respHandler = new ResponseHandler\Base(); + + $sendResult = new SendResult(); + $sendResult->responseXml = $this->getTestFile('dummySoapFault.txt'); + $sendResult->messageVersion = '14.2'; + $sendResult->exception = new \SoapFault("Sender", "1929|Application|INVALID RECORD LOCATOR"); + + $result = $respHandler->analyzeResponse($sendResult, 'PNR_Retrieve'); + + $this->assertEquals(Result::STATUS_FATAL, $result->status); + $this->assertEquals(1, count($result->messages)); + $this->assertEquals('1929', $result->messages[0]->code); + $this->assertEquals("INVALID RECORD LOCATOR", $result->messages[0]->text); + $this->assertEquals("Application", $result->messages[0]->level); + } + + public function testCanHandleSoapFaultSession() + { + $respHandler = new ResponseHandler\Base(); + + $sendResult = new SendResult(); + $sendResult->responseXml = $this->getTestFile('dummySoapFaultSession.txt'); + $sendResult->messageVersion = '14.2'; + $sendResult->exception = new \SoapFault("Sender", "11|Session|"); + + $result = $respHandler->analyzeResponse($sendResult, 'PNR_Retrieve'); + + $this->assertEquals(Result::STATUS_FATAL, $result->status); + $this->assertEquals(1, count($result->messages)); + $this->assertEquals('11', $result->messages[0]->code); + $this->assertEquals("Session", $result->messages[0]->level); + $this->assertEquals('', $result->messages[0]->text); + } } diff --git a/tests/Amadeus/Client/ResponseHandler/testfiles/dummySecurityAuthenticateReply.txt b/tests/Amadeus/Client/ResponseHandler/testfiles/dummySecurityAuthenticateReply.txt new file mode 100644 index 000000000..a65c4294a --- /dev/null +++ b/tests/Amadeus/Client/ResponseHandler/testfiles/dummySecurityAuthenticateReply.txt @@ -0,0 +1 @@ +P \ No newline at end of file diff --git a/tests/Amadeus/Client/ResponseHandler/testfiles/dummySecurityAuthenticateReplyError.txt b/tests/Amadeus/Client/ResponseHandler/testfiles/dummySecurityAuthenticateReplyError.txt new file mode 100644 index 000000000..e9f7bf0a2 --- /dev/null +++ b/tests/Amadeus/Client/ResponseHandler/testfiles/dummySecurityAuthenticateReplyError.txt @@ -0,0 +1,19 @@ + + + + + 16199 + EC + APPLICATION1 + + + + + 3 + TXT + EN + + You are not authorized to login in this area. + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/ResponseHandler/testfiles/dummySoapFault.txt b/tests/Amadeus/Client/ResponseHandler/testfiles/dummySoapFault.txt new file mode 100644 index 000000000..a82576450 --- /dev/null +++ b/tests/Amadeus/Client/ResponseHandler/testfiles/dummySoapFault.txt @@ -0,0 +1 @@ +soap:Server1929|Application|INVALID RECORD LOCATORSI:Backend \ No newline at end of file diff --git a/tests/Amadeus/Client/ResponseHandler/testfiles/dummySoapFaultSession.txt b/tests/Amadeus/Client/ResponseHandler/testfiles/dummySoapFaultSession.txt new file mode 100644 index 000000000..569527ee1 --- /dev/null +++ b/tests/Amadeus/Client/ResponseHandler/testfiles/dummySoapFaultSession.txt @@ -0,0 +1 @@ +soap:Client 11|Session| \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php b/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php index f8ecd0fab..ad17bc8cb 100644 --- a/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php +++ b/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php @@ -128,6 +128,7 @@ public function testCanSendAuthCallAndStartSession() $messageResult = new SendResult(); $messageResult->responseObject = $wsResponse; $messageResult->responseXml = Client\Util\MsgBodyExtractor::extract($dummyReply); + $messageResult->messageVersion = '6.1'; $overrideSoapClient diff --git a/tests/Amadeus/Client/Session/Handler/SoapHeader4Test.php b/tests/Amadeus/Client/Session/Handler/SoapHeader4Test.php index 8ed64fa7c..8830afafb 100644 --- a/tests/Amadeus/Client/Session/Handler/SoapHeader4Test.php +++ b/tests/Amadeus/Client/Session/Handler/SoapHeader4Test.php @@ -449,15 +449,14 @@ public function testCanSendMessage() $expectedResult = new Client\Session\Handler\SendResult(); $expectedResult->responseXml = $dummyPnrReplyExtractedMessage; $expectedResult->responseObject = new \stdClass(); + $expectedResult->messageVersion = '11.3'; $this->assertEquals($expectedResult, $messageResponse); } - public function testCanHandleMessageThrowingSoapFault() + public function testCanHandleMessageWithSoapFault() { - $this->setExpectedException('\SoapFault'); - $overrideSoapClient = $this->getMock( 'Amadeus\Client\SoapClient', ['__getLastRequest', '__getLastResponse', 'PNR_Retrieve'], @@ -483,7 +482,7 @@ public function testCanHandleMessageThrowingSoapFault() $overrideSoapClient ->expects($this->any()) ->method('PNR_Retrieve') - ->will($this->throwException(new \SoapFault("Sender", "SECURED PNR"))); + ->will($this->throwException(new \SoapFault("Sender", "284|Application|SECURED PNR"))); $sessionHandlerParams = $this->makeSessionHandlerParams($overrideSoapClient); $sessionHandler = new SoapHeader4($sessionHandlerParams); @@ -493,11 +492,17 @@ public function testCanHandleMessageThrowingSoapFault() 'ABC123' ); - $sessionHandler->sendMessage( + $sendResult = $sessionHandler->sendMessage( 'PNR_Retrieve', $pnrRetrieveMessage, ['asString'=>true,'endSession'=>false] ); + + $this->assertInstanceOf('Amadeus\Client\Session\Handler\SendResult', $sendResult); + $this->assertInstanceOf('\SoapFault', $sendResult->exception); + $this->assertEquals('284|Application|SECURED PNR', $sendResult->exception->getMessage()); + $this->assertEquals('11.3', $sendResult->messageVersion); + $this->assertEquals(Client\Util\MsgBodyExtractor::extract($dummyPnrReply), $sendResult->responseXml); } public function testCanHandleMessageThrowingNonSoapFaultException() @@ -590,6 +595,7 @@ public function testCanExtractSessionDataAfterCall() $expectedResult = new Client\Session\Handler\SendResult(); $expectedResult->responseXml = $this->getTestFile('acspnrreply.xml'); $expectedResult->responseObject = $this->getTestFile('acspnr.xml'); + $expectedResult->messageVersion = '11.3'; $this->assertEquals($expectedResult, $messageResponse); @@ -689,6 +695,7 @@ public function testCanMakeSessionHandlerWithoutLogger() $expectedResult = new Client\Session\Handler\SendResult(); $expectedResult->responseXml = $dummyPnrReplyExtractedMessage; $expectedResult->responseObject = new \stdClass(); + $expectedResult->messageVersion = '11.3'; $this->assertEquals($expectedResult, $messageResponse); }