Skip to content

Commit 5a34488

Browse files
zymapjiazhai
authored andcommitted
Migrate command bookieformat
Descriptions of the changes in this PR: Migrate command `bookieformat`. ### Motivation #1974 ### Changes - Add command `bookieformat` to bkctl - Replace command in shell Reviewers: Jia Zhai <zhaijia@apache.org>, Sijie Guo <sijie@apache.org> This closes #1975 from zymap/command-bookieformat and squashes the following commits: 90e8a1d [Yong Zhang] Add doc e079383 [Yong Zhang] Fix the way deal with exception eb78fe7 [Yong Zhang] Add unit test for `commandformat` a3bafe6 [Yong Zhang] Migrate command `bookieformate` to bkctl
1 parent 6b602f7 commit 5a34488

File tree

4 files changed

+256
-17
lines changed

4 files changed

+256
-17
lines changed

bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
import org.apache.bookkeeper.replication.ReplicationException.CompatibilityException;
110110
import org.apache.bookkeeper.replication.ReplicationException.UnavailableException;
111111
import org.apache.bookkeeper.stats.NullStatsLogger;
112+
import org.apache.bookkeeper.tools.cli.commands.bookie.FormatCommand;
112113
import org.apache.bookkeeper.tools.cli.commands.bookie.LastMarkCommand;
113114
import org.apache.bookkeeper.tools.cli.commands.bookies.InfoCommand;
114115
import org.apache.bookkeeper.tools.cli.commands.bookies.ListBookiesCommand;
@@ -456,23 +457,14 @@ String getUsage() {
456457
int runCmd(CommandLine cmdLine) throws Exception {
457458
boolean interactive = (!cmdLine.hasOption("n"));
458459
boolean force = cmdLine.hasOption("f");
459-
460-
ServerConfiguration conf = new ServerConfiguration(bkConf);
461-
boolean result = Bookie.format(conf, interactive, force);
462-
// delete cookie
463-
if (cmdLine.hasOption("d")) {
464-
runFunctionWithRegistrationManager(bkConf, rm -> {
465-
try {
466-
Versioned<Cookie> cookie = Cookie.readFromRegistrationManager(rm, conf);
467-
cookie.getValue().deleteFromRegistrationManager(rm, conf, cookie.getVersion());
468-
} catch (CookieNotFoundException nne) {
469-
LOG.warn("No cookie to remove : ", nne);
470-
} catch (BookieException be) {
471-
throw new UncheckedExecutionException(be.getMessage(), be);
472-
}
473-
return null;
474-
});
475-
}
460+
boolean deletecookie = cmdLine.hasOption("d");
461+
462+
FormatCommand.Flags flags = new FormatCommand.Flags()
463+
.nonInteractive(interactive)
464+
.force(force)
465+
.deleteCookie(deletecookie);
466+
FormatCommand command = new FormatCommand(flags);
467+
boolean result = command.apply(bkConf, flags);
476468
return (result) ? 0 : 1;
477469
}
478470
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.bookkeeper.tools.cli.commands.bookie;
20+
21+
import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithRegistrationManager;
22+
23+
import com.beust.jcommander.Parameter;
24+
import com.google.common.util.concurrent.UncheckedExecutionException;
25+
import java.util.concurrent.ExecutionException;
26+
import lombok.Setter;
27+
import lombok.experimental.Accessors;
28+
import org.apache.bookkeeper.bookie.Bookie;
29+
import org.apache.bookkeeper.bookie.Cookie;
30+
import org.apache.bookkeeper.conf.ServerConfiguration;
31+
import org.apache.bookkeeper.meta.exceptions.MetadataException;
32+
import org.apache.bookkeeper.tools.cli.helpers.BookieCommand;
33+
import org.apache.bookkeeper.tools.framework.CliFlags;
34+
import org.apache.bookkeeper.tools.framework.CliSpec;
35+
import org.apache.bookkeeper.versioning.Versioned;
36+
import org.slf4j.Logger;
37+
import org.slf4j.LoggerFactory;
38+
39+
/**
40+
* Command to format the current server contents.
41+
*/
42+
public class FormatCommand extends BookieCommand<FormatCommand.Flags> {
43+
44+
static final Logger LOG = LoggerFactory.getLogger(FormatCommand.class);
45+
46+
private static final String NAME = "format";
47+
private static final String DESC = "Format the current server contents.";
48+
49+
public FormatCommand() {
50+
this(new Flags());
51+
}
52+
53+
public FormatCommand(Flags flags) {
54+
super(CliSpec.<Flags>newBuilder()
55+
.withName(NAME)
56+
.withDescription(DESC)
57+
.withFlags(flags)
58+
.build());
59+
}
60+
61+
/**
62+
* Flags for format bookie command.
63+
*/
64+
@Accessors(fluent = true)
65+
@Setter
66+
public static class Flags extends CliFlags {
67+
68+
@Parameter(names = {"-n", "--noninteractive"},
69+
description = "Whether to confirm if old data exists?")
70+
private boolean nonInteractive;
71+
72+
@Parameter(names = {"-f", "--force"},
73+
description = "If [noninteractive] is specified, then whether"
74+
+ "to force delete the old data without prompt?")
75+
private boolean force;
76+
77+
@Parameter(names = {"-d", "--deletecookie"},
78+
description = "Delete its cookie on metadata store.")
79+
private boolean deleteCookie;
80+
81+
}
82+
83+
@Override
84+
public boolean apply(ServerConfiguration conf, Flags cmdFlags) {
85+
86+
ServerConfiguration bfconf = new ServerConfiguration(conf);
87+
boolean result = Bookie.format(bfconf, cmdFlags.nonInteractive, cmdFlags.force);
88+
89+
// delete cookie
90+
if (cmdFlags.deleteCookie) {
91+
try {
92+
runFunctionWithRegistrationManager(conf, rm -> {
93+
94+
try {
95+
Versioned<Cookie> cookie = Cookie.readFromRegistrationManager(rm, bfconf);
96+
cookie.getValue().deleteFromRegistrationManager(rm, bfconf, cookie.getVersion());
97+
} catch (Exception e) {
98+
throw new UncheckedExecutionException(e.getMessage(), e);
99+
}
100+
101+
return null;
102+
});
103+
} catch (MetadataException | ExecutionException e) {
104+
throw new UncheckedExecutionException(e.getMessage(), e);
105+
}
106+
}
107+
return result;
108+
}
109+
}

tools/ledger/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookieCommandGroup.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.apache.bookkeeper.tools.common.BKCommandCategories.CATEGORY_INFRA_SERVICE;
2222

2323
import org.apache.bookkeeper.tools.cli.BKCtl;
24+
import org.apache.bookkeeper.tools.cli.commands.bookie.FormatCommand;
2425
import org.apache.bookkeeper.tools.cli.commands.bookie.LastMarkCommand;
2526
import org.apache.bookkeeper.tools.common.BKFlags;
2627
import org.apache.bookkeeper.tools.framework.CliCommandGroup;
@@ -40,6 +41,7 @@ public class BookieCommandGroup extends CliCommandGroup<BKFlags> {
4041
.withParent(BKCtl.NAME)
4142
.withCategory(CATEGORY_INFRA_SERVICE)
4243
.addCommand(new LastMarkCommand())
44+
.addCommand(new FormatCommand())
4345
.build();
4446

4547
public BookieCommandGroup() {
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.bookkeeper.tools.cli.commands.bookie;
20+
21+
import static org.junit.Assert.assertTrue;
22+
import static org.junit.Assert.fail;
23+
import static org.mockito.ArgumentMatchers.any;
24+
import static org.mockito.ArgumentMatchers.eq;
25+
import static org.mockito.Mockito.mock;
26+
import static org.mockito.Mockito.when;
27+
28+
import java.util.function.Function;
29+
30+
import org.apache.bookkeeper.bookie.Cookie;
31+
import org.apache.bookkeeper.conf.AbstractConfiguration;
32+
import org.apache.bookkeeper.conf.ServerConfiguration;
33+
import org.apache.bookkeeper.discover.RegistrationManager;
34+
import org.apache.bookkeeper.meta.MetadataDrivers;
35+
import org.apache.bookkeeper.tools.cli.helpers.BookieCommandTestBase;
36+
import org.apache.bookkeeper.versioning.LongVersion;
37+
import org.apache.bookkeeper.versioning.Version;
38+
import org.apache.bookkeeper.versioning.Versioned;
39+
import org.junit.Test;
40+
import org.junit.runner.RunWith;
41+
import org.powermock.api.mockito.PowerMockito;
42+
import org.powermock.core.classloader.annotations.PrepareForTest;
43+
import org.powermock.modules.junit4.PowerMockRunner;
44+
45+
/**
46+
* Unit test {@link FormatCommand}.
47+
*/
48+
@RunWith(PowerMockRunner.class)
49+
@PrepareForTest({ FormatCommand.class, MetadataDrivers.class, Cookie.class })
50+
public class FormatCommandTest extends BookieCommandTestBase {
51+
52+
public FormatCommandTest() {
53+
super(3, 0);
54+
}
55+
56+
@SuppressWarnings("unchecked")
57+
public void setup() throws Exception {
58+
super.setup();
59+
60+
PowerMockito.whenNew(ServerConfiguration.class).withNoArguments().thenReturn(conf);
61+
62+
PowerMockito.whenNew(ServerConfiguration.class).withParameterTypes(AbstractConfiguration.class)
63+
.withArguments(eq(conf)).thenReturn(conf);
64+
65+
PowerMockito.mockStatic(MetadataDrivers.class);
66+
RegistrationManager rm = mock(RegistrationManager.class);
67+
PowerMockito.doAnswer(invocationOnMock -> {
68+
Function<RegistrationManager, ?> func = invocationOnMock.getArgument(1);
69+
func.apply(rm);
70+
return true;
71+
}).when(MetadataDrivers.class, "runFunctionWithRegistrationManager", any(ServerConfiguration.class),
72+
any(Function.class));
73+
74+
Versioned cookie = mock(Versioned.class);
75+
PowerMockito.whenNew(Versioned.class).withParameterTypes(Object.class, Version.class)
76+
.withArguments(any(Cookie.class), eq(new LongVersion(1L))).thenReturn(cookie);
77+
78+
PowerMockito.mockStatic(Cookie.class);
79+
when(Cookie.readFromRegistrationManager(rm, conf)).thenReturn((Versioned<Cookie>) cookie);
80+
81+
when(cookie.getValue()).thenReturn(mock(Cookie.class));
82+
}
83+
84+
/**
85+
* Test different type of command flags.
86+
*/
87+
@Test
88+
public void testNonInteraction() {
89+
testCommand("-n");
90+
}
91+
92+
@Test
93+
public void testNonInteractionLongArgs() {
94+
testCommand("--noninteractive");
95+
}
96+
97+
@Test
98+
public void testForce() {
99+
testCommand("-f");
100+
}
101+
102+
@Test
103+
public void testForceLongArgs() {
104+
testCommand("--force");
105+
}
106+
107+
@Test
108+
public void testDeleteCookie() {
109+
testCommand("-d");
110+
}
111+
112+
@Test
113+
public void testDeleteCookieLongArgs() {
114+
testCommand("--deletecookie");
115+
}
116+
117+
@Test
118+
public void testAllCommand() {
119+
testCommand("-n", "-f", "-d");
120+
}
121+
122+
@Test
123+
public void testAllCommandLongArgs() {
124+
testCommand("--noninteractive", "--force", "--deletecookie");
125+
}
126+
127+
private void testCommand(String... args) {
128+
FormatCommand cmd = new FormatCommand();
129+
try {
130+
assertTrue(cmd.apply(bkFlags, args));
131+
} catch (Exception e) {
132+
fail("Should not throw any exception here");
133+
}
134+
}
135+
136+
}

0 commit comments

Comments
 (0)