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 Oct 19, 2024
1 parent 94c322f commit c400834
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 9 deletions.
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
14 changes: 14 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function getConfigTreeBuilder(): TreeBuilder
$this->addDataCollection($rootBuilder->children());
$this->addClients($rootBuilder->children());
$this->addConnections($rootBuilder->children());
$this->addUriOptions($rootBuilder->children());
$this->addDriversOption($rootBuilder->children());

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

private function addUriOptions(NodeBuilder $builder): void
{
$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');
}
}
6 changes: 6 additions & 0 deletions src/DependencyInjection/MongoDbBundleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,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 @@ -111,6 +112,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
22 changes: 16 additions & 6 deletions src/Services/ClientRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Facile\MongoDbBundle\Event\ConnectionEvent;
use Facile\MongoDbBundle\Models\ClientConfiguration;
use Facile\MongoDbBundle\Services\DriverOptions\DriverOptionsInterface;
use Facile\MongoDbBundle\Services\UriOptions\UriOptionsInterface;
use MongoDB\Client;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

Expand All @@ -28,16 +29,20 @@ final class ClientRegistry

private EventDispatcherInterface $eventDispatcher;

private ?UriOptionsInterface $uriOptionsService;

private ?DriverOptionsInterface $driverOptionsService;

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

public function addClientsConfigurations(array $configurations): void
Expand All @@ -53,6 +58,16 @@ private function buildClientConfiguration(array $conf): ClientConfiguration
$conf['uri'] = $this->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 @@ -63,12 +78,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 @@ -17,7 +17,7 @@ class ClientRegistryTest extends TestCase

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

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

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

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

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

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

0 comments on commit c400834

Please sign in to comment.