diff --git a/src/Connection.php b/src/Connection.php index d802e83f6..a859bfa63 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -9,6 +9,10 @@ use InvalidArgumentException; use MongoDB\Client; use MongoDB\Database; +use MongoDB\Driver\Exception\AuthenticationException; +use MongoDB\Driver\Exception\ConnectionException; +use MongoDB\Driver\Exception\RuntimeException; +use MongoDB\Driver\ReadPreference; use MongoDB\Laravel\Concerns\ManagesTransactions; use Throwable; @@ -189,6 +193,18 @@ protected function createConnection(string $dsn, array $config, array $options): return new Client($dsn, $options, $driverOptions); } + /** + * Check the connection to the MongoDB server + * + * @throws ConnectionException if connection to the server fails (for reasons other than authentication). + * @throws AuthenticationException if authentication is needed and fails. + * @throws RuntimeException if a server matching the read preference could not be found. + */ + public function ping(): void + { + $this->getMongoClient()->getManager()->selectServer(new ReadPreference(ReadPreference::PRIMARY_PREFERRED)); + } + /** @inheritdoc */ public function disconnect() { diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php index b46168df8..262c4cafc 100644 --- a/tests/ConnectionTest.php +++ b/tests/ConnectionTest.php @@ -9,11 +9,13 @@ use InvalidArgumentException; use MongoDB\Client; use MongoDB\Database; +use MongoDB\Driver\Exception\ConnectionTimeoutException; use MongoDB\Laravel\Collection; use MongoDB\Laravel\Connection; use MongoDB\Laravel\Query\Builder; use MongoDB\Laravel\Schema\Builder as SchemaBuilder; +use function env; use function spl_object_hash; class ConnectionTest extends TestCase @@ -231,4 +233,29 @@ public function testDriverName() $driver = DB::connection('mongodb')->getDriverName(); $this->assertEquals('mongodb', $driver); } + + public function testPingMethod() + { + $config = [ + 'name' => 'mongodb', + 'driver' => 'mongodb', + 'dsn' => env('MONGODB_URI', 'mongodb://127.0.0.1/'), + 'database' => 'unittest', + 'options' => [ + 'connectTimeoutMS' => 100, + 'serverSelectionTimeoutMS' => 250, + ], + ]; + + $instance = new Connection($config); + $instance->ping(); + + $this->expectException(ConnectionTimeoutException::class); + $this->expectExceptionMessage("No suitable servers found (`serverSelectionTryOnce` set): [Failed to resolve 'wrong-host']"); + + $config['dsn'] = 'mongodb://wrong-host/'; + + $instance = new Connection($config); + $instance->ping(); + } }