Skip to content
This repository was archived by the owner on Jan 16, 2018. It is now read-only.

Add a concrete implementation for sending multiple requests #16

Merged
merged 1 commit into from
Oct 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 4 additions & 25 deletions spec/BatchRequestSpec.php → spec/BatchClientSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,30 @@
namespace spec\Http\Client\Utils;

use Http\Client\HttpClient;
use Http\Client\Utils\BatchRequest;
use PhpSpec\ObjectBehavior;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class BatchRequestSpec extends ObjectBehavior
class BatchClientSpec extends ObjectBehavior
{
function let(HttpClient $client)
{
$this->beAnInstanceOf('spec\Http\Client\Utils\BatchRequestStub', [$client]);
$this->beAnInstanceOf('Http\Client\Utils\BatchClient', [$client]);
}

function it_send_multiple_request_using_send_request(HttpClient $client, RequestInterface $request1, RequestInterface $request2, ResponseInterface $response1, ResponseInterface $response2)
{
$client->sendRequest($request1)->willReturn($response1);
$client->sendRequest($request2)->willReturn($response2);

$this->sendRequests([$request1, $request2])->shouldReturnAnInstanceOf('Http\Client\BatchResult');
$this->sendRequests([$request1, $request2])->shouldReturnAnInstanceOf('Http\Client\Utils\BatchResult');
}

function it_throw_batch_exception_if_one_or_more_request_failed(HttpClient $client, RequestInterface $request1, RequestInterface $request2, ResponseInterface $response)
{
$client->sendRequest($request1)->willReturn($response);
$client->sendRequest($request2)->willThrow('Http\Client\Exception\HttpException');

$this->shouldThrow('Http\Client\Exception\BatchException')->duringSendRequests([$request1, $request2]);
}
}

class BatchRequestStub implements HttpClient
{
use BatchRequest;

protected $client;

public function __construct(HttpClient $client)
{
$this->client = $client;
}

/**
* {@inheritdoc}
*/
public function sendRequest(RequestInterface $request)
{
return $this->client->sendRequest($request);
$this->shouldThrow('Http\Client\Utils\Exception\BatchException')->duringSendRequests([$request1, $request2]);
}
}
1 change: 0 additions & 1 deletion spec/BatchResultSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class BatchResultSpec extends ObjectBehavior
function it_is_initializable()
{
$this->beAnInstanceOf('Http\Client\Utils\BatchResult');
$this->shouldImplement('Http\Client\BatchResult');
}

function it_is_immutable(RequestInterface $request, ResponseInterface $response)
Expand Down
37 changes: 37 additions & 0 deletions spec/Exception/BatchExceptionSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace spec\Http\Client\Utils\Exception;

use Http\Client\Utils\BatchResult;
use Http\Client\Exception;
use PhpSpec\ObjectBehavior;

class BatchExceptionSpec extends ObjectBehavior
{
function let()
{
$batchResult = new BatchResult();
$this->beConstructedWith($batchResult);
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Client\Utils\Exception\BatchException');
}

function it_is_a_runtime_exception()
{
$this->shouldHaveType('RuntimeException');
}

function it_is_an_exception()
{
$this->shouldImplement('Http\Client\Exception');
}

function it_has_a_batch_result()
{
$this->getResult()->shouldHaveType('Http\Client\Utils\BatchResult');
}
}

8 changes: 0 additions & 8 deletions spec/HttpMethodsClientSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,6 @@ function it_sends_request_with_underlying_client(HttpClient $client, MessageFact
$this->beConstructedWith($client, $messageFactory);
$this->sendRequest($request)->shouldReturn($response);
}

function it_sends_requests_with_underlying_client(HttpClient $client, MessageFactory $messageFactory, RequestInterface $request1, RequestInterface $request2, BatchResult $batchResult)
{
$client->sendRequests([$request1, $request2])->shouldBeCalled()->willReturn($batchResult);

$this->beConstructedWith($client, $messageFactory);
$this->sendRequests([$request1, $request2])->shouldReturn($batchResult);
}
}

class HttpMethodsClientStub extends HttpMethodsClient
Expand Down
21 changes: 15 additions & 6 deletions src/BatchRequest.php → src/BatchClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,33 @@
namespace Http\Client\Utils;

use Http\Client\Exception;
use Http\Client\Exception\BatchException;
use Http\Client\HttpClient;
use Http\Client\Utils\Exception\BatchException;
use Psr\Http\Message\RequestInterface;

/**
* Implements sending multiple request for client not supporting parallel requests.
* BatchClient allow to sends multiple request and retrieve a Batch Result
*
* This implementation simply loops over the requests and uses sendRequest to send each of them.
*
* Use when implementing Http\Client\HttpClient.
*
* @author Joel Wurtz <[email protected]>
*/
trait BatchRequest
class BatchClient implements HttpClient
{
private $client;

public function __construct(HttpClient $client)
{
$this->client = $client;
}

/**
* {@inheritdoc}
*/
abstract public function sendRequest(RequestInterface $request);
public function sendRequest(RequestInterface $request)
{
return $this->client->sendRequest($request);
}

/**
* {@inheritdoc}
Expand Down
61 changes: 49 additions & 12 deletions src/BatchResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace Http\Client\Utils;

use Http\Client\Exception;
use Http\Client\BatchResult as BatchResultInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

Expand All @@ -12,7 +11,7 @@
*
* @author Márk Sági-Kazár <[email protected]>
*/
final class BatchResult implements BatchResultInterface
final class BatchResult
{
/**
* @var \SplObjectStorage
Expand All @@ -31,15 +30,19 @@ public function __construct()
}

/**
* {@inheritDoc}
* Checks if there are any successful responses at all.
*
* @return boolean
*/
public function hasResponses()
{
return $this->responses->count() > 0;
}

/**
* {@inheritDoc}
* Returns all successful responses.
*
* @return ResponseInterface[]
*/
public function getResponses()
{
Expand All @@ -53,15 +56,25 @@ public function getResponses()
}

/**
* {@inheritDoc}
* Checks if there is a successful response for a request.
*
* @param RequestInterface $request
*
* @return boolean
*/
public function isSuccessful(RequestInterface $request)
{
return $this->responses->contains($request);
}

/**
* {@inheritDoc}
* Returns the response for a successful request.
*
* @param RequestInterface $request
*
* @return ResponseInterface
*
* @throws \UnexpectedValueException If request was not part of the batch or failed.
*/
public function getResponseFor(RequestInterface $request)
{
Expand All @@ -73,7 +86,12 @@ public function getResponseFor(RequestInterface $request)
}

/**
* {@inheritDoc}
* Adds a response in an immutable way.
*
* @param RequestInterface $request
* @param ResponseInterface $response
*
* @return BatchResult the new BatchResult with this request-response pair added to it.
*/
public function addResponse(RequestInterface $request, ResponseInterface $response)
{
Expand All @@ -84,15 +102,19 @@ public function addResponse(RequestInterface $request, ResponseInterface $respon
}

/**
* {@inheritDoc}
* Checks if there are any unsuccessful requests at all.
*
* @return boolean
*/
public function hasExceptions()
{
return $this->exceptions->count() > 0;
}

/**
* {@inheritDoc}
* Returns all exceptions for the unsuccessful requests.
*
* @return Exception[]
*/
public function getExceptions()
{
Expand All @@ -106,15 +128,25 @@ public function getExceptions()
}

/**
* {@inheritDoc}
* Checks if there is an exception for a request, meaning the request failed.
*
* @param RequestInterface $request
*
* @return boolean
*/
public function isFailed(RequestInterface $request)
{
return $this->exceptions->contains($request);
}

/**
* {@inheritDoc}
* Returns the exception for a failed request.
*
* @param RequestInterface $request
*
* @return Exception
*
* @throws \UnexpectedValueException If request was not part of the batch or was successful.
*/
public function getExceptionFor(RequestInterface $request)
{
Expand All @@ -126,7 +158,12 @@ public function getExceptionFor(RequestInterface $request)
}

/**
* {@inheritDoc}
* Adds an exception in an immutable way.
*
* @param RequestInterface $request
* @param Exception $exception
*
* @return BatchResult the new BatchResult with this request-exception pair added to it.
*/
public function addException(RequestInterface $request, Exception $exception)
{
Expand Down
39 changes: 39 additions & 0 deletions src/Exception/BatchException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Http\Client\Utils\Exception;

use Http\Client\Exception;
use Http\Client\Exception\TransferException;
use Http\Client\Utils\BatchResult;

/**
* This exception is thrown when HttpClient::sendRequests led to at least one failure.
*
* It gives access to a BatchResult with the request-exception and request-response pairs.
*
* @author Márk Sági-Kazár <[email protected]>
*/
final class BatchException extends TransferException implements Exception
{
/**
* @var BatchResult
*/
private $result;

/**
* @param BatchResult $result
*/
public function __construct(BatchResult $result)
{
$this->result = $result;
}
/**
* Returns the BatchResult that contains all responses and exceptions
*
* @return BatchResult
*/
public function getResult()
{
return $this->result;
}
}
10 changes: 0 additions & 10 deletions src/HttpMethodsClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,4 @@ public function sendRequest(RequestInterface $request)
{
return $this->httpClient->sendRequest($request);
}

/**
* Forward to the underlying HttpClient.
*
* {@inheritdoc}
*/
public function sendRequests(array $requests)
{
return $this->httpClient->sendRequests($requests);
}
}