You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2016/03/30 15:19:54 UTC
incubator-geode git commit: GEODE-1134: Some scenarios loading
cluster config from dir do not work.
Repository: incubator-geode
Updated Branches:
refs/heads/develop 78bc55d86 -> ffd920735
GEODE-1134: Some scenarios loading cluster config from dir do not work.
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/ffd92073
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/ffd92073
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/ffd92073
Branch: refs/heads/develop
Commit: ffd9207350d612d0c88e27fad45c9b5494203c68
Parents: 78bc55d
Author: Jens Deppe <jd...@pivotal.io>
Authored: Mon Mar 28 07:33:36 2016 -0700
Committer: Jens Deppe <jd...@pivotal.io>
Committed: Wed Mar 30 06:19:15 2016 -0700
----------------------------------------------------------------------
.../internal/SharedConfiguration.java | 17 +-
.../SharedConfigurationUsingDirDUnitTest.java | 322 +++++++++++++++++++
.../internal/configuration/cluster-empty.xml | 30 ++
.../internal/configuration/cluster-region.xml | 33 ++
4 files changed, 394 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ffd92073/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/SharedConfiguration.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/SharedConfiguration.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/SharedConfiguration.java
index 38dd5da..a8f331a 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/SharedConfiguration.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/SharedConfiguration.java
@@ -49,7 +49,6 @@ import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.gemstone.gemfire.CancelException;
-import com.gemstone.gemfire.LogWriter;
import com.gemstone.gemfire.cache.AttributesFactory;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.DataPolicy;
@@ -311,16 +310,18 @@ public class SharedConfiguration {
File zipFile = new File(zipFileName);
byte[] zipBytes = FileUtils.readFileToByteArray(zipFile);
Object [] args = new Object[] {zipFileName, zipBytes};
- CliUtil.executeFunction(fn, args, locatorsWithSC);
+ // Make sure we wait for the result. The fn also does a clear on the config
+ // region so there is a race with the clear below.
+ CliUtil.executeFunction(fn, args, locatorsWithSC).getResult();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
- //Clear the configuration region and load the configuration read from the 'shared_config' directory
- configRegion.clear();
- configRegion.putAll(sharedConfigMap);
- }
- }finally {
+ }
+ //Clear the configuration region and load the configuration read from the 'shared_config' directory
+ configRegion.clear();
+ configRegion.putAll(sharedConfigMap);
+ } finally {
unlockSharedConfiguration();
}
} else {
@@ -372,9 +373,9 @@ public class SharedConfiguration {
boolean isLocked = sharedConfigLockingService.lock(SHARED_CONFIG_LOCK_NAME, 5000, 5000);
try {
if (isLocked) {
- logger.info("Building up configuration response with following configurations");
Set<String> groups = configRequest.getGroups();
groups.add(SharedConfiguration.CLUSTER_CONFIG);
+ logger.info("Building up configuration response with following configurations: {}", groups);
for (String group : groups) {
Configuration configuration = getConfiguration(group);
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ffd92073/geode-core/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationUsingDirDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationUsingDirDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationUsingDirDUnitTest.java
new file mode 100644
index 0000000..b625cfa
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationUsingDirDUnitTest.java
@@ -0,0 +1,322 @@
+/*
+ * 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.
+ */
+package com.gemstone.gemfire.management.internal.configuration;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.distributed.Locator;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.InternalLocator;
+import com.gemstone.gemfire.distributed.internal.SharedConfiguration;
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+import com.gemstone.gemfire.test.dunit.cache.internal.JUnit4CacheTestCase;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+import com.gemstone.gemfire.util.test.TestUtil;
+import com.jayway.awaitility.Awaitility;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import static java.util.stream.Collectors.joining;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+@Category(DistributedTest.class)
+public class SharedConfigurationUsingDirDUnitTest extends JUnit4CacheTestCase {
+
+ @After
+ public void teardown() throws Exception {
+ for (int i = 0; i < 2; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ vm.invoke("Removing shared configuration", () -> {
+ InternalLocator locator = InternalLocator.getLocator();
+ if (locator == null) {
+ return;
+ }
+
+ SharedConfiguration sharedConfig = locator.getSharedConfiguration();
+ if (sharedConfig != null) {
+ sharedConfig.destroySharedConfiguration();
+ }
+ });
+ }
+ }
+
+ @Test
+ public void basicClusterConfigDirWithOneLocator() throws Exception {
+ final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(1);
+ final int locatorCount = ports.length;
+
+ for (int i = 0; i < locatorCount; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ copyClusterXml(vm, "cluster-region.xml");
+ startLocator(vm, i, ports);
+ waitForSharedConfiguration(vm);
+ }
+
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ restartCache(vm, i, ports);
+
+ vm.invoke("Checking for region presence", () -> {
+ Awaitility.waitAtMost(15, TimeUnit.SECONDS).until(() -> getRootRegion("newReplicatedRegion") != null);
+ });
+ }
+ }
+
+ @Test
+ public void basicClusterConfigDirWithTwoLocators() throws Exception {
+ final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+ final int locatorCount = ports.length;
+
+ for (int i = 0; i < locatorCount; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ copyClusterXml(vm, "cluster-region.xml");
+ startLocator(vm, i, ports);
+ waitForSharedConfiguration(vm);
+ }
+
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ restartCache(vm, i, ports);
+
+ vm.invoke("Checking for region presence", () -> {
+ Awaitility.waitAtMost(15, TimeUnit.SECONDS).until(() -> getRootRegion("newReplicatedRegion") != null);
+ });
+ }
+ }
+
+ @Test
+ public void updateClusterConfigDirWithTwoLocatorsNoRollingServerRestart() throws Exception {
+ final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+ final int locatorCount = ports.length;
+
+ for (int i = 0; i < locatorCount; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ copyClusterXml(vm, "cluster-empty.xml");
+ startLocator(vm, i, ports);
+ waitForSharedConfiguration(vm);
+ }
+
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ restartCache(vm, i, ports);
+
+ vm.invoke("Checking for region absence", () -> {
+ Region r = getRootRegion("newReplicatedRegion");
+ assertNull("Region does exist", r);
+ });
+ }
+
+ // Shut down the locators in reverse order to how we will start them up in the next step.
+ // Unless we start them asynchronously, the older one will want to wait for a new diskstore
+ // to become available and will time out.
+ for (int i = locatorCount; i > 0; i--) {
+ VM vm = Host.getHost(0).getVM(i - 1);
+ stopLocator(vm);
+ }
+
+ for (int i = 0; i < locatorCount; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ copyClusterXml(vm, "cluster-region.xml");
+ startLocator(vm, i, ports);
+ waitForSharedConfiguration(vm);
+ }
+
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ vm.invoke(() -> disconnectFromDS());
+ }
+
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ restartCache(vm, i, ports);
+
+ vm.invoke("Checking for region presence", () -> {
+ Awaitility.waitAtMost(15, TimeUnit.SECONDS).until(() -> getRootRegion("newReplicatedRegion") != null);
+ });
+ }
+ }
+
+ @Test
+ public void updateClusterConfigDirWithTwoLocatorsAndRollingServerRestart() throws Exception {
+ final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+ final int locatorCount = ports.length;
+
+ for (int i = 0; i < locatorCount; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ copyClusterXml(vm, "cluster-empty.xml");
+ startLocator(vm, i, ports);
+ waitForSharedConfiguration(vm);
+ }
+
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ restartCache(vm, i, ports);
+
+ vm.invoke("Checking for region absence", () -> {
+ Region r = getRootRegion("newReplicatedRegion");
+ assertNull("Region does exist", r);
+ });
+ }
+
+ // Shut down the locators in reverse order to how we will start them up in the next step.
+ // Unless we start them asynchronously, the older one will want to wait for a new diskstore
+ // to become available and will time out.
+ for (int i = locatorCount; i > 0; i--) {
+ VM vm = Host.getHost(0).getVM(i - 1);
+ stopLocator(vm);
+ }
+
+ for (int i = 0; i < locatorCount; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ copyClusterXml(vm, "cluster-region.xml");
+ startLocator(vm, i, ports);
+ waitForSharedConfiguration(vm);
+ }
+
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ restartCache(vm, i, ports);
+
+ vm.invoke("Checking for region presence", () -> {
+ Awaitility.waitAtMost(15, TimeUnit.SECONDS).until(() -> getRootRegion("newReplicatedRegion") != null);
+ });
+ }
+ }
+
+ @Test
+ public void updateClusterConfigDirWithTwoLocatorsRollingRestartAndRollingServerRestart() throws Exception {
+ final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+ final int locatorCount = ports.length;
+
+ for (int i = 0; i < locatorCount; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ copyClusterXml(vm, "cluster-empty.xml");
+ startLocator(vm, i, ports);
+ waitForSharedConfiguration(vm);
+ }
+
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ restartCache(vm, i, ports);
+
+ vm.invoke("Checking for region absence", () -> {
+ Region r = getRootRegion("newReplicatedRegion");
+ assertNull("Region does exist", r);
+ });
+ }
+
+ // Roll the locators
+ for (int i = locatorCount - 1; i >= 0; i--) {
+ VM vm = Host.getHost(0).getVM(i);
+ stopLocator(vm);
+ copyClusterXml(vm, "cluster-region.xml");
+ startLocator(vm, i, ports);
+ waitForSharedConfiguration(vm);
+ }
+
+ // Roll the servers
+ for (int i = 2; i < 4; i++) {
+ VM vm = Host.getHost(0).getVM(i);
+ restartCache(vm, i, ports);
+
+ vm.invoke("Checking for region presence", () -> {
+ Awaitility.waitAtMost(15, TimeUnit.SECONDS).until(() -> getRootRegion("newReplicatedRegion") != null);
+ });
+ }
+ }
+
+ private void copyClusterXml(final VM vm, final String clusterXml) {
+ vm.invoke("Copying new cluster.xml from " + clusterXml, () -> {
+ String clusterXmlPath = TestUtil.getResourcePath(SharedConfigurationUsingDirDUnitTest.class, clusterXml);
+ InputStream cacheXml = new FileInputStream(clusterXmlPath);
+ assertNotNull("Could not create InputStream from " + clusterXmlPath, cacheXml);
+ Files.createDirectories(Paths.get("cluster_config", "cluster"));
+ Files.copy(cacheXml, Paths.get("cluster_config", "cluster", "cluster.xml"), StandardCopyOption.REPLACE_EXISTING);
+ });
+ }
+
+ private void startLocator(final VM vm, final int i, final int[] locatorPorts) {
+ vm.invoke("Creating locator on " + vm, () -> {
+ final String locatorName = "locator" + i;
+ final File logFile = new File("locator-" + i + ".log");
+ final Properties props = new Properties();
+ props.setProperty(DistributionConfig.NAME_NAME, locatorName);
+ props.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+ props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "true");
+ props.setProperty(DistributionConfig.LOAD_CLUSTER_CONFIG_FROM_DIR_NAME, "true");
+
+ if (locatorPorts.length > 1) {
+ int otherLocatorPort = locatorPorts[(i + 1) % locatorPorts.length];
+ props.setProperty(DistributionConfig.LOCATORS_NAME, "localhost[" + otherLocatorPort + "]");
+ }
+
+ Locator.startLocatorAndDS(locatorPorts[i], logFile, props);
+ });
+ }
+
+ private void waitForSharedConfiguration(final VM vm) {
+ vm.invoke("Waiting for shared configuration", () -> {
+ final InternalLocator locator = InternalLocator.getLocator();
+ Awaitility.waitAtMost(15, TimeUnit.SECONDS).until(() -> {
+ return locator.isSharedConfigurationRunning();
+ });
+ });
+ }
+
+ private void stopLocator(final VM vm) {
+ vm.invoke("Stopping locator on " + vm, () -> {
+ InternalLocator locator = InternalLocator.getLocator();
+ assertNotNull("No locator found", locator);
+ locator.stop();
+ disconnectAllFromDS();
+ });
+ }
+
+ private void restartCache(final VM vm, final int i, final int[] locatorPorts) {
+ vm.invoke("Creating cache on VM " + i, () -> {
+ disconnectFromDS();
+
+ final Properties props = new Properties();
+ props.setProperty(DistributionConfig.NAME_NAME, "member" + i);
+ props.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+ props.setProperty(DistributionConfig.LOCATORS_NAME, getLocatorStr(locatorPorts));
+ props.setProperty(DistributionConfig.LOG_FILE_NAME, "server-" + i + ".log");
+ props.setProperty(DistributionConfig.USE_CLUSTER_CONFIGURATION_NAME, "true");
+ props.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, "true");
+
+ getSystem(props);
+ getCache();
+ });
+ }
+
+ private String getLocatorStr(final int[] locatorPorts) {
+ return Arrays.stream(locatorPorts).mapToObj(p -> "localhost[" + p + "]").collect(joining(","));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ffd92073/geode-core/src/test/resources/com/gemstone/gemfire/management/internal/configuration/cluster-empty.xml
----------------------------------------------------------------------
diff --git a/geode-core/src/test/resources/com/gemstone/gemfire/management/internal/configuration/cluster-empty.xml b/geode-core/src/test/resources/com/gemstone/gemfire/management/internal/configuration/cluster-empty.xml
new file mode 100644
index 0000000..60882e1
--- /dev/null
+++ b/geode-core/src/test/resources/com/gemstone/gemfire/management/internal/configuration/cluster-empty.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<!--
+ Used by com/gemstone/gemfire/management/internal/configuration/SharedConfigurationUsingDirDUnitTest.java
+-->
+<cache xsi:schemaLocation="http://schema.pivotal.io/gemfire/cache http://schema.pivotal.io/gemfire/cache/cache-8.1.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://schema.pivotal.io/gemfire/cache"
+ version="8.1"
+ lock-lease="120"
+ lock-timeout="60"
+ search-timeout="300"
+ is-server="false"
+ copy-on-read="false">
+</cache>
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/ffd92073/geode-core/src/test/resources/com/gemstone/gemfire/management/internal/configuration/cluster-region.xml
----------------------------------------------------------------------
diff --git a/geode-core/src/test/resources/com/gemstone/gemfire/management/internal/configuration/cluster-region.xml b/geode-core/src/test/resources/com/gemstone/gemfire/management/internal/configuration/cluster-region.xml
new file mode 100644
index 0000000..8e8281a
--- /dev/null
+++ b/geode-core/src/test/resources/com/gemstone/gemfire/management/internal/configuration/cluster-region.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<!--
+ Used by com/gemstone/gemfire/management/internal/configuration/SharedConfigurationUsingDirDUnitTest.java
+-->
+<cache xsi:schemaLocation="http://schema.pivotal.io/gemfire/cache http://schema.pivotal.io/gemfire/cache/cache-8.1.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://schema.pivotal.io/gemfire/cache"
+ version="8.1"
+ lock-lease="120"
+ lock-timeout="60"
+ search-timeout="300"
+ is-server="false"
+ copy-on-read="false">
+ <region name="newReplicatedRegion">
+ <region-attributes scope="distributed-ack" data-policy="replicate"/>
+ </region>
+</cache>