| /** |
| * |
| * 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)); |
| } |
| } |