Skip to content

Commit a9856ff

Browse files
authored
Add mapping from config (#12)
Fix #6
1 parent caaf65e commit a9856ff

File tree

11 files changed

+293
-65
lines changed

11 files changed

+293
-65
lines changed
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
framework:
22
secret: '%env(APP_SECRET)%'
33

4-
json_rpc_http_server: ~
4+
json_rpc_http_server:
5+
methods_mapping:
6+
bundledMethodA:
7+
service: 'jsonrpc.method.a'
8+
aliases: 'bundledMethodAAlias'
9+
bundledMethodB: 'jsonrpc.method.b'
10+
bundledGetDummy: 'jsonrpc.method.c'
11+
bundledGetAnotherDummy: 'jsonrpc.method.d'
Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
# Configure JSON-RPC method services. /!\ Do not forget to define public visibility /!\
22
services:
3-
# Configure Json-RPC method MethodA by adding the tag
3+
# Configure Json-RPC method MethodA as simple service, it will be injected by configuration mapping
44
jsonrpc.method.a:
55
class: DemoApp\Method\MethodA
66
public: true
7-
tags:
8-
- { name: 'json_rpc_http_server.jsonrpc_method', method: 'bundledMethodA' }
9-
- { name: 'json_rpc_http_server.jsonrpc_method', method: 'bundledMethodAAlias' }
10-
# Configure Json-RPC method MethodB with tag also
7+
# Configure Json-RPC method MethodB as simple service, it will be injected by configuration mapping
118
jsonrpc.method.b:
129
class: DemoApp\Method\MethodB
1310
public: true
14-
tags:
15-
- { name: 'json_rpc_http_server.jsonrpc_method', method: 'bundledMethodB' }
16-
17-
# Configure Json-RPC method MethodC as simple service, it will be injected on container building
11+
# Configure Json-RPC method MethodC as simple service, it will be injected by configuration mapping
1812
jsonrpc.method.c:
1913
class: DemoApp\Method\MethodC
2014
public: true
21-
# Configure Json-RPC method MethodD as simple service, it will be injected on container building
15+
# Configure Json-RPC method MethodD as simple service, it will be injected by configuration mapping
2216
jsonrpc.method.d:
2317
class: DemoApp\Method\MethodD
2418
public: true

features/demo_app/src/DefaultKernel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function registerBundles()
2424
*/
2525
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
2626
{
27-
/**** Add extension **/
27+
/**** Add and load extension **/
2828
$container->registerExtension($extension = new JsonRpcHttpServerExtension());
2929
$container->loadFromExtension($extension->getAlias());
3030

features/demo_app/src/KernelWithBundle.php

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
namespace DemoApp;
33

44
use Symfony\Component\Config\Loader\LoaderInterface;
5-
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
65
use Symfony\Component\DependencyInjection\ContainerBuilder;
76
use Symfony\Component\Routing\RouteCollectionBuilder;
8-
use Yoanm\SymfonyJsonRpcHttpServer\DependencyInjection\JsonRpcHttpServerExtension;
97

10-
class KernelWithBundle extends AbstractKernel implements CompilerPassInterface
8+
class KernelWithBundle extends AbstractKernel
119
{
1210
public function registerBundles()
1311
{
@@ -30,18 +28,6 @@ protected function configureContainer(ContainerBuilder $container, LoaderInterfa
3028
$loader->load($confDir.'/services'.self::CONFIG_EXTS, 'glob');
3129
}
3230

33-
/**
34-
* {@inheritdoc}
35-
*/
36-
public function process(ContainerBuilder $container)
37-
{
38-
// You can manually inject method mapping if you want, use ServiceNameResolver::addMethodMapping method
39-
$container->getDefinition(JsonRpcHttpServerExtension::SERVICE_NAME_RESOLVER_SERVICE_NAME)
40-
->addMethodCall('addMethodMapping', ['bundledGetDummy', 'jsonrpc.method.c'])
41-
->addMethodCall('addMethodMapping', ['bundledGetAnotherDummy', 'jsonrpc.method.d'])
42-
;
43-
}
44-
4531
/**
4632
* {@inheritdoc}
4733
*/

features/demo_app/src/KernelWithCustomResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function registerBundles()
2323
*/
2424
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
2525
{
26-
/**** Add extension **/
26+
/**** Add and load extension **/
2727
$container->registerExtension($extension = new JsonRpcHttpServerExtension());
2828
$container->loadFromExtension($extension->getAlias());
2929

src/DependencyInjection/Configuration.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,31 @@ public function getConfigTreeBuilder()
1919
->treatNullLike(false)
2020
->defaultFalse()
2121
->end()
22+
->arrayNode('methods_mapping')
23+
->requiresAtLeastOneElement()
24+
->normalizeKeys(false)
25+
->arrayPrototype()
26+
->beforeNormalization()
27+
// Convert simple string to an array with the string as service
28+
->ifString()->then(function ($v) {
29+
return ['service' => $v];
30+
})
31+
->end()
32+
->children()
33+
->scalarNode('service')
34+
->isRequired()
35+
->cannotBeEmpty()
36+
->end()
37+
->arrayNode('aliases')
38+
->requiresAtLeastOneElement()
39+
->beforeNormalization()
40+
->castToArray()
41+
->end()
42+
->scalarPrototype()->end()
43+
->end()
44+
->end()
45+
->end()
46+
->end()
2247
->end()
2348
;
2449

src/DependencyInjection/JsonRpcHttpServerExtension.php

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class JsonRpcHttpServerExtension implements ExtensionInterface, CompilerPassInte
4949

5050
/** Private constants */
5151
const CUSTOM_METHOD_RESOLVER_CONTAINER_PARAM = self::EXTENSION_IDENTIFIER.'.custom_method_resolver';
52+
const METHODS_MAPPING_CONTAINER_PARAM = self::EXTENSION_IDENTIFIER.'.methods_mapping';
5253

5354
/** @var bool */
5455
private $parseConfig = false;
@@ -106,7 +107,7 @@ public function process(ContainerBuilder $container)
106107
{
107108
$isContainerResolver = $this->aliasMethodResolver($container);
108109
if (true === $isContainerResolver) {
109-
$this->loadJsonRpcMethodsFromTag($container);
110+
$this->loadJsonRpcMethods($container);
110111
}
111112
}
112113

@@ -273,17 +274,27 @@ private function aliasMethodResolver(ContainerBuilder $container)
273274
/**
274275
* @param ContainerBuilder $container
275276
*/
276-
private function loadJsonRpcMethodsFromTag(ContainerBuilder $container)
277+
private function loadJsonRpcMethods(ContainerBuilder $container)
277278
{
278279
// Check if methods have been defined by tags
279280
$methodServiceList = $container->findTaggedServiceIds(self::JSONRPC_METHOD_TAG);
280-
$defaultResolverDefinition = $container->getDefinition(self::SERVICE_NAME_RESOLVER_SERVICE_NAME);
281281

282282
foreach ($methodServiceList as $serviceId => $tagAttributeList) {
283283
$this->checkJsonRpcMethodService($container, $serviceId);
284284
$methodNameList = $this->extractMethodNameList($tagAttributeList, $serviceId);
285285
foreach ($methodNameList as $methodName) {
286-
$defaultResolverDefinition->addMethodCall('addMethodMapping', [$methodName, $serviceId]);
286+
$this->injectMethodMappingToServiceNameResolver($methodName, $serviceId, $container);
287+
}
288+
}
289+
290+
if ($container->hasParameter(self::METHODS_MAPPING_CONTAINER_PARAM)) {
291+
foreach ($container->getParameter(self::METHODS_MAPPING_CONTAINER_PARAM) as $methodName => $mappingConfig) {
292+
$serviceId = $mappingConfig['service'];
293+
$this->checkJsonRpcMethodService($container, $serviceId);
294+
$this->injectMethodMappingToServiceNameResolver($methodName, $serviceId, $container);
295+
foreach ($mappingConfig['aliases'] as $methodAlias) {
296+
$this->injectMethodMappingToServiceNameResolver($methodAlias, $serviceId, $container);
297+
}
287298
}
288299
}
289300
}
@@ -339,6 +350,23 @@ private function compileAndProcessConfigurations(array $configs, ContainerBuilde
339350
if (array_key_exists('method_resolver', $config) && $config['method_resolver']) {
340351
$container->setParameter(self::CUSTOM_METHOD_RESOLVER_CONTAINER_PARAM, $config['method_resolver']);
341352
}
353+
if (array_key_exists('methods_mapping', $config) && is_array($config['methods_mapping'])) {
354+
$container->setParameter(self::METHODS_MAPPING_CONTAINER_PARAM, $config['methods_mapping']);
355+
}
342356
}
343357
}
358+
359+
/**
360+
* @param string $methodName
361+
* @param string $serviceId
362+
* @param ContainerBuilder $container
363+
*/
364+
private function injectMethodMappingToServiceNameResolver(
365+
string $methodName,
366+
string $serviceId,
367+
ContainerBuilder $container
368+
) {
369+
$container->getDefinition(self::SERVICE_NAME_RESOLVER_SERVICE_NAME)
370+
->addMethodCall('addMethodMapping', [$methodName, $serviceId]);
371+
}
344372
}

tests/Common/DependencyInjection/AbstractTestClass.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,24 @@ protected function assertEndpointIsUsable()
4848
}
4949

5050
/**
51-
* @param $methodName
5251
* @return Definition
5352
*/
54-
protected function createJsonRpcMethodDefinition($methodName)
53+
protected function createJsonRpcMethodDefinition()
5554
{
56-
$jsonRpcMethodServiceDefinition = new Definition(\stdClass::class);
57-
$jsonRpcMethodServiceDefinition
58-
->setPrivate(false)
59-
->addTag(
60-
self::EXPECTED_JSONRPC_METHOD_TAG,
61-
[self::EXPECTED_JSONRPC_METHOD_TAG_METHOD_NAME_KEY => $methodName]
62-
);
55+
return (new Definition(\stdClass::class))
56+
->setPrivate(false);
57+
}
6358

64-
return $jsonRpcMethodServiceDefinition;
59+
/**
60+
* @param Definition $definition
61+
* @param string $methodName
62+
*/
63+
protected function addJsonRpcMethodTag(Definition $definition, $methodName)
64+
{
65+
$definition->addTag(
66+
self::EXPECTED_JSONRPC_METHOD_TAG,
67+
[self::EXPECTED_JSONRPC_METHOD_TAG_METHOD_NAME_KEY => $methodName]
68+
);
6569
}
6670

6771
/**

tests/Functional/DependencyInjection/JsonRpcHttpServerExtensionTest.php

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,13 @@ public function testHandleManageJsonRpcMethodTag()
9797
$methodName2 = 'my-method-name-2';
9898

9999
// A first method
100-
$this->setDefinition($jsonRpcMethodServiceId, $this->createJsonRpcMethodDefinition($methodName));
100+
$methodService = $this->createJsonRpcMethodDefinition();
101+
$this->addJsonRpcMethodTag($methodService, $methodName);
102+
$this->setDefinition($jsonRpcMethodServiceId, $methodService);
101103
// A second method
102-
$this->setDefinition($jsonRpcMethodServiceId2, $this->createJsonRpcMethodDefinition($methodName2));
104+
$methodService2 = $this->createJsonRpcMethodDefinition();
105+
$this->addJsonRpcMethodTag($methodService2, $methodName2);
106+
$this->setDefinition($jsonRpcMethodServiceId2, $methodService2);
103107

104108
$this->load();
105109

@@ -135,9 +139,13 @@ public function testHandleNotManageJsonRpcMethodTagIfCustomResolverIsUsed()
135139
$methodName2 = 'my-method-name-2';
136140

137141
// A first method
138-
$this->setDefinition($jsonRpcMethodServiceId, $this->createJsonRpcMethodDefinition($methodName));
142+
$methodService = $this->createJsonRpcMethodDefinition();
143+
$this->addJsonRpcMethodTag($methodService, $methodName);
144+
$this->setDefinition($jsonRpcMethodServiceId, $methodService);
139145
// A second method
140-
$this->setDefinition($jsonRpcMethodServiceId2, $this->createJsonRpcMethodDefinition($methodName2));
146+
$methodService2 = $this->createJsonRpcMethodDefinition();
147+
$this->addJsonRpcMethodTag($methodService2, $methodName2);
148+
$this->setDefinition($jsonRpcMethodServiceId2, $methodService2);
141149

142150
// Add the custom method resolver
143151
$this->setDefinition(uniqid(), $this->createCustomMethodResolverDefinition());
@@ -157,19 +165,15 @@ public function testShouldThrowAnExceptionIfJsonRpcMethodUsedWithTagIsDoesNotHav
157165
$jsonRpcMethodServiceId = uniqid();
158166
$jsonRpcMethodServiceId2 = uniqid();
159167
$methodName = 'my-method-name';
160-
$methodName2 = 'my-method-name-2';
161168

162169
// A first method
163-
$this->setDefinition($jsonRpcMethodServiceId, $this->createJsonRpcMethodDefinition($methodName));
164-
// A second method
165-
$this->setDefinition(
166-
$jsonRpcMethodServiceId2,
167-
$this->createJsonRpcMethodDefinition($methodName2)
168-
// Clear previous tag
169-
->clearTag(self::EXPECTED_JSONRPC_METHOD_TAG)
170-
// And add one without attribute
171-
->addTag(self::EXPECTED_JSONRPC_METHOD_TAG)
172-
);
170+
$methodService = $this->createJsonRpcMethodDefinition();
171+
$this->addJsonRpcMethodTag($methodService, $methodName);
172+
$this->setDefinition($jsonRpcMethodServiceId, $methodService);
173+
// A second method with empty tag attribute
174+
$methodService2 = $this->createJsonRpcMethodDefinition();
175+
$methodService2->addTag(self::EXPECTED_JSONRPC_METHOD_TAG);
176+
$this->setDefinition($jsonRpcMethodServiceId2, $methodService2);
173177

174178
$this->expectException(LogicException::class);
175179
// Check that exception is for the second method
@@ -193,12 +197,13 @@ public function testShouldThrowAnExceptionIfJsonRpcMethodUsedWithTagIsNotPublic(
193197
$methodName2 = 'my-method-name-2';
194198

195199
// A first method
196-
$this->setDefinition($jsonRpcMethodServiceId, $this->createJsonRpcMethodDefinition($methodName));
197-
// A second method
198-
$this->setDefinition(
199-
$jsonRpcMethodServiceId2,
200-
$this->createJsonRpcMethodDefinition($methodName2)->setPublic(false)
201-
);
200+
$methodService = $this->createJsonRpcMethodDefinition();
201+
$this->addJsonRpcMethodTag($methodService, $methodName);
202+
$this->setDefinition($jsonRpcMethodServiceId, $methodService);
203+
// A second method with private service
204+
$methodService2 = $this->createJsonRpcMethodDefinition()->setPublic(false);
205+
$this->addJsonRpcMethodTag($methodService2, $methodName2);
206+
$this->setDefinition($jsonRpcMethodServiceId2, $methodService2);
202207

203208
$this->expectException(LogicException::class);
204209
// Check that exception is for the second method

0 commit comments

Comments
 (0)