Repository: quarkusio/quarkus
Issue: wrong initialisation order of mongo codec providers

**Describe the bug**
It is impossible to override standard coders, `MongoClients.createMongoConfiguration()` uses `defaultCodecRegistry` before custom `CodecProvider`:
```java
        CodecRegistry registry = CodecRegistries.fromRegistries(defaultCodecRegistry,
                CodecRegistries.fromProviders(providers));
        settings.codecRegistry(registry);
```

**Expected behavior**
Custom providers should be used at the first place:
```java
        CodecRegistry registry = CodecRegistries.fromRegistries(CodecRegistries.fromProviders(providers), defaultCodecRegistry);
```
this is also recommended by mongodb-team [Codec and CodecRegistry](https://mongodb.github.io/mongo-java-driver/3.6/bson/codecs/):
```java
CodecRegistry defaultCodecRegistry = ... 
DocumentCodecProvider documentCodecProvider = ... 
Codec<Instant> instantCodec = ...   
codecRegistry = CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(instantCodec),
                                               CodecRegistries.fromProviders(documentCodecProvider),
                                               defaultCodecRegistry);
```

**Actual behavior**
codecs registry is initialized with default codes at the first place and this will not allow to override them. reading of the `BigDecimal` value will not use a custom `Codec` and will fail with the message:
```
Caused by: org.bson.BsonInvalidOperationException: readDecimal can only be called when CurrentBSONType is DECIMAL128, not when CurrentBSONType is STRING.
	at org.bson.AbstractBsonReader.verifyBSONType(AbstractBsonReader.java:690)
	at org.bson.AbstractBsonReader.checkPreconditions(AbstractBsonReader.java:722)
	at org.bson.AbstractBsonReader.readDecimal128(AbstractBsonReader.java:380)
	at org.bson.codecs.BigDecimalCodec.decode(BigDecimalCodec.java:39)
	at org.bson.codecs.BigDecimalCodec.decode(BigDecimalCodec.java:30)
	at org.bson.codecs.DecoderContext.decodeWithChildContext(DecoderContext.java:96)
	at org.bson.codecs.pojo.PojoCodecImpl.decodePropertyModel(PojoCodecImpl.java:219)
	... 106 more
```

**To Reproduce**
Please check this repository [quarkus-mongo-bug](https://github.com/oxelad/quarkus-mongo-bug.git)

Steps to reproduce the behavior:
run tests: `mvn clean verify` ; integration tests will fail.

**Environment (please complete the following information):**
 - Output of `uname -a` or `ver`:  `Darwin Kernel Version 19.6.0`
 - Output of `java -version`:  `java version "11.0.9" 2020-10-20 LTS`
 - Build tool (ie. output of `mvnw --version` or `gradlew --version`): `Apache Maven 3.6.3`


Changed files:
extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java

diff --git a/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java b/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java
index 68b720924a6..a1f7f7a396d 100644
--- a/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java
+++ b/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java
@@ -4,6 +4,8 @@
 import static com.mongodb.AuthenticationMechanism.MONGODB_X509;
 import static com.mongodb.AuthenticationMechanism.PLAIN;
 import static com.mongodb.AuthenticationMechanism.SCRAM_SHA_1;
+import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
+import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
 
 import java.lang.reflect.Constructor;
 import java.util.ArrayList;
@@ -21,7 +23,6 @@
 import javax.inject.Singleton;
 
 import org.bson.codecs.configuration.CodecProvider;
-import org.bson.codecs.configuration.CodecRegistries;
 import org.bson.codecs.configuration.CodecRegistry;
 import org.bson.codecs.pojo.ClassModel;
 import org.bson.codecs.pojo.Conventions;
@@ -226,35 +227,7 @@ private MongoClientSettings createMongoConfiguration(MongoClientConfig config) {
             settings.applyConnectionString(connectionString);
         }
 
-        List<CodecProvider> providers = new ArrayList<>();
-        if (!mongoClientSupport.getCodecProviders().isEmpty()) {
-            providers.addAll(getCodecProviders(mongoClientSupport.getCodecProviders()));
-        }
-        // add pojo codec provider with automatic capabilities
-        // it always needs to be the last codec provided
-        PojoCodecProvider.Builder pojoCodecProviderBuilder = PojoCodecProvider.builder()
-                .automatic(true)
-                .conventions(Conventions.DEFAULT_CONVENTIONS);
-        // register bson discriminators
-        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-        for (String bsonDiscriminator : mongoClientSupport.getBsonDiscriminators()) {
-            try {
-                pojoCodecProviderBuilder
-                        .register(ClassModel.builder(Class.forName(bsonDiscriminator, true, classLoader))
-                                .enableDiscriminator(true).build());
-            } catch (ClassNotFoundException e) {
-                // Ignore
-            }
-        }
-        // register property codec provider
-        if (!mongoClientSupport.getPropertyCodecProviders().isEmpty()) {
-            pojoCodecProviderBuilder.register(getPropertyCodecProviders(mongoClientSupport.getPropertyCodecProviders())
-                    .toArray(new PropertyCodecProvider[0]));
-        }
-        providers.add(pojoCodecProviderBuilder.build());
-        CodecRegistry registry = CodecRegistries.fromRegistries(defaultCodecRegistry,
-                CodecRegistries.fromProviders(providers));
-        settings.codecRegistry(registry);
+        configureCodecRegistry(defaultCodecRegistry, settings);
 
         settings.commandListenerList(getCommandListeners(mongoClientSupport.getCommandListeners()));
 
@@ -299,6 +272,38 @@ private MongoClientSettings createMongoConfiguration(MongoClientConfig config) {
         return settings.build();
     }
 
+    private void configureCodecRegistry(CodecRegistry defaultCodecRegistry, MongoClientSettings.Builder settings) {
+        List<CodecProvider> providers = new ArrayList<>();
+        if (!mongoClientSupport.getCodecProviders().isEmpty()) {
+            providers.addAll(getCodecProviders(mongoClientSupport.getCodecProviders()));
+        }
+        // add pojo codec provider with automatic capabilities
+        // it always needs to be the last codec provided
+        PojoCodecProvider.Builder pojoCodecProviderBuilder = PojoCodecProvider.builder()
+                .automatic(true)
+                .conventions(Conventions.DEFAULT_CONVENTIONS);
+        // register bson discriminators
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        for (String bsonDiscriminator : mongoClientSupport.getBsonDiscriminators()) {
+            try {
+                pojoCodecProviderBuilder
+                        .register(ClassModel.builder(Class.forName(bsonDiscriminator, true, classLoader))
+                                .enableDiscriminator(true).build());
+            } catch (ClassNotFoundException e) {
+                // Ignore
+            }
+        }
+        // register property codec provider
+        if (!mongoClientSupport.getPropertyCodecProviders().isEmpty()) {
+            pojoCodecProviderBuilder.register(getPropertyCodecProviders(mongoClientSupport.getPropertyCodecProviders())
+                    .toArray(new PropertyCodecProvider[0]));
+        }
+        CodecRegistry registry = !providers.isEmpty() ? fromRegistries(fromProviders(providers), defaultCodecRegistry,
+                fromProviders(pojoCodecProviderBuilder.build()))
+                : fromRegistries(defaultCodecRegistry, fromProviders(pojoCodecProviderBuilder.build()));
+        settings.codecRegistry(registry);
+    }
+
     private static List<ServerAddress> parseHosts(List<String> addresses) {
         if (addresses.isEmpty()) {
             return Collections.singletonList(new ServerAddress(ServerAddress.defaultHost(), ServerAddress.defaultPort()));