Browse Source

Internal: extract gateway required allocation calculations

and add a basic test

Closes #13391
Boaz Leskes 10 years ago
parent
commit
30ca6d3970

+ 30 - 25
core/src/main/java/org/elasticsearch/gateway/Gateway.java

@@ -32,7 +32,6 @@ import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.NodeEnvironment;
 
-
 import java.nio.file.Path;
 
 /**
@@ -73,30 +72,8 @@ public class Gateway extends AbstractComponent implements ClusterStateListener {
         TransportNodesListGatewayMetaState.NodesGatewayMetaState nodesState = listGatewayMetaState.list(nodesIds.toArray(String.class), null).actionGet();
 
 
-        int requiredAllocation = 1;
-        try {
-            if ("quorum".equals(initialMeta)) {
-                if (nodesIds.size() > 2) {
-                    requiredAllocation = (nodesIds.size() / 2) + 1;
-                }
-            } else if ("quorum-1".equals(initialMeta) || "half".equals(initialMeta)) {
-                if (nodesIds.size() > 2) {
-                    requiredAllocation = ((1 + nodesIds.size()) / 2);
-                }
-            } else if ("one".equals(initialMeta)) {
-                requiredAllocation = 1;
-            } else if ("full".equals(initialMeta) || "all".equals(initialMeta)) {
-                requiredAllocation = nodesIds.size();
-            } else if ("full-1".equals(initialMeta) || "all-1".equals(initialMeta)) {
-                if (nodesIds.size() > 1) {
-                    requiredAllocation = nodesIds.size() - 1;
-                }
-            } else {
-                requiredAllocation = Integer.parseInt(initialMeta);
-            }
-        } catch (Exception e) {
-            logger.warn("failed to derived initial_meta from value {}", initialMeta);
-        }
+        int requiredAllocation = calcRequiredAllocations(this.initialMeta, nodesIds.size());
+
 
         if (nodesState.failures().length > 0) {
             for (FailedNodeException failedNodeException : nodesState.failures()) {
@@ -163,6 +140,34 @@ public class Gateway extends AbstractComponent implements ClusterStateListener {
         listener.onSuccess(builder.build());
     }
 
+    protected int calcRequiredAllocations(final String setting, final int nodeCount) {
+        int requiredAllocation = 1;
+        try {
+            if ("quorum".equals(setting)) {
+                if (nodeCount > 2) {
+                    requiredAllocation = (nodeCount / 2) + 1;
+                }
+            } else if ("quorum-1".equals(setting) || "half".equals(setting)) {
+                if (nodeCount > 2) {
+                    requiredAllocation = ((1 + nodeCount) / 2);
+                }
+            } else if ("one".equals(setting)) {
+                requiredAllocation = 1;
+            } else if ("full".equals(setting) || "all".equals(setting)) {
+                requiredAllocation = nodeCount;
+            } else if ("full-1".equals(setting) || "all-1".equals(setting)) {
+                if (nodeCount > 1) {
+                    requiredAllocation = nodeCount - 1;
+                }
+            } else {
+                requiredAllocation = Integer.parseInt(setting);
+            }
+        } catch (Exception e) {
+            logger.warn("failed to derived initial_meta from value {}", setting);
+        }
+        return requiredAllocation;
+    }
+
     public void reset() throws Exception {
         try {
             Path[] dataPaths = nodeEnv.nodeDataPaths();

+ 67 - 0
core/src/test/java/org/elasticsearch/gateway/GatewayTests.java

@@ -0,0 +1,67 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.
+ */
+package org.elasticsearch.gateway;
+
+import org.elasticsearch.cluster.ClusterName;
+import org.elasticsearch.cluster.ClusterService;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.test.ESTestCase;
+import org.elasticsearch.test.cluster.TestClusterService;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+
+
+public class GatewayTests extends ESTestCase {
+
+    public void testCalcRequiredAllocations() {
+        MockGateway gateway = new MockGateway(Settings.EMPTY, new TestClusterService());
+        int nodeCount = randomIntBetween(1, 6);
+        Map<String, Integer> expectedResult = new HashMap<>();
+        expectedResult.put("quorum", nodeCount > 2 ? nodeCount / 2 + 1 : 1);
+        expectedResult.put("quorum-1", nodeCount > 2 ? (nodeCount + 1) / 2 : 1);
+        expectedResult.put("half", expectedResult.get("quorum-1"));
+        expectedResult.put("one", 1);
+        expectedResult.put("full", nodeCount);
+        expectedResult.put("all", nodeCount);
+        expectedResult.put("full-1", Math.max(1, nodeCount - 1));
+        expectedResult.put("all-1", Math.max(1, nodeCount - 1));
+        int i = randomIntBetween(1, 20);
+        expectedResult.put("" + i, i);
+        expectedResult.put(randomUnicodeOfCodepointLength(10), 1);
+        for (String setting : expectedResult.keySet()) {
+            assertThat("unexpected result for setting [" + setting + "]", gateway.calcRequiredAllocations(setting, nodeCount), equalTo(expectedResult.get(setting).intValue()));
+        }
+
+    }
+
+    static class MockGateway extends Gateway {
+
+        MockGateway(Settings settings, ClusterService clusterService) {
+            super(settings, clusterService, null, null, null, ClusterName.DEFAULT);
+        }
+
+        @Override
+        public int calcRequiredAllocations(String setting, int nodeCount) {
+            return super.calcRequiredAllocations(setting, nodeCount);
+        }
+    }
+}