You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by hu...@apache.org on 2020/04/08 22:53:58 UTC

[helix] 28/50: Make MSDS endpoint configurable for HttpRoutingDataReader (#836)

This is an automated email from the ASF dual-hosted git repository.

hulee pushed a commit to branch zooscalability_merge
in repository https://gitbox.apache.org/repos/asf/helix.git

commit cafe4a3fea3d3fd25bb2649c9454088647c6b260
Author: Hunter Lee <hu...@linkedin.com>
AuthorDate: Fri Feb 28 18:47:41 2020 -0800

    Make MSDS endpoint configurable for HttpRoutingDataReader (#836)
    
    We need to add a few more constructors that allows the users to configure which MSDS to talk to. Applications may wish to create RealmAwareZkClients connecting to different regions or namespaces.
---
 .../zookeeper/util/HttpRoutingDataReader.java      | 77 ++++++++++++++++------
 .../zookeeper/impl/client/TestSharedZkClient.java  | 20 +++++-
 .../zookeeper/util/TestHttpRoutingDataReader.java  |  5 +-
 3 files changed, 79 insertions(+), 23 deletions(-)

diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/util/HttpRoutingDataReader.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/util/HttpRoutingDataReader.java
index b795de0..04f6c44 100644
--- a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/util/HttpRoutingDataReader.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/util/HttpRoutingDataReader.java
@@ -21,6 +21,7 @@ package org.apache.helix.zookeeper.util;
 
 import java.io.IOException;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -41,13 +42,17 @@ import org.apache.http.util.EntityUtils;
 
 
 public class HttpRoutingDataReader {
-  private static final String MSDS_ENDPOINT =
+  private static final String SYSTEM_MSDS_ENDPOINT =
       System.getProperty(MetadataStoreRoutingConstants.MSDS_SERVER_ENDPOINT_KEY);
   private static final int HTTP_TIMEOUT_IN_MS = 5000;
 
   /** Double-checked locking requires that the following fields be volatile */
-  private static volatile Map<String, List<String>> _rawRoutingData;
-  private static volatile MetadataStoreRoutingData _metadataStoreRoutingData;
+  // The following map stands for (MSDS endpoint, Raw Routing Data)
+  private static volatile Map<String, Map<String, List<String>>> _rawRoutingDataMap =
+      new HashMap<>();
+  // The following map stands for (MSDS endpoint, MetadataStoreRoutingData)
+  private static volatile Map<String, MetadataStoreRoutingData> _metadataStoreRoutingDataMap =
+      new HashMap<>();
 
   /**
    * This class is a Singleton.
@@ -56,44 +61,78 @@ public class HttpRoutingDataReader {
   }
 
   /**
-   * Fetches routing data from the data source via HTTP.
-   * @return a mapping from "metadata store realm addresses" to lists of
-   * "metadata store sharding keys", where the sharding keys in a value list all route to
-   * the realm address in the key disallows a meaningful mapping to be returned
+   * Fetches routing data from the data source via HTTP by querying the MSDS configured in the JVM config.
+   * @return
+   * @throws IOException
    */
   public static Map<String, List<String>> getRawRoutingData() throws IOException {
-    if (MSDS_ENDPOINT == null || MSDS_ENDPOINT.isEmpty()) {
+    if (SYSTEM_MSDS_ENDPOINT == null || SYSTEM_MSDS_ENDPOINT.isEmpty()) {
       throw new IllegalStateException(
           "HttpRoutingDataReader was unable to find a valid MSDS endpoint String in System Properties!");
     }
-    if (_rawRoutingData == null) {
+    return getRawRoutingData(SYSTEM_MSDS_ENDPOINT);
+  }
+
+  /**
+   * Fetches routing data from the data source via HTTP.
+   * @return a mapping from "metadata store realm addresses" to lists of
+   * "metadata store sharding keys", where the sharding keys in a value list all route to
+   * the realm address in the key disallows a meaningful mapping to be returned.
+   * @param msdsEndpoint Metadata Store Directory Store endpoint to query from
+   */
+  public static Map<String, List<String>> getRawRoutingData(String msdsEndpoint)
+      throws IOException {
+    Map<String, List<String>> rawRoutingData = _rawRoutingDataMap.get(msdsEndpoint);
+    if (rawRoutingData == null) {
       synchronized (HttpRoutingDataReader.class) {
-        if (_rawRoutingData == null) {
+        rawRoutingData = _rawRoutingDataMap.get(msdsEndpoint);
+        if (rawRoutingData == null) {
           String routingDataJson = getAllRoutingData();
           // Update the reference if reading routingData over HTTP is successful
-          _rawRoutingData = parseRoutingData(routingDataJson);
+          rawRoutingData = parseRoutingData(routingDataJson);
+          _rawRoutingDataMap.put(msdsEndpoint, rawRoutingData);
         }
       }
     }
-    return _rawRoutingData;
+    return rawRoutingData;
+  }
+
+  /**
+   * Returns the routing data read from MSDS in a MetadataStoreRoutingData format by querying the MSDS configured in the JVM config.
+   * @return MetadataStoreRoutingData
+   * @throws IOException
+   * @throws InvalidRoutingDataException
+   */
+  public static MetadataStoreRoutingData getMetadataStoreRoutingData()
+      throws IOException, InvalidRoutingDataException {
+    if (SYSTEM_MSDS_ENDPOINT == null || SYSTEM_MSDS_ENDPOINT.isEmpty()) {
+      throw new IllegalStateException(
+          "HttpRoutingDataReader was unable to find a valid MSDS endpoint String in System Properties!");
+    }
+    return getMetadataStoreRoutingData(SYSTEM_MSDS_ENDPOINT);
   }
 
   /**
    * Returns the routing data read from MSDS in a MetadataStoreRoutingData format.
-   * @return
+   * @param msdsEndpoint Metadata Store Directory Store endpoint to query from
+   * @return MetadataStoreRoutingData
    * @throws IOException if there is an issue connecting to MSDS
    * @throws InvalidRoutingDataException if the raw routing data is not valid
    */
-  public static MetadataStoreRoutingData getMetadataStoreRoutingData()
+  public static MetadataStoreRoutingData getMetadataStoreRoutingData(String msdsEndpoint)
       throws IOException, InvalidRoutingDataException {
-    if (_metadataStoreRoutingData == null) {
+    MetadataStoreRoutingData metadataStoreRoutingData =
+        _metadataStoreRoutingDataMap.get(msdsEndpoint);
+    if (metadataStoreRoutingData == null) {
       synchronized (HttpRoutingDataReader.class) {
-        if (_metadataStoreRoutingData == null) {
-          _metadataStoreRoutingData = new TrieRoutingData(getRawRoutingData());
+        metadataStoreRoutingData = _metadataStoreRoutingDataMap.get(msdsEndpoint);
+        if (metadataStoreRoutingData == null) {
+          metadataStoreRoutingData = new TrieRoutingData(getRawRoutingData(msdsEndpoint));
+          _metadataStoreRoutingDataMap.put(msdsEndpoint, metadataStoreRoutingData);
         }
       }
     }
-    return _metadataStoreRoutingData;
+    return metadataStoreRoutingData;
   }
 
   /**
@@ -105,7 +144,7 @@ public class HttpRoutingDataReader {
     // Note that MSDS_ENDPOINT should provide high-availability - it risks becoming a single point of failure if it's backed by a single IP address/host
     // Retry count is 3 by default.
     HttpGet requestAllData = new HttpGet(
-        MSDS_ENDPOINT + MetadataStoreRoutingConstants.MSDS_GET_ALL_ROUTING_DATA_ENDPOINT);
+        SYSTEM_MSDS_ENDPOINT + MetadataStoreRoutingConstants.MSDS_GET_ALL_ROUTING_DATA_ENDPOINT);
 
     // Define timeout configs
     RequestConfig config = RequestConfig.custom().setConnectTimeout(HTTP_TIMEOUT_IN_MS)
diff --git a/zookeeper-api/src/test/java/org/apache/helix/zookeeper/impl/client/TestSharedZkClient.java b/zookeeper-api/src/test/java/org/apache/helix/zookeeper/impl/client/TestSharedZkClient.java
index 364f66f..1dd44f6 100644
--- a/zookeeper-api/src/test/java/org/apache/helix/zookeeper/impl/client/TestSharedZkClient.java
+++ b/zookeeper-api/src/test/java/org/apache/helix/zookeeper/impl/client/TestSharedZkClient.java
@@ -1,8 +1,26 @@
 package org.apache.helix.zookeeper.impl.client;
 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.zookeeper.datamodel.serializer.ZNRecordSerializer;
-import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
 import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
 import org.apache.zookeeper.CreateMode;
 import org.testng.Assert;
diff --git a/zookeeper-api/src/test/java/org/apache/helix/zookeeper/util/TestHttpRoutingDataReader.java b/zookeeper-api/src/test/java/org/apache/helix/zookeeper/util/TestHttpRoutingDataReader.java
index 83ee471..1eccd1a 100644
--- a/zookeeper-api/src/test/java/org/apache/helix/zookeeper/util/TestHttpRoutingDataReader.java
+++ b/zookeeper-api/src/test/java/org/apache/helix/zookeeper/util/TestHttpRoutingDataReader.java
@@ -87,9 +87,8 @@ public class TestHttpRoutingDataReader extends ZkTestBase {
     Map<String, Set<String>> groupedMappings = allMappings.entrySet().stream().collect(Collectors
         .groupingBy(Map.Entry::getValue,
             Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));
-    _testRawRoutingData.forEach((realm, keys) -> {
-      Assert.assertEquals(groupedMappings.get(realm), new HashSet(keys));
-    });
+    _testRawRoutingData.forEach(
+        (realm, keys) -> Assert.assertEquals(groupedMappings.get(realm), new HashSet(keys)));
   }
 
   /**