Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GEODE-6918: Adding log message to denote end of startup #3824

Merged
merged 32 commits into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d3fd406
Log when server with no async tasks is done
demery-pivotal Jul 8, 2019
a68881d
WIP server online is logged after redundancy recovered
demery-pivotal Jul 8, 2019
d7dad60
Rebase on develop and fix tests.
kirklund Jul 9, 2019
21a00bb
Make test assert order of log lines
moleske Jul 10, 2019
ee9b52e
WIP wiring up InternalResourceManager and ServerLauncher
demery-pivotal Jul 11, 2019
5969d17
ServerLauncher waits on startup tasks before reporting server is online
moleske Jul 11, 2019
b814749
Write failing test for redundancy recovery completion task
demery-pivotal Jul 11, 2019
8e6f1bf
Use rebalance op factory to create rebalance op
demery-pivotal Jul 12, 2019
5b84a6a
Does not mark startup task complete if rebalance op throws
demery-pivotal Jul 12, 2019
1512060
Do not report startup task if rebalance not started
demery-pivotal Jul 12, 2019
84ebba2
Clean up
moleske Jul 12, 2019
cd56c6b
Add second region to Recovery Notification Test
moleske Jul 12, 2019
427353e
Use a Collection for tracking startup tasks
moleske Jul 15, 2019
2dac7e8
Spotless miss and fix integrationTest
moleske Jul 15, 2019
281a56e
Add server name to startup log message
demery-pivotal Jul 16, 2019
4c25023
Server start log line includes member name and startup duration
demery-pivotal Jul 16, 2019
3104d40
ServerStartupNotificationTest now expects correct log line
demery-pivotal Jul 16, 2019
110db71
Spotless
demery-pivotal Jul 17, 2019
515b3ce
Clear startup tasks when creating final CompletableFuture when asking to
Jul 17, 2019
44c32ac
Spotless
Jul 17, 2019
d686f15
Add ability to call exception action when an exception occurs in a
Jul 18, 2019
3511b1a
Log a message when server startup completes with error(s)
Jul 18, 2019
8948071
Add acceptance test for failing startup task
Jul 18, 2019
a1fd5bb
Add ServiceJarRule to create JARs for tests
Jul 18, 2019
aa37864
Update GatewayReceiverMetricsTest to use ServiceJarRule
Jul 18, 2019
75362e7
Complete exceptionally if exception is thrown in
Jul 19, 2019
08ec329
Add acceptance tests for failing startup tasks
Jul 19, 2019
47fd7d0
Add startup task for disk value recovery
Jul 19, 2019
afc2332
GEODE-6918: Added log message to denote end of startup
kirklund Jul 22, 2019
1128eb4
GEODE-6918: fixing a merge issue.
kirklund Jul 22, 2019
7c73260
GEODE-6918: Adding the license text
kirklund Jul 23, 2019
2b15f53
Remove unnecessary test code
moleske Jul 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* 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.launchers;

import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.CompletionException;
import java.util.regex.Pattern;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;

import org.apache.geode.distributed.ServerLauncherCacheProvider;
import org.apache.geode.launchers.startuptasks.CompletingAndFailing;
import org.apache.geode.launchers.startuptasks.Failing;
import org.apache.geode.launchers.startuptasks.MultipleFailing;
import org.apache.geode.rules.ServiceJarRule;
import org.apache.geode.test.junit.rules.gfsh.GfshRule;

public class ServerStartupNotificationTest {

@Rule
public GfshRule gfshRule = new GfshRule();

@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Rule
public TestName testName = new TestName();

@Rule
public ServiceJarRule serviceJarRule = new ServiceJarRule();

private File serverFolder;
private String serverName;

@Before
public void setup() {
serverFolder = temporaryFolder.getRoot();
serverName = testName.getMethodName();
}

@After
public void stopServer() {
String stopServerCommand = "stop server --dir=" + serverFolder.getAbsolutePath();
gfshRule.execute(stopServerCommand);
}

@Test
public void startupWithNoAsyncTasks() {
String startServerCommand = String.join(" ",
"start server",
"--name=" + serverName,
"--dir=" + serverFolder.getAbsolutePath(),
"--disable-default-server");

gfshRule.execute(startServerCommand);

Path logFile = serverFolder.toPath().resolve(serverName + ".log");

Pattern expectedLogLine =
Pattern.compile("^\\[info .*].*Server " + serverName + " startup completed in \\d+ ms");
await().untilAsserted(() -> assertThat(Files.lines(logFile))
.as("Log file " + logFile + " includes line matching " + expectedLogLine)
.anyMatch(expectedLogLine.asPredicate()));
}

@Test
public void startupWithFailingAsyncTask() {
String serviceJarPath = serviceJarRule.createJarFor("ServerLauncherCacheProvider.jar",
ServerLauncherCacheProvider.class, Failing.class);

String startServerCommand = String.join(" ",
"start server",
"--name=" + serverName,
"--dir=" + serverFolder.getAbsolutePath(),
"--classpath=" + serviceJarPath,
"--disable-default-server");

gfshRule.execute(startServerCommand);

Path logFile = serverFolder.toPath().resolve(serverName + ".log");

Exception exception = Failing.EXCEPTION;
String errorDetail = CompletionException.class.getName() + ": " +
exception.getClass().getName() + ": " + exception.getMessage();

Pattern expectedLogLine = Pattern.compile("^\\[error .*].*Server " + serverName +
" startup completed in \\d+ ms with error: " + errorDetail);

await().untilAsserted(() -> assertThat(Files.lines(logFile))
.as("Log file " + logFile + " includes line matching " + expectedLogLine)
.anyMatch(expectedLogLine.asPredicate()));
}

@Test
public void startupWithMultipleFailingAsyncTasks() {
String serviceJarPath = serviceJarRule.createJarFor("ServerLauncherCacheProvider.jar",
ServerLauncherCacheProvider.class, MultipleFailing.class);

String startServerCommand = String.join(" ",
"start server",
"--name=" + serverName,
"--dir=" + serverFolder.getAbsolutePath(),
"--classpath=" + serviceJarPath,
"--disable-default-server");

gfshRule.execute(startServerCommand);

Path logFile = serverFolder.toPath().resolve(serverName + ".log");

Exception exception = MultipleFailing.EXCEPTION;
String errorDetail = CompletionException.class.getName() + ": " +
exception.getClass().getName() + ": " + exception.getMessage();

Pattern expectedLogLine = Pattern.compile("^\\[error .*].*Server " + serverName +
" startup completed in \\d+ ms with error: " + errorDetail);

await().untilAsserted(() -> assertThat(Files.lines(logFile))
.as("Log file " + logFile + " includes line matching " + expectedLogLine)
.anyMatch(expectedLogLine.asPredicate()));
}

@Test
public void startupWithCompletingAndFailingAsyncTasks() {
String serviceJarPath = serviceJarRule.createJarFor("ServerLauncherCacheProvider.jar",
ServerLauncherCacheProvider.class, CompletingAndFailing.class);

String startServerCommand = String.join(" ",
"start server",
"--name=" + serverName,
"--dir=" + serverFolder.getAbsolutePath(),
"--classpath=" + serviceJarPath,
"--disable-default-server");

gfshRule.execute(startServerCommand);

Path logFile = serverFolder.toPath().resolve(serverName + ".log");

Exception exception = CompletingAndFailing.EXCEPTION;
String errorDetail = CompletionException.class.getName() + ": " +
exception.getClass().getName() + ": " + exception.getMessage();

Pattern expectedLogLine = Pattern.compile("^\\[error .*].*Server " + serverName +
" startup completed in \\d+ ms with error: " + errorDetail);

await().untilAsserted(() -> assertThat(Files.lines(logFile))
.as("Log file " + logFile + " includes line matching " + expectedLogLine)
.anyMatch(expectedLogLine.asPredicate()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*
* 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.launchers;

import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;

import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.test.junit.rules.gfsh.GfshRule;

public class ServerStartupRedundancyRecoveryNotificationTest {

private static final String SERVER_1_NAME = "server1";
private static final String SERVER_2_NAME = "server2";
private static final String LOCATOR_NAME = "locator";

@Rule
public GfshRule gfshRule = new GfshRule();

@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Rule
public TestName testName = new TestName();

private Path locatorFolder;
private Path server1Folder;
private Path server2Folder;
private int locatorPort;
private String startServer1Command;
private String regionName;
private String regionNameTwo;

@Before
public void redundantRegionThatRequiresRedundancyRecovery() throws IOException {
locatorFolder = temporaryFolder.newFolder(LOCATOR_NAME).toPath().toAbsolutePath();
server1Folder = temporaryFolder.newFolder(SERVER_1_NAME).toPath().toAbsolutePath();
server2Folder = temporaryFolder.newFolder(SERVER_2_NAME).toPath().toAbsolutePath();

locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();

String startLocatorCommand = String.join(" ",
"start locator",
"--name=" + LOCATOR_NAME,
"--dir=" + locatorFolder,
"--port=" + locatorPort,
"--locators=localhost[" + locatorPort + "]");

startServer1Command = String.join(" ",
"start server",
"--name=" + SERVER_1_NAME,
"--dir=" + server1Folder,
"--locators=localhost[" + locatorPort + "]",
"--disable-default-server");

String startServer2Command = String.join(" ",
"start server",
"--name=" + SERVER_2_NAME,
"--dir=" + server2Folder,
"--locators=localhost[" + locatorPort + "]",
"--disable-default-server");

regionName = "myRegion";
String createRegionCommand = String.join(" ",
"create region",
"--name=" + regionName,
"--type=PARTITION_REDUNDANT",
"--redundant-copies=1");

regionNameTwo = "mySecondRegion";
String createRegionTwoCommand = String.join(" ",
"create region",
"--name=" + regionNameTwo,
"--type=PARTITION_REDUNDANT",
"--redundant-copies=1");

String putCommand = String.join(" ",
"put",
"--region=" + regionName,
"--key=James",
"--value=Bond");

String putCommandInRegionTwo = String.join(" ",
"put",
"--region=" + regionNameTwo,
"--key=Derrick",
"--value=Flint");

gfshRule.execute(startLocatorCommand, startServer1Command, startServer2Command,
createRegionCommand, createRegionTwoCommand, putCommand, putCommandInRegionTwo);

String stopServer1Command = "stop server --dir=" + server1Folder;
gfshRule.execute(stopServer1Command);
}

@After
public void stopAllMembers() {
String stopServer1Command = "stop server --dir=" + server1Folder;
String stopServer2Command = "stop server --dir=" + server2Folder;
String stopLocatorCommand = "stop locator --dir=" + locatorFolder;
gfshRule.execute(stopServer1Command, stopServer2Command, stopLocatorCommand);
}

@Test
public void startupReportsOnlineOnlyAfterRedundancyRestored() throws IOException {
String connectCommand = "connect --locator=localhost[" + locatorPort + "]";
server1Folder =
temporaryFolder.newFolder(SERVER_1_NAME + "secondfolder").toPath().toAbsolutePath();
startServer1Command = String.join(" ",
"start server",
"--name=" + SERVER_1_NAME,
"--dir=" + server1Folder,
"--locators=localhost[" + locatorPort + "]");

gfshRule.execute(connectCommand, startServer1Command);

Pattern serverOnlinePattern =
Pattern.compile("^\\[info .*].*Server " + SERVER_1_NAME + " startup completed in \\d+ ms");
Pattern redundancyRestoredPattern =
Pattern.compile(
"^\\[info .*].*Configured redundancy of 2 copies has been restored to /" + regionName
+ ".*");
Pattern redundancyRestoredSecondRegionPattern =
Pattern.compile(
"^\\[info .*].*Configured redundancy of 2 copies has been restored to /" + regionNameTwo
+ ".*");

Path logFile = server1Folder.resolve(SERVER_1_NAME + ".log");

await()
.untilAsserted(() -> {
final Predicate<String> isRelevantLine = redundancyRestoredPattern.asPredicate()
.or(redundancyRestoredSecondRegionPattern.asPredicate())
.or(serverOnlinePattern.asPredicate());

final List<String> foundPatterns =
Files.lines(logFile).filter(isRelevantLine)
.collect(Collectors.toList());

assertThat(foundPatterns)
.as("Log file " + logFile + " includes one line matching each of "
+ redundancyRestoredPattern + ", " + redundancyRestoredSecondRegionPattern
+ ", and "
+ serverOnlinePattern)
.hasSize(3);

assertThat(foundPatterns)
.as("lines in the log file")
.withFailMessage("%n Expect line matching %s %n but was %s",
redundancyRestoredPattern.pattern(), foundPatterns)
.anyMatch(redundancyRestoredPattern.asPredicate())
.withFailMessage("%n Expect line matching %s %n but was %s",
redundancyRestoredSecondRegionPattern.pattern(), foundPatterns)
.anyMatch(redundancyRestoredSecondRegionPattern.asPredicate());

assertThat(foundPatterns.get(2))
.as("Third matching Log line of " + foundPatterns)
.matches(serverOnlinePattern.asPredicate(), serverOnlinePattern.pattern());
});
}
}