/driver-core/src/main/com/mongodb/internal/binding/ClusterBinding.java

http://github.com/mongodb/mongo-java-driver · Java · 190 lines · 129 code · 25 blank · 36 comment · 3 complexity · 3e6273d00e29877abe03b9f7cca4e629 MD5 · raw file

  1. /*
  2. * Copyright 2008-present MongoDB, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.mongodb.internal.binding;
  17. import com.mongodb.ReadConcern;
  18. import com.mongodb.ReadPreference;
  19. import com.mongodb.RequestContext;
  20. import com.mongodb.ServerAddress;
  21. import com.mongodb.ServerApi;
  22. import com.mongodb.connection.ClusterConnectionMode;
  23. import com.mongodb.connection.ServerDescription;
  24. import com.mongodb.internal.connection.Cluster;
  25. import com.mongodb.internal.connection.Connection;
  26. import com.mongodb.internal.connection.ReadConcernAwareNoOpSessionContext;
  27. import com.mongodb.internal.connection.Server;
  28. import com.mongodb.internal.connection.ServerTuple;
  29. import com.mongodb.internal.selector.ReadPreferenceServerSelector;
  30. import com.mongodb.internal.selector.ReadPreferenceWithFallbackServerSelector;
  31. import com.mongodb.internal.selector.ServerAddressSelector;
  32. import com.mongodb.internal.selector.WritableServerSelector;
  33. import com.mongodb.internal.session.SessionContext;
  34. import com.mongodb.lang.Nullable;
  35. import static com.mongodb.assertions.Assertions.notNull;
  36. /**
  37. * A simple ReadWriteBinding implementation that supplies write connection sources bound to a possibly different primary each time, and a
  38. * read connection source bound to a possible different server each time.
  39. *
  40. * @since 3.0
  41. */
  42. public class ClusterBinding extends AbstractReferenceCounted implements ClusterAwareReadWriteBinding {
  43. private final Cluster cluster;
  44. private final ReadPreference readPreference;
  45. private final ReadConcern readConcern;
  46. @Nullable
  47. private final ServerApi serverApi;
  48. private final RequestContext requestContext;
  49. /**
  50. * Creates an instance.
  51. * @param cluster a non-null Cluster which will be used to select a server to bind to
  52. * @param readPreference a non-null ReadPreference for read operations
  53. * @param readConcern a non-null read concern
  54. * @param serverApi a server API, which may be null
  55. * @param requestContext the request context
  56. * @since 3.8
  57. */
  58. public ClusterBinding(final Cluster cluster, final ReadPreference readPreference, final ReadConcern readConcern,
  59. final @Nullable ServerApi serverApi, final RequestContext requestContext) {
  60. this.cluster = notNull("cluster", cluster);
  61. this.readPreference = notNull("readPreference", readPreference);
  62. this.readConcern = notNull("readConcern", readConcern);
  63. this.serverApi = serverApi;
  64. this.requestContext = notNull("requestContext", requestContext);
  65. }
  66. /**
  67. * Return the cluster.
  68. * @return the cluster
  69. * @since 3.11
  70. */
  71. public Cluster getCluster() {
  72. return cluster;
  73. }
  74. @Override
  75. public ReadWriteBinding retain() {
  76. super.retain();
  77. return this;
  78. }
  79. @Override
  80. public ReadPreference getReadPreference() {
  81. return readPreference;
  82. }
  83. @Override
  84. public SessionContext getSessionContext() {
  85. return new ReadConcernAwareNoOpSessionContext(readConcern);
  86. }
  87. @Override
  88. @Nullable
  89. public ServerApi getServerApi() {
  90. return serverApi;
  91. }
  92. @Override
  93. public RequestContext getRequestContext() {
  94. return requestContext;
  95. }
  96. @Override
  97. public ConnectionSource getReadConnectionSource() {
  98. return new ClusterBindingConnectionSource(cluster.selectServer(new ReadPreferenceServerSelector(readPreference)), readPreference);
  99. }
  100. @Override
  101. public ConnectionSource getReadConnectionSource(final int minWireVersion, final ReadPreference fallbackReadPreference) {
  102. // Assume 5.0+ for load-balanced mode
  103. if (cluster.getSettings().getMode() == ClusterConnectionMode.LOAD_BALANCED) {
  104. return getReadConnectionSource();
  105. } else {
  106. ReadPreferenceWithFallbackServerSelector readPreferenceWithFallbackServerSelector
  107. = new ReadPreferenceWithFallbackServerSelector(readPreference, minWireVersion, fallbackReadPreference);
  108. ServerTuple serverTuple = cluster.selectServer(readPreferenceWithFallbackServerSelector);
  109. return new ClusterBindingConnectionSource(serverTuple, readPreferenceWithFallbackServerSelector.getAppliedReadPreference());
  110. }
  111. }
  112. @Override
  113. public ConnectionSource getWriteConnectionSource() {
  114. return new ClusterBindingConnectionSource(cluster.selectServer(new WritableServerSelector()), readPreference);
  115. }
  116. @Override
  117. public ConnectionSource getConnectionSource(final ServerAddress serverAddress) {
  118. return new ClusterBindingConnectionSource(cluster.selectServer(new ServerAddressSelector(serverAddress)), readPreference);
  119. }
  120. private final class ClusterBindingConnectionSource extends AbstractReferenceCounted implements ConnectionSource {
  121. private final Server server;
  122. private final ServerDescription serverDescription;
  123. private final ReadPreference appliedReadPreference;
  124. private ClusterBindingConnectionSource(final ServerTuple serverTuple, final ReadPreference appliedReadPreference) {
  125. this.server = serverTuple.getServer();
  126. this.serverDescription = serverTuple.getServerDescription();
  127. this.appliedReadPreference = appliedReadPreference;
  128. ClusterBinding.this.retain();
  129. }
  130. @Override
  131. public ServerDescription getServerDescription() {
  132. return serverDescription;
  133. }
  134. @Override
  135. public SessionContext getSessionContext() {
  136. return new ReadConcernAwareNoOpSessionContext(readConcern);
  137. }
  138. @Override
  139. public ServerApi getServerApi() {
  140. return serverApi;
  141. }
  142. @Override
  143. public RequestContext getRequestContext() {
  144. return requestContext;
  145. }
  146. @Override
  147. public ReadPreference getReadPreference() {
  148. return appliedReadPreference;
  149. }
  150. @Override
  151. public Connection getConnection() {
  152. return server.getConnection();
  153. }
  154. public ConnectionSource retain() {
  155. super.retain();
  156. ClusterBinding.this.retain();
  157. return this;
  158. }
  159. @Override
  160. public void release() {
  161. super.release();
  162. ClusterBinding.this.release();
  163. }
  164. }
  165. }