blob: 0b3498cecc095962a54a72fcbe48597eb0b3af6f [file] [log] [blame]
/*
* 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.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START;
import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
import static org.apache.geode.distributed.ConfigurationProperties.MAX_WAIT_TIME_RECONNECT;
import static org.apache.geode.distributed.ConfigurationProperties.MEMBER_TIMEOUT;
import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPorts;
import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
import static org.apache.geode.test.dunit.IgnoredException.addIgnoredException;
import static org.apache.geode.test.dunit.VM.getVM;
import static org.apache.geode.test.dunit.VM.getVMId;
import static org.apache.geode.test.dunit.VM.toArray;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.apache.geode.cache.Cache;
import org.apache.geode.distributed.DistributedSystemDisconnectedException;
import org.apache.geode.distributed.LocatorLauncher;
import org.apache.geode.distributed.ServerLauncher;
import org.apache.geode.distributed.internal.InternalLocator;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.rules.DistributedRule;
import org.apache.geode.test.junit.categories.GfshTest;
import org.apache.geode.test.junit.rules.GfshCommandRule;
import org.apache.geode.test.junit.rules.GfshCommandRule.PortType;
import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;
@Category(GfshTest.class)
public class ShutdownCommandOverHttpDUnitTest implements Serializable {
private static final String LOCATOR_NAME = "locator";
private static final String SERVER1_NAME = "server1";
private static final String SERVER2_NAME = "server2";
private static final AtomicReference<LocatorLauncher> LOCATOR_LAUNCHER = new AtomicReference<>();
private static final AtomicReference<ServerLauncher> SERVER_LAUNCHER = new AtomicReference<>();
private VM locator;
private VM server1;
private VM server2;
private String locatorString;
private int locatorPort;
private int locatorJmxPort;
private int locatorHttpPort;
@Rule
public DistributedRule distributedRule = new DistributedRule();
@Rule
public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder();
@Rule
public transient GfshCommandRule gfsh = new GfshCommandRule();
@Before
public void setUp() throws Exception {
locator = getVM(0);
server1 = getVM(1);
server2 = getVM(2);
File locatorDir = temporaryFolder.newFolder(LOCATOR_NAME);
File server1Dir = temporaryFolder.newFolder(SERVER1_NAME);
File server2Dir = temporaryFolder.newFolder(SERVER2_NAME);
int[] ports = getRandomAvailableTCPPorts(3);
locatorPort = ports[0];
locatorJmxPort = ports[1];
locatorHttpPort = ports[2];
locatorString = "localhost[" + locatorPort + "]";
locator.invoke(() -> startLocator(locatorDir, locatorPort, locatorJmxPort, locatorHttpPort));
server1.invoke(() -> startServer(SERVER1_NAME, server1Dir, locatorString));
server2.invoke(() -> startServer(SERVER2_NAME, server2Dir, locatorString));
gfsh.connectAndVerify(locatorHttpPort, PortType.http);
addIgnoredException(DistributedSystemDisconnectedException.class);
}
@Test
public void testShutdownServers() {
String command = "shutdown";
gfsh.executeAndAssertThat(command)
.statusIsSuccess()
.containsOutput("Shutdown is triggered");
for (VM vm : toArray(server1, server2)) {
vm.invoke(() -> verifyNotConnected(SERVER_LAUNCHER.get().getCache()));
}
gfsh.executeAndAssertThat("list members")
.statusIsSuccess();
assertThat(gfsh.getGfshOutput()).contains("locator");
}
@Test
public void testShutdownAll() {
String command = "shutdown --include-locators=true";
gfsh.executeAndAssertThat(command)
.statusIsSuccess()
.containsOutput("Shutdown is triggered");
server1.invoke(() -> verifyNotConnected(SERVER_LAUNCHER.get().getCache()));
server2.invoke(() -> verifyNotConnected(SERVER_LAUNCHER.get().getCache()));
locator.invoke(() -> verifyNotConnected(LOCATOR_LAUNCHER.get().getCache()));
}
private void verifyNotConnected(Cache cache) {
await().untilAsserted(() -> {
assertThat(cache.getDistributedSystem().isConnected())
.as("cache.getDistributedSystem().isConnected()")
.isFalse();
});
}
private void startLocator(File directory, int port, int jmxPort, int httpPort) {
LOCATOR_LAUNCHER.set(new LocatorLauncher.Builder()
.setDeletePidFileOnStop(true)
.setMemberName(LOCATOR_NAME)
.setPort(port)
.setWorkingDirectory(directory.getAbsolutePath())
.set(HTTP_SERVICE_PORT, String.valueOf(httpPort))
.set(JMX_MANAGER, "true")
.set(JMX_MANAGER_PORT, String.valueOf(jmxPort))
.set(JMX_MANAGER_START, "true")
.set(LOG_FILE, new File(directory, LOCATOR_NAME + ".log").getAbsolutePath())
.set(MAX_WAIT_TIME_RECONNECT, "1000")
.set(MEMBER_TIMEOUT, "2000")
.build());
LOCATOR_LAUNCHER.get().start();
InternalLocator locator = (InternalLocator) LOCATOR_LAUNCHER.get().getLocator();
await().untilAsserted(() -> {
assertThat(locator.isSharedConfigurationRunning())
.as("Locator shared configuration is running on locator" + getVMId())
.isTrue();
});
}
private void startServer(String name, File workingDirectory, String locator) {
SERVER_LAUNCHER.set(new ServerLauncher.Builder()
.setDeletePidFileOnStop(true)
.setDisableDefaultServer(true)
.setMemberName(name)
.setWorkingDirectory(workingDirectory.getAbsolutePath())
.set(HTTP_SERVICE_PORT, "0")
.set(LOCATORS, locator)
.set(LOG_FILE, new File(workingDirectory, name + ".log").getAbsolutePath())
.set(MAX_WAIT_TIME_RECONNECT, "1000")
.set(MEMBER_TIMEOUT, "2000")
.build());
SERVER_LAUNCHER.get().start();
}
}