| /* |
| * 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 org.apache.geode.management.internal.cli.commands; |
| |
| import static org.apache.geode.lang.Identifiable.find; |
| import static org.assertj.core.api.Assertions.assertThat; |
| |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.experimental.categories.Category; |
| import org.junit.rules.TemporaryFolder; |
| import org.junit.rules.TestName; |
| |
| import org.apache.geode.cache.configuration.CacheConfig; |
| import org.apache.geode.cache.configuration.RegionConfig; |
| import org.apache.geode.distributed.internal.InternalLocator; |
| import org.apache.geode.test.dunit.IgnoredException; |
| import org.apache.geode.test.dunit.rules.ClusterStartupRule; |
| import org.apache.geode.test.dunit.rules.MemberVM; |
| import org.apache.geode.test.junit.categories.WanTest; |
| import org.apache.geode.test.junit.rules.GfshCommandRule; |
| import org.apache.geode.test.junit.rules.serializable.SerializableTestName; |
| |
| @Category(WanTest.class) |
| public class AlterRegionCommandDUnitTest { |
| private static MemberVM locator; |
| |
| @Rule |
| public GfshCommandRule gfsh = new GfshCommandRule(); |
| |
| @Rule |
| public TestName testName = new SerializableTestName(); |
| |
| @Rule |
| public ClusterStartupRule lsRule = new ClusterStartupRule(); |
| |
| @Rule |
| public TemporaryFolder temporaryFolder = new TemporaryFolder(); |
| |
| @Before |
| public void before() throws Exception { |
| locator = lsRule.startLocatorVM(0); |
| lsRule.startServerVM(1, locator.getPort()); |
| |
| gfsh.connectAndVerify(locator); |
| gfsh.executeAndAssertThat( |
| "create disk-store --name=diskStore --dir=" + temporaryFolder.getRoot()) |
| .statusIsSuccess() |
| .doesNotContainOutput("Did not complete waiting"); |
| } |
| |
| @Test |
| public void alterPartitionRegionWithParallelAsynchronousEventQueueShouldPersistTheChangesIntoTheClusterConfigurationService() { |
| String regionName = testName.getMethodName(); |
| String asyncEventQueueName = "asyncEventQueue1"; |
| |
| gfsh.executeAndAssertThat( |
| "create async-event-queue --parallel=true --persistent=false --listener=org.apache.geode.internal.cache.wan.MyAsyncEventListener --id=" |
| + asyncEventQueueName) |
| .statusIsSuccess(); |
| locator.waitUntilAsyncEventQueuesAreReadyOnExactlyThisManyServers(asyncEventQueueName, 1); |
| |
| gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + regionName) |
| .statusIsSuccess(); |
| locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 1); |
| |
| // Associate the async-event-queue |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + regionName + " --async-event-queue-id=" + asyncEventQueueName) |
| .statusIsSuccess().containsOutput("server-1", "OK", "Region " + regionName + " altered"); |
| |
| // Check the cluster configuration service. |
| locator.invoke(() -> { |
| InternalLocator internalLocator = ClusterStartupRule.getLocator(); |
| assertThat(internalLocator).isNotNull(); |
| CacheConfig config = |
| internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster"); |
| |
| RegionConfig regionConfig = find(config.getRegions(), regionName); |
| assertThat(regionConfig).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes()).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes().getAsyncEventQueueIds()).isNotEmpty() |
| .isEqualTo(asyncEventQueueName); |
| }); |
| } |
| |
| @Test |
| public void alterNonColocatedPartitionRegionWithTheSameParallelAsynchronousEventQueueShouldThrowExceptionAndPreventTheClusterConfigurationServiceFromBeingUpdated() { |
| IgnoredException.addIgnoredException( |
| "Non colocated regions (.*) cannot have the same parallel async event queue id (.*) configured."); |
| |
| String asyncEventQueue = "asyncEventQueue"; |
| String region1Name = testName.getMethodName() + "1"; |
| String region2Name = testName.getMethodName() + "2"; |
| |
| gfsh.executeAndAssertThat( |
| "create async-event-queue --parallel=true --persistent=false --listener=org.apache.geode.internal.cache.wan.MyAsyncEventListener --id=" |
| + asyncEventQueue) |
| .statusIsSuccess(); |
| locator.waitUntilAsyncEventQueuesAreReadyOnExactlyThisManyServers(asyncEventQueue, 1); |
| |
| gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + region1Name) |
| .statusIsSuccess(); |
| locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + region1Name, 1); |
| |
| gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + region2Name) |
| .statusIsSuccess(); |
| locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + region2Name, 1); |
| |
| // Associate the async-event-queue to both regions (second one should fail because they are not |
| // co-located) |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + region1Name + " --async-event-queue-id=" + asyncEventQueue) |
| .statusIsSuccess().containsOutput("server-1", "OK", "Region " + region1Name + " altered"); |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + region2Name + " --async-event-queue-id=" + asyncEventQueue) |
| .statusIsError().containsOutput("server-1", "ERROR", |
| "Non colocated regions /" + region2Name + ", /" + region1Name |
| + " cannot have the same parallel async event queue id " + asyncEventQueue |
| + " configured."); |
| |
| // The exception must be thrown early in the initialization, so the change shouldn't be |
| // persisted to the cluster configuration service for the second region. |
| locator.invoke(() -> { |
| InternalLocator internalLocator = ClusterStartupRule.getLocator(); |
| assertThat(internalLocator).isNotNull(); |
| CacheConfig config = |
| internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster"); |
| |
| RegionConfig regionConfig = find(config.getRegions(), region1Name); |
| assertThat(regionConfig).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes()).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes().getAsyncEventQueueIds()) |
| .isEqualTo(asyncEventQueue); |
| |
| RegionConfig region2Config = find(config.getRegions(), region2Name); |
| assertThat(region2Config).isNotNull(); |
| assertThat(region2Config.getRegionAttributes()).isNotNull(); |
| assertThat(region2Config.getRegionAttributes().getAsyncEventQueueIds()).isBlank(); |
| }); |
| } |
| |
| @Test |
| public void alterPartitionPersistentRegionWithParallelNonPersistentAsynchronousEventQueueShouldThrowExceptionAndPreventTheClusterConfigurationServiceFromBeingUpdated() { |
| IgnoredException.addIgnoredException( |
| "Non persistent asynchronous event queue (.*) can not be attached to persistent region (.*)"); |
| String regionName = testName.getMethodName(); |
| String asyncEventQueueName = "asyncEventQueue"; |
| |
| gfsh.executeAndAssertThat( |
| "create async-event-queue --parallel=true --persistent=false --listener=org.apache.geode.internal.cache.wan.MyAsyncEventListener --id=" |
| + asyncEventQueueName) |
| .statusIsSuccess(); |
| locator.waitUntilAsyncEventQueuesAreReadyOnExactlyThisManyServers(asyncEventQueueName, 1); |
| |
| gfsh.executeAndAssertThat("create region --type=PARTITION_PERSISTENT --name=" + regionName |
| + " --disk-store=diskStore").statusIsSuccess(); |
| locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 1); |
| |
| // Make sure that the next invocations also fail and that the changes are not persisted to the |
| // cluster configuration service. See GEODE-6551. |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + regionName + " --async-event-queue-id=" + asyncEventQueueName) |
| .statusIsError() |
| .containsOutput("server-1", "ERROR", "Non persistent asynchronous event queue " |
| + asyncEventQueueName + " can not be attached to persistent region /" + regionName); |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + regionName + " --async-event-queue-id=" + asyncEventQueueName) |
| .statusIsError() |
| .containsOutput("server-1", "ERROR", "Non persistent asynchronous event queue " |
| + asyncEventQueueName + " can not be attached to persistent region /" + regionName); |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + regionName + " --async-event-queue-id=" + asyncEventQueueName) |
| .statusIsError() |
| .containsOutput("server-1", "ERROR", "Non persistent asynchronous event queue " |
| + asyncEventQueueName + " can not be attached to persistent region /" + regionName); |
| |
| // The exception must be thrown early in the initialization, so the change shouldn't be |
| // persisted to the cluster configuration service. |
| locator.invoke(() -> { |
| InternalLocator internalLocator = ClusterStartupRule.getLocator(); |
| assertThat(internalLocator).isNotNull(); |
| CacheConfig config = |
| internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster"); |
| |
| RegionConfig regionConfig = find(config.getRegions(), regionName); |
| assertThat(regionConfig).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes()).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes().getAsyncEventQueueIds()).isBlank(); |
| }); |
| } |
| |
| @Test |
| public void alterPartitionRegionWithParallelGatewaySenderShouldPersistTheChangesIntoTheClusterConfigurationService() { |
| IgnoredException.addIgnoredException("could not get remote locator information"); |
| String regionName = testName.getMethodName(); |
| String gatewaySenderName = "gatewaySender"; |
| |
| gfsh.executeAndAssertThat( |
| "create gateway-sender --parallel=true --enable-persistence=false --remote-distributed-system-id=2 --id=" |
| + gatewaySenderName) |
| .statusIsSuccess() |
| .doesNotContainOutput("Did not complete waiting"); |
| |
| gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + regionName) |
| .statusIsSuccess(); |
| locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 1); |
| |
| // Associate the gateway-sender |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + regionName + " --gateway-sender-id=" + gatewaySenderName) |
| .statusIsSuccess().containsOutput("server-1", "OK", "Region " + regionName + " altered"); |
| |
| // Check the cluster configuration service. |
| locator.invoke(() -> { |
| InternalLocator internalLocator = ClusterStartupRule.getLocator(); |
| assertThat(internalLocator).isNotNull(); |
| CacheConfig config = |
| internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster"); |
| |
| RegionConfig regionConfig = find(config.getRegions(), regionName); |
| assertThat(regionConfig).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes()).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes().getGatewaySenderIds()).isNotEmpty() |
| .isEqualTo(gatewaySenderName); |
| }); |
| } |
| |
| @Test |
| public void alterNonColocatedPartitionRegionWithTheSameParallelGatewaySenderShouldThrowExceptionAndPreventTheClusterConfigurationServiceFromBeingUpdated() { |
| IgnoredException.addIgnoredException("could not get remote locator information"); |
| IgnoredException.addIgnoredException( |
| "Non colocated regions (.*) cannot have the same parallel gateway sender id (.*) configured."); |
| |
| String gatewaySenderName = "gatewaySender"; |
| String region1Name = testName.getMethodName() + "1"; |
| String region2Name = testName.getMethodName() + "2"; |
| |
| gfsh.executeAndAssertThat( |
| "create gateway-sender --parallel=true --enable-persistence=false --remote-distributed-system-id=2 --id=" |
| + gatewaySenderName) |
| .statusIsSuccess() |
| .doesNotContainOutput("Did not complete waiting"); |
| |
| gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + region1Name) |
| .statusIsSuccess(); |
| locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + region1Name, 1); |
| |
| gfsh.executeAndAssertThat("create region --type=PARTITION --name=" + region2Name) |
| .statusIsSuccess(); |
| locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + region2Name, 1); |
| |
| // Associate the gateway-sender to both regions (second one should fail because they are not |
| // co-located) |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + region1Name + " --gateway-sender-id=" + gatewaySenderName) |
| .statusIsSuccess().containsOutput("server-1", "OK", "Region " + region1Name + " altered"); |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + region2Name + " --gateway-sender-id=" + gatewaySenderName) |
| .statusIsError().containsOutput("server-1", "ERROR", |
| "Non colocated regions /" + region2Name + ", /" + region1Name |
| + " cannot have the same parallel gateway sender id " + gatewaySenderName |
| + " configured."); |
| |
| // The exception must be thrown early in the initialization, so the change shouldn't be |
| // persisted to the cluster configuration service for the second region. |
| locator.invoke(() -> { |
| InternalLocator internalLocator = ClusterStartupRule.getLocator(); |
| assertThat(internalLocator).isNotNull(); |
| CacheConfig config = |
| internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster"); |
| |
| RegionConfig regionConfig = find(config.getRegions(), region1Name); |
| assertThat(regionConfig).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes()).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes().getGatewaySenderIds()) |
| .isEqualTo(gatewaySenderName); |
| |
| RegionConfig region2Config = find(config.getRegions(), region2Name); |
| assertThat(region2Config).isNotNull(); |
| assertThat(region2Config.getRegionAttributes()).isNotNull(); |
| assertThat(region2Config.getRegionAttributes().getGatewaySenderIds()).isBlank(); |
| }); |
| } |
| |
| @Test |
| public void alterPartitionPersistentRegionWithParallelNonPersistentGatewaySenderShouldThrowExceptionAndPreventTheClusterConfigurationServiceFromBeingUpdated() { |
| IgnoredException.addIgnoredException("could not get remote locator information"); |
| IgnoredException.addIgnoredException( |
| "Non persistent gateway sender (.*) can not be attached to persistent region (.*)"); |
| String regionName = testName.getMethodName(); |
| String gatewaySenderName = "gatewaySender"; |
| |
| gfsh.executeAndAssertThat( |
| "create gateway-sender --parallel=true --enable-persistence=false --remote-distributed-system-id=2 --id=" |
| + gatewaySenderName) |
| .statusIsSuccess() |
| .doesNotContainOutput("Did not complete waiting"); |
| |
| gfsh.executeAndAssertThat("create region --type=PARTITION_PERSISTENT --name=" + regionName |
| + " --disk-store=diskStore").statusIsSuccess(); |
| locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + regionName, 1); |
| |
| // Make sure that the next invocations also fail and that the changes are not persisted to the |
| // cluster configuration service. See GEODE-6551. |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + regionName + " --gateway-sender-id=" + gatewaySenderName) |
| .statusIsError().containsOutput("server-1", "ERROR", "Non persistent gateway sender " |
| + gatewaySenderName + " can not be attached to persistent region /" + regionName); |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + regionName + " --gateway-sender-id=" + gatewaySenderName) |
| .statusIsError().containsOutput("server-1", "ERROR", "Non persistent gateway sender " |
| + gatewaySenderName + " can not be attached to persistent region /" + regionName); |
| gfsh.executeAndAssertThat( |
| "alter region --name=" + regionName + " --gateway-sender-id=" + gatewaySenderName) |
| .statusIsError().containsOutput("server-1", "ERROR", "Non persistent gateway sender " |
| + gatewaySenderName + " can not be attached to persistent region /" + regionName); |
| |
| // The exception must be thrown early in the initialization, so the change shouldn't be |
| // persisted to the cluster configuration service. |
| locator.invoke(() -> { |
| InternalLocator internalLocator = ClusterStartupRule.getLocator(); |
| assertThat(internalLocator).isNotNull(); |
| CacheConfig config = |
| internalLocator.getConfigurationPersistenceService().getCacheConfig("cluster"); |
| |
| RegionConfig regionConfig = find(config.getRegions(), regionName); |
| assertThat(regionConfig).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes()).isNotNull(); |
| assertThat(regionConfig.getRegionAttributes().getGatewaySenderIds()).isBlank(); |
| }); |
| } |
| } |