blob: 35913ba619f85d55b1e6001e1e390460bc5c4d1a [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.bookkeeper.bookie;
import static org.apache.bookkeeper.util.BookKeeperConstants.COOKIE_NODE;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.List;
import org.apache.bookkeeper.conf.ServerConfiguration;
import org.apache.bookkeeper.discover.RegistrationManager;
import org.apache.bookkeeper.meta.MetadataBookieDriver;
import org.apache.bookkeeper.meta.MetadataDrivers;
import org.apache.bookkeeper.meta.zk.ZKMetadataDriverBase;
import org.apache.bookkeeper.proto.BookieServer;
import org.apache.bookkeeper.stats.NullStatsLogger;
import org.apache.bookkeeper.test.BookKeeperClusterTestCase;
import org.apache.bookkeeper.versioning.Version;
import org.apache.zookeeper.KeeperException;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This tests 'updatecookie' shell command.
*/
public class UpdateCookieCmdTest extends BookKeeperClusterTestCase {
private static final Logger LOG = LoggerFactory.getLogger(UpdateCookieCmdTest.class);
MetadataBookieDriver driver;
RegistrationManager rm;
public UpdateCookieCmdTest() {
super(1);
useUUIDasBookieId = false;
}
@Override
public void setUp() throws Exception {
super.setUp();
LOG.info("setUp ZKRegistrationManager");
baseConf.setMetadataServiceUri(zkUtil.getMetadataServiceUri());
driver = MetadataDrivers.getBookieDriver(
URI.create(baseConf.getMetadataServiceUri()));
driver.initialize(baseConf, () -> {}, NullStatsLogger.INSTANCE);
rm = driver.getRegistrationManager();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
if (driver != null) {
driver.close();
}
}
/**
* updatecookie to hostname.
*/
@Test
public void testUpdateCookieIpAddressToHostname() throws Exception {
updateCookie("-bookieId", "hostname", true);
}
/**
* updatecookie to short hostname.
*/
@Test
public void testUpdateCookieIpAddressToShortHostname() throws Exception {
updateCookie("-bookieId", "hostname", true, true);
}
/**
* updatecookie to ipaddress.
*/
@Test
public void testUpdateCookieHostnameToIpAddress() throws Exception {
updateCookie("-bookieId", "hostname", true);
updateCookie("-b", "ip", false);
// start bookie to ensure everything works fine
ServerConfiguration conf = bsConfs.get(0);
BookieServer restartBookie = startBookie(conf);
restartBookie.shutdown();
}
/**
* updatecookie to invalid bookie id.
*/
@Test
public void testUpdateCookieWithInvalidOption() throws Exception {
String[] argv = new String[] { "updatecookie", "-b", "invalidBookieID" };
final ServerConfiguration conf = bsConfs.get(0);
updateCookie(argv, -1, conf);
argv = new String[] { "updatecookie", "-b" };
updateCookie(argv, -1, conf);
argv = new String[] { "updatecookie" };
updateCookie(argv, -1, conf);
// conf not updated
argv = new String[] { "updatecookie", "-b", "hostname" };
conf.setUseHostNameAsBookieID(false);
updateCookie(argv, -1, conf);
argv = new String[] { "updatecookie", "-b", "ip" };
conf.setUseHostNameAsBookieID(true);
updateCookie(argv, -1, conf);
}
/**
* During first updatecookie it successfully created the hostname cookie but
* it fails to delete the old ipaddress cookie. Here user will issue
* updatecookie again, now it should be able to delete the old cookie
* gracefully.
*/
@Test
public void testWhenBothIPaddressAndHostNameCookiesExists() throws Exception {
updateCookie("-b", "hostname", true);
// creates cookie with ipaddress
ServerConfiguration conf = bsConfs.get(0);
conf.setUseHostNameAsBookieID(true); // sets to hostname
Cookie cookie = Cookie.readFromRegistrationManager(rm, conf).getValue();
Cookie.Builder cookieBuilder = Cookie.newBuilder(cookie);
conf.setUseHostNameAsBookieID(false); // sets to hostname
final String newBookieHost = BookieImpl.getBookieAddress(conf).toString();
cookieBuilder.setBookieId(newBookieHost);
cookieBuilder.build().writeToRegistrationManager(rm, conf, Version.NEW);
verifyCookieInZooKeeper(conf, 2);
// again issue hostname cmd
BookieShell bkShell = new BookieShell();
conf.setUseHostNameAsBookieID(true); // sets to hostname
bkShell.setConf(conf);
String[] argv = new String[] { "updatecookie", "-b", "hostname" };
Assert.assertEquals("Failed to return the error code!", 0, bkShell.run(argv));
conf.setUseHostNameAsBookieID(true);
cookie = Cookie.readFromRegistrationManager(rm, conf).getValue();
Assert.assertFalse("Cookie has created with IP!", cookie.isBookieHostCreatedFromIp());
// ensure the old cookie is deleted
verifyCookieInZooKeeper(conf, 1);
}
/**
* updatecookie to hostname.
*/
@Test
public void testDuplicateUpdateCookieIpAddress() throws Exception {
String[] argv = new String[] { "updatecookie", "-b", "ip" };
final ServerConfiguration conf = bsConfs.get(0);
conf.setUseHostNameAsBookieID(true);
updateCookie(argv, -1, conf);
}
@Test
public void testWhenNoCookieExists() throws Exception {
ServerConfiguration conf = bsConfs.get(0);
BookieServer bks = bs.get(0);
bks.shutdown();
String zkCookiePath = ZKMetadataDriverBase.resolveZkLedgersRootPath(conf)
+ "/" + COOKIE_NODE + "/" + BookieImpl.getBookieAddress(conf);
Assert.assertNotNull("Cookie path doesn't still exists!", zkc.exists(zkCookiePath, false));
zkc.delete(zkCookiePath, -1);
Assert.assertNull("Cookie path still exists!", zkc.exists(zkCookiePath, false));
BookieShell bkShell = new BookieShell();
conf.setUseHostNameAsBookieID(true);
bkShell.setConf(conf);
String[] argv = new String[] { "updatecookie", "-b", "hostname" };
Assert.assertEquals("Failed to return the error code!", -1, bkShell.run(argv));
}
private void verifyCookieInZooKeeper(ServerConfiguration conf, int expectedCount) throws KeeperException,
InterruptedException {
List<String> cookies;
String bookieCookiePath1 = ZKMetadataDriverBase.resolveZkLedgersRootPath(conf) + "/" + COOKIE_NODE;
cookies = zkc.getChildren(bookieCookiePath1, false);
Assert.assertEquals("Wrongly updated the cookie!", expectedCount, cookies.size());
}
private void updateCookie(String option, String optionVal, boolean useHostNameAsBookieID) throws Exception {
updateCookie(option, optionVal, useHostNameAsBookieID, false);
}
private void updateCookie(String option, String optionVal, boolean useHostNameAsBookieID, boolean useShortHostName)
throws Exception {
ServerConfiguration conf = new ServerConfiguration(bsConfs.get(0));
BookieServer bks = bs.get(0);
bks.shutdown();
conf.setUseHostNameAsBookieID(!useHostNameAsBookieID);
Cookie cookie = Cookie.readFromRegistrationManager(rm, conf).getValue();
final boolean previousBookieID = cookie.isBookieHostCreatedFromIp();
Assert.assertEquals("Wrong cookie!", useHostNameAsBookieID, previousBookieID);
LOG.info("Perform updatecookie command");
ServerConfiguration newconf = new ServerConfiguration(conf);
newconf.setUseHostNameAsBookieID(useHostNameAsBookieID);
newconf.setUseShortHostName(useShortHostName);
BookieShell bkShell = new BookieShell();
bkShell.setConf(newconf);
String[] argv = new String[] { "updatecookie", option, optionVal };
Assert.assertEquals("Failed to return exit code!", 0, bkShell.run(argv));
newconf.setUseHostNameAsBookieID(useHostNameAsBookieID);
newconf.setUseShortHostName(useShortHostName);
cookie = Cookie.readFromRegistrationManager(rm, newconf).getValue();
Assert.assertEquals("Wrongly updated cookie!", previousBookieID, !cookie.isBookieHostCreatedFromIp());
Assert.assertEquals("Wrongly updated cookie!", useHostNameAsBookieID, !cookie.isBookieHostCreatedFromIp());
verifyCookieInZooKeeper(newconf, 1);
for (File journalDir : conf.getJournalDirs()) {
journalDir = BookieImpl.getCurrentDirectory(journalDir);
Cookie jCookie = Cookie.readFromDirectory(journalDir);
jCookie.verify(cookie);
}
File[] ledgerDir = BookieImpl.getCurrentDirectories(conf.getLedgerDirs());
for (File dir : ledgerDir) {
Cookie lCookie = Cookie.readFromDirectory(dir);
lCookie.verify(cookie);
}
}
private void updateCookie(String[] argv, int exitCode, ServerConfiguration conf) throws KeeperException,
InterruptedException, IOException, UnknownHostException, Exception {
BookieServer bks = bs.get(0);
bks.shutdown();
LOG.info("Perform updatecookie command");
BookieShell bkShell = new BookieShell();
bkShell.setConf(conf);
Assert.assertEquals("Failed to return exit code!", exitCode, bkShell.run(argv));
}
}