Skip to content

Commit

Permalink
Allow customizing URI options more
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniele Scibilia committed May 10, 2023
1 parent 1cf9334 commit 63ddbda
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 12 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"facile-it/facile-coding-standard": "^0.4.0",
"phpstan/phpstan": "^0.12.88",
"phpstan/extension-installer": "^1.1",
"jangregor/phpstan-prophecy": "^0.8.1"
"jangregor/phpstan-prophecy": "^0.8.1",
"phpspec/prophecy": "~1.0"
},
"minimum-stability": "stable",
"suggest": {
Expand Down
47 changes: 47 additions & 0 deletions docs/Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,57 @@ mongo_db_bundle:
client_name: ~
database_name: ~

# Service reference to provide URI options - see example below
uriOptions: 'App\Services\UriOptionsProvider' # default null

# Service reference to provide driver options - see example below
driverOptions: 'App\Services\DriverOptionsProvider' # default null
```
### Uri options
You might need to specify some URI options for constructing the `MongoDB\Client`. Read the [reference] for a complete
explanation of all the available options.

Implement `UriOptionsInterface` and declare the class as a Symfony service.

```php
namespace App\Services;
use Facile\MongoDbBundle\Services\UriOptions\UriOptionsInterface;
final class MyCustomUriOptionsProvider implements DriverOptionsInterface
{
/** @var string */
private $appname;
public function __construct(string $appname) {
$this->appname = $appname;
}
public function buildDriverOptions(array $clientConfiguration) : array {
$clientConfiguration['appname'] = $this->appname;
return $clientConfiguration;
}
}
```

```yaml
# config/services.yaml
App\Services\MyCustomUriOptionsProvider:
arguments:
$appname: 'APPNAME'
```

Then use its service id as value of `uriOptions` in the bundle configuration.

```yml
# config/packages/facile_it_mongodb.yaml
mongo_db_bundle:
uriOptions: 'App\Services\MyCustomUriOptionsProvider'
# ...
```

### Driver options

You might need to specify some driver options for constructing the `MongoDB\Client`. Read the [reference] for a complete
Expand Down
20 changes: 20 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function getConfigTreeBuilder(): TreeBuilder
self::addDataCollection($rootBuilder->children());
self::addClients($rootBuilder->children());
self::addConnections($rootBuilder->children());
self::addUriOptions($rootBuilder->children());
self::addDriversOption($rootBuilder->children());

return $treeBuilder;
Expand Down Expand Up @@ -134,4 +135,23 @@ private static function addConnections(NodeBuilder $builder): void
->isRequired()
->info('Database name');
}


private static function addUriOptions(NodeBuilder $builder)
{
$uriOptionsBuilder = $builder
->arrayNode('uriOptions')
->info('Additional connection string options')
->children();

$uriOptionsBuilder
->variableNode('context')
->defaultValue([])
->info('Overwrite any options with the same name in the uri parameter');
}

private function addDriversOptionFactory(NodeBuilder $builder) {
$connectionBuilder = $builder
->scalarNode('driverOptions');
}
}
6 changes: 6 additions & 0 deletions src/DependencyInjection/MongoDbBundleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ private function defineClientRegistry(array $config, bool $debug): void
[
new Reference('facile_mongo_db.event_dispatcher'),
$debug,
$this->defineUriOptionsFactory($config),
$this->defineDriverOptionsFactory($config),
]
);
Expand Down Expand Up @@ -114,6 +115,11 @@ private function attachDataCollectionListenerToEventManager(): void
);
}

private function defineUriOptionsFactory(array $config): ?Reference
{
return isset($config['uriOptions']) ? new Reference($config['uriOptions']) : null;
}

private function defineDriverOptionsFactory(array $config): ?Reference
{
return isset($config['driverOptions']) ? new Reference($config['driverOptions']) : null;
Expand Down
26 changes: 18 additions & 8 deletions src/Services/ClientRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Facile\MongoDbBundle\Capsule\Client as BundleClient;
use Facile\MongoDbBundle\Event\ConnectionEvent;
use Facile\MongoDbBundle\Models\ClientConfiguration;
use Facile\MongoDbBundle\Services\UriOptions\UriOptionsInterface;
use Facile\MongoDbBundle\Services\DriverOptions\DriverOptionsInterface;
use MongoDB\Client;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
Expand All @@ -31,19 +32,23 @@ final class ClientRegistry
/** @var EventDispatcherInterface */
private $eventDispatcher;

/** @var UriOptionsInterface */
private $uriOptionsService;
/** @var DriverOptionsInterface */
private $driverOptionsService;

public function __construct(
EventDispatcherInterface $eventDispatcher,
bool $debug,
?DriverOptionsInterface $driverOptionsService
bool $debug,
?UriOptionsInterface $uriOptionsService,
?DriverOptionsInterface $driverOptionsService
) {
$this->clients = [];
$this->configurations = [];
$this->debug = $debug;
$this->eventDispatcher = $eventDispatcher;
$this->driverOptionsService = $driverOptionsService;
$this->uriOptionsService = $uriOptionsService;
}

public function addClientsConfigurations(array $configurations): void
Expand All @@ -64,6 +69,16 @@ private function buildClientConfiguration(array $conf): ClientConfiguration
$conf['uri'] = self::buildConnectionUri($conf['hosts']);
}

$conf['uriOptions'] = [
'replicaSet' => $conf['replicaSet'],
'ssl' => $conf['ssl'],
'connectTimeoutMS' => $conf['connectTimeoutMS'],
'readPreference' => $conf['readPreference'],
];
if ($this->uriOptionsService instanceof UriOptionsInterface) {
$conf['options'] = $this->uriOptionsService->buildUriOptions($conf['uriOptions']);
}

$conf['driverOptions'] = [];
if ($this->driverOptionsService instanceof DriverOptionsInterface) {
$conf['driverOptions'] = $this->driverOptionsService->buildDriverOptions($conf);
Expand All @@ -74,12 +89,7 @@ private function buildClientConfiguration(array $conf): ClientConfiguration
$conf['username'],
$conf['password'],
$conf['authSource'],
[
'replicaSet' => $conf['replicaSet'],
'ssl' => $conf['ssl'],
'connectTimeoutMS' => $conf['connectTimeoutMS'],
'readPreference' => $conf['readPreference'],
],
$conf['uriOptions'],
$conf['driverOptions']
);
}
Expand Down
22 changes: 22 additions & 0 deletions src/Services/UriOptions/UriOptionsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Facile\MongoDbBundle\Services\UriOptions;

use MongoDB\Client;

interface UriOptionsInterface
{
/**
* It creates an array of options for constructing a MongoDB\Client
*
* @param array $clientConfiguration client's bundle configuration for which the options are needed
*
* @return array Options for MongoDB\Client
*
* @see Client
* @see http://php.net/manual/en/mongodb-driver-manager.construct.php
*/
public function buildUriOptions(array $clientConfiguration): array;
}
6 changes: 3 additions & 3 deletions tests/Unit/Services/ClientRegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ClientRegistryTest extends TestCase
{
public function test_client_connection_url_provided_manually()
{
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null);
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null);

$testConf = [
'test_client' => [
Expand All @@ -41,7 +41,7 @@ public function test_client_connection_url_provided_manually()

public function test_client_connection_url_generation_singlehost()
{
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null);
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null);

$testConf = [
'test_client' => [
Expand Down Expand Up @@ -69,7 +69,7 @@ public function test_client_connection_url_generation_singlehost()

public function test_client_connection_url_generation_multihost()
{
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null);
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null);

$testConf = [
'test_client' => [
Expand Down

0 comments on commit 63ddbda

Please sign in to comment.