pkuwm commented on a change in pull request #855: Make ZkBaseDataAccessor 
realm-aware
URL: https://github.com/apache/helix/pull/855#discussion_r389317008
 
 

 ##########
 File path: 
helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
 ##########
 @@ -1248,4 +1289,122 @@ public void close() {
       _zkClient.close();
     }
   }
+
+  public static class Builder {
+    private String zkAddress;
+    private RealmAwareZkClient.RealmMode realmMode;
+    private ZkBaseDataAccessor.ZkClientType zkClientType;
+    private RealmAwareZkClient.RealmAwareZkConnectionConfig 
realmAwareZkConnectionConfig;
+    private RealmAwareZkClient.RealmAwareZkClientConfig 
realmAwareZkClientConfig;
+
+    public Builder() {
+    }
+
+    public ZkBaseDataAccessor.Builder setZkAddress(String zkAddress) {
+      this.zkAddress = zkAddress;
+      return this;
+    }
+
+    public ZkBaseDataAccessor.Builder 
setRealmMode(RealmAwareZkClient.RealmMode realmMode) {
+      this.realmMode = realmMode;
+      return this;
+    }
+
+    public ZkBaseDataAccessor.Builder setZkClientType(
+        ZkBaseDataAccessor.ZkClientType zkClientType) {
+      this.zkClientType = zkClientType;
+      return this;
+    }
+
+    public ZkBaseDataAccessor.Builder setRealmAwareZkConnectionConfig(
+        RealmAwareZkClient.RealmAwareZkConnectionConfig 
realmAwareZkConnectionConfig) {
+      this.realmAwareZkConnectionConfig = realmAwareZkConnectionConfig;
+      return this;
+    }
+
+    public ZkBaseDataAccessor.Builder setRealmAwareZkClientConfig(
+        RealmAwareZkClient.RealmAwareZkClientConfig realmAwareZkClientConfig) {
+      this.realmAwareZkClientConfig = realmAwareZkClientConfig;
+      return this;
+    }
+
+    public ZkBaseDataAccessor<?> build() throws Exception {
+      validate();
+      return new ZkBaseDataAccessor<>(this);
+    }
+
+    /**
+     * Validate the given parameters before creating an instance of 
ConfigAccessor.
+     */
+    private void validate() {
+      // Resolve RealmMode based on other parameters
+      boolean isZkAddressSet = zkAddress != null && !zkAddress.isEmpty();
+      boolean isZkClientTypeSet = zkClientType != null;
+
+      if (realmMode == RealmAwareZkClient.RealmMode.SINGLE_REALM && 
!isZkAddressSet) {
+        throw new HelixException(
+            "RealmMode cannot be single-realm without a valid ZkAddress set!");
+      }
+      if (realmMode == null) {
+        realmMode = isZkAddressSet ? RealmAwareZkClient.RealmMode.SINGLE_REALM
+            : RealmAwareZkClient.RealmMode.MULTI_REALM;
+      }
+
+      // If ZkClientType is set, RealmMode must either be single-realm or not 
set.
+      if (isZkClientTypeSet && realmMode == 
RealmAwareZkClient.RealmMode.MULTI_REALM) {
+        throw new HelixException(
+            "ZkClientType cannot be set on multi-realm mode!");
+      }
+      // If ZkClientType is not set, default to SHARED
+      if (!isZkClientTypeSet) {
+        zkClientType = ZkBaseDataAccessor.ZkClientType.SHARED;
+      }
+
+      // Resolve RealmAwareZkClientConfig
+      boolean isZkClientConfigSet = realmAwareZkClientConfig != null;
+      // Resolve which clientConfig to use
+      realmAwareZkClientConfig =
+          isZkClientConfigSet ? 
realmAwareZkClientConfig.createHelixZkClientConfig()
+              : new HelixZkClient.ZkClientConfig().setZkSerializer(new 
ZNRecordSerializer());
+
+      // Resolve RealmAwareZkConnectionConfig
+      if (realmAwareZkConnectionConfig == null) {
+        // If not set, create a default one
+        realmAwareZkConnectionConfig =
+            new 
RealmAwareZkClient.RealmAwareZkConnectionConfig.Builder().build();
+      }
+    }
+  }
+
+  private RealmAwareZkClient buildRealmAwareZkClient(
+      RealmAwareZkClient.RealmAwareZkClientConfig clientConfig, String 
zkAddress,
+      ZkClientType zkClientType) {
+    try {
+      return new FederatedZkClient(
+          new 
RealmAwareZkClient.RealmAwareZkConnectionConfig.Builder().build(), 
clientConfig);
+    } catch (IllegalStateException | IOException | InvalidRoutingDataException 
e) {
+      // Fall back to connect on single-realm mode if failed to connect on 
multi-realm mode and
+      // ZK address is not empty.
+      LOG.info("Not able to connect on multi-realm mode, caused by: {}. "
+          + "Connecting on single-realm mode to ZK: {}.", e.getMessage(), 
zkAddress);
+    }
+
+    RealmAwareZkClient zkClient;
+
+    switch (zkClientType) {
+      case DEDICATED:
+        zkClient = DedicatedZkClientFactory.getInstance()
+            .buildZkClient(new HelixZkClient.ZkConnectionConfig(zkAddress),
+                clientConfig.createHelixZkClientConfig());
+        break;
+      case SHARED:
+      default:
+        zkClient = SharedZkClientFactory.getInstance()
+            .buildZkClient(new HelixZkClient.ZkConnectionConfig(zkAddress),
+                clientConfig.createHelixZkClientConfig());
+        break;
 
 Review comment:
   It is just my habit: As a matter of good form, put a break after the last 
case (the default here) even though it's logically unnecessary. Some day when 
another case gets added at the end, this bit of defensive programming will save 
you.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to