Skip to content

Commit

Permalink
Merge pull request #3 from bankiru/feature/fixes-and-tests
Browse files Browse the repository at this point in the history
Fix method loader
  • Loading branch information
scaytrase committed May 17, 2016
2 parents 055f1b3 + 6067099 commit f72a4ba
Show file tree
Hide file tree
Showing 28 changed files with 617 additions and 156 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ rpc:
This creates endpoint on URL / with generic symfony controller. Also it
pre-populates the methods from the `service_rpc.yml` config file

`my-public-endpoint` will become a route name, so make sure it does not
overlap with other routes until you want it do to this.

### Method routing

Expand Down Expand Up @@ -136,3 +139,19 @@ hook your extension into given system events
instance of `RpcResponseInterface`
* `rpc.exception` is triggered when exception is raised during RPC call processing
* `rpc.finish_request` is used to finalize RPC response before it is returned to HTTP controller


## RPC Controller implementation

The goal of implementing controller is to extend abstract `RpcController` passing
`RequestInterface` and endpoint name into `getResponse` method.

`RequestInterface` is an extension of `RpcRequestInterface` with extra attributes
allowing request metadata carrying alongside the request.

The generic solution is to convert incoming symfony `Request` instance into your own
implementation of `RequestInterface` (i.e extract method and args from XML-RPC or JSON-RPC requests)
and send serialized response back, transforming `RpcResponseInterface` back to your response object.

You can also automatically convert `RpcResponseInterface` into your serialized response via
generic symfony view event processing
12 changes: 6 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@
],
"require": {
"php": "~5.5 || ~7.0",
"symfony/console": "~2.8 || ~3.0",
"symfony/config": "~2.8 || ~3.0",
"symfony/http-kernel": "~2.8 || ~3.0",
"symfony/dependency-injection": "~2.8 || ~3.0",
"symfony/console": "~2.7 || ~3.0",
"symfony/config": "~2.7 || ~3.0",
"symfony/http-kernel": "~2.7 || ~3.0",
"symfony/dependency-injection": "~2.7 || ~3.0",
"doctrine/annotations": "~1.2",
"scaytrase/rpc-common": "~1.0"
},
"require-dev": {
"symfony/routing": "~2.8 || ~3.0",
"symfony/routing": "~2.7 || ~3.0",
"nelmio/api-doc-bundle": "~2.9",
"phpunit/phpunit": "~4.8 || ~5.1",
"symfony/browser-kit": "~2.8 || ~3.0"
"symfony/browser-kit": "~2.7 || ~3.0"
},
"suggest": {
"nelmio/api-doc-bundle": "For RpcApiDoc extraction"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace Bankiru\Api\Rpc\ApiDoc\Extractor\Provider;

use Bankiru\Api\Rpc\ApiDoc\Annotation\RpcApiDoc;
use Bankiru\Api\Rpc\Impl\Request;
use Bankiru\Api\Rpc\Routing\ControllerResolver\ControllerResolverInterface;
use Bankiru\Api\Rpc\Routing\Route as Method;
use Doctrine\Common\Annotations\Reader;
Expand Down Expand Up @@ -55,7 +56,7 @@ protected function processMethod(Method $method, $endpoint)

$views[] = 'default';

$request = new RpcRequestMock($method, null, new ParameterBag(['_controller' => $method->getController()]));
$request = new Request($method, [], new ParameterBag(['_controller' => $method->getController()]));

/** @var array $controller */
$controller = $this->resolver->getController($request);
Expand Down
20 changes: 20 additions & 0 deletions src/Bankiru/Api/Rpc/Controller/RpcController.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ public function setContainer(ContainerInterface $container = null)
$this->dispatcher = $container->get('event_dispatcher');
}

/**
* @param RequestInterface $request
* @param string $endpoint
*
* @return RpcResponseInterface
* @throws \Exception
*/
protected function getResponse(RequestInterface $request, $endpoint)
{
$request->getAttributes()->set('_endpoint', $endpoint);

try {
$rpcResponse = $this->handleSingleRequest($request);
} catch (\Exception $e) {
$rpcResponse = $this->handleException($e, $request);
}

return $rpcResponse;
}

/**
* @param RequestInterface $request
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Created by PhpStorm.
* User: batanov.pavel
* Date: 17.05.2016
* Time: 7:42
*/

namespace Bankiru\Api\Rpc\DependencyInjection\Compiler;

use Bankiru\Api\Rpc\Listener\ExceptionListener;
use Bankiru\Api\Rpc\RpcEvents;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class RouterLoaderPass implements CompilerPassInterface
{
/** {@inheritdoc} */
public function process(ContainerBuilder $container)
{
if ($container->has('logger')) {
$container
->register('rpc.exception_listener', ExceptionListener::class)
->setArguments([new Reference('logger')])
->addTag(
'kernel.event_listener',
[
'event' => RpcEvents::EXCEPTION,
'method' => 'onException',
]
);
}

$loader = $container->getDefinition('rpc.router.resolver');

$taggedServices = $container->findTaggedServiceIds('rpc.route_loader');

foreach ($taggedServices as $id => $tags) {
$loader->addMethodCall('addLoader', [new Reference($id)]);
}
}
}
31 changes: 1 addition & 30 deletions src/Bankiru/Api/Rpc/DependencyInjection/RpcExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,16 @@

namespace Bankiru\Api\Rpc\DependencyInjection;

use Bankiru\Api\Rpc\Listener\ExceptionListener;
use Bankiru\Api\Rpc\Listener\RouterListener;
use Bankiru\Api\Rpc\Routing\MethodCollection;
use Bankiru\Api\Rpc\Routing\Router;
use Bankiru\Api\Rpc\RpcEvents;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;

final class RpcExtension extends Extension implements CompilerPassInterface
final class RpcExtension extends Extension
{

/** {@inheritdoc} */
Expand Down Expand Up @@ -93,29 +89,4 @@ public function getAlias()
{
return 'rpc';
}

/** {@inheritdoc} */
public function process(ContainerBuilder $container)
{
if ($container->has('logger')) {
$container
->register('rpc.exception_listener', ExceptionListener::class)
->setArguments([new Reference('logger')])
->addTag(
'kernel.event_listener',
[
'event' => RpcEvents::EXCEPTION,
'method' => 'onException',
]
);
}

$loader = $container->getDefinition('rpc.router.resolver');

$taggedServices = $container->findTaggedServiceIds('rpc.route_loader');

foreach ($taggedServices as $id => $tags) {
$loader->addMethodCall('addLoader', [new Reference($id)]);
}
}
}
6 changes: 3 additions & 3 deletions src/Bankiru/Api/Rpc/Event/FilterResponseEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class FilterResponseEvent extends RpcEvent
{
/** @var RpcResponseInterface */
/** @var RpcResponseInterface|null */
private $response;

public function __construct(
Expand All @@ -30,13 +30,13 @@ public function __construct(
}


/** @return RpcResponseInterface */
/** @return RpcResponseInterface|null */
public function getResponse()
{
return $this->response;
}

public function setResponse(RpcResponseInterface $response)
public function setResponse(RpcResponseInterface $response = null)
{
$this->response = $response;
}
Expand Down
22 changes: 1 addition & 21 deletions src/Bankiru/Api/Rpc/Event/GetExceptionResponseEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,20 @@
use ScayTrase\Api\Rpc\RpcResponseInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class GetExceptionResponseEvent extends RpcEvent
class GetExceptionResponseEvent extends RpcResponseEvent
{
/** @var \Exception */
private $exception;
/** @var RpcResponseInterface */
private $response;

public function __construct(HttpKernelInterface $kernel, RequestInterface $request, \Exception $exception)
{
parent::__construct($kernel, $request);
$this->exception = $exception;
}


/** @return \Exception */
public function getException()
{
return $this->exception;
}

/** @return bool */
public function hasResponse()
{
return null !== $this->response;
}

/** @return RpcResponseInterface */
public function getResponse()
{
return $this->response;
}

public function setResponse(RpcResponseInterface $response)
{
$this->response = $response;
}
}
25 changes: 1 addition & 24 deletions src/Bankiru/Api/Rpc/Event/GetResponseEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,10 @@
use Bankiru\Api\Rpc\RpcEvent;
use ScayTrase\Api\Rpc\RpcResponseInterface;

class GetResponseEvent extends RpcEvent
class GetResponseEvent extends RpcResponseEvent
{
/** @var RpcResponseInterface|null */
private $response;

public function getEndpoint()
{
return $this->getRequest()->getAttributes()->get('_endpoint');
}

/** @return bool */
public function hasResponse()
{
return null !== $this->response;
}

/** @return RpcResponseInterface */
public function getResponse()
{
return $this->response;
}

/**
* @param RpcResponseInterface $response
*/
public function setResponse(RpcResponseInterface $response)
{
$this->response = $response;
}
}
38 changes: 38 additions & 0 deletions src/Bankiru/Api/Rpc/Event/RpcResponseEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
/**
* Created by PhpStorm.
* User: batanov.pavel
* Date: 17.05.2016
* Time: 8:44
*/

namespace Bankiru\Api\Rpc\Event;

use Bankiru\Api\Rpc\RpcEvent;
use ScayTrase\Api\Rpc\RpcResponseInterface;

class RpcResponseEvent extends RpcEvent
{
/** @var RpcResponseInterface|null */
protected $response;

/** @return bool */
public function hasResponse()
{
return null !== $this->response;
}

/** @return RpcResponseInterface */
public function getResponse()
{
return $this->response;
}

/**
* @param RpcResponseInterface $response
*/
public function setResponse(RpcResponseInterface $response)
{
$this->response = $response;
}
}
7 changes: 7 additions & 0 deletions src/Bankiru/Api/Rpc/Event/ViewEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ class ViewEvent extends RpcEvent
/** @var mixed */
private $response;

/**
* ViewEvent constructor.
*
* @param HttpKernelInterface $kernel
* @param RequestInterface $request
* @param mixed $response
*/
public function __construct(HttpKernelInterface $kernel, RequestInterface $request, $response)
{
parent::__construct($kernel, $request);
Expand Down
44 changes: 44 additions & 0 deletions src/Bankiru/Api/Rpc/Exception/InvalidMethodParametersException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* Created by PhpStorm.
* User: batanov.pavel
* Date: 16.05.2016
* Time: 10:06
*/

namespace Bankiru\Api\Rpc\Exception;

class InvalidMethodParametersException extends \InvalidArgumentException implements RpcException
{
/**
* @param string $method
* @param string[] $missing
*
* @return static
*/
public static function missing($method, array $missing)
{
return new static(
sprintf(
'Some parameters for method "%s" are missing and do not have the default value: %s',
$method,
implode(', ', $missing)
)
);
}

/**
* @param string $method
* @param string $name
* @param string $expected
* @param string $actual
*
* @return static
*/
public static function typeMismatch($method, $name, $expected, $actual)
{
return new static(
sprintf('Parameter %s for method "%s" has invalid type: %s given, %s expected', $name, $method, $actual, $expected)
);
}
}
Loading

0 comments on commit f72a4ba

Please sign in to comment.