Skip to content

Commit 6b602f7

Browse files
zymapsijie
authored andcommitted
Migrate command bookieinfo to bkctl
### Motivation Migrate command `bookieinfo` to bkctl. ### Changes You can execute as `bin/bkctl bookie info`. Reviewers: Sijie Guo <sijie@apache.org> This closes #1972 from zymap/yongzhang/command_info
1 parent 2576afd commit 6b602f7

File tree

4 files changed

+205
-41
lines changed

4 files changed

+205
-41
lines changed

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

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import java.io.File;
3939
import java.io.IOException;
4040
import java.io.Serializable;
41-
import java.math.RoundingMode;
4241
import java.net.URI;
4342
import java.nio.ByteBuffer;
4443
import java.nio.file.FileSystems;
@@ -47,7 +46,6 @@
4746
import java.nio.file.Paths;
4847
import java.nio.file.attribute.BasicFileAttributes;
4948
import java.nio.file.attribute.FileTime;
50-
import java.text.DecimalFormat;
5149
import java.util.ArrayList;
5250
import java.util.Arrays;
5351
import java.util.Base64;
@@ -87,7 +85,6 @@
8785
import org.apache.bookkeeper.client.BookKeeper;
8886
import org.apache.bookkeeper.client.BookKeeper.DigestType;
8987
import org.apache.bookkeeper.client.BookKeeperAdmin;
90-
import org.apache.bookkeeper.client.BookieInfoReader.BookieInfo;
9188
import org.apache.bookkeeper.client.LedgerEntry;
9289
import org.apache.bookkeeper.client.LedgerHandle;
9390
import org.apache.bookkeeper.client.UpdateLedgerOp;
@@ -113,6 +110,7 @@
113110
import org.apache.bookkeeper.replication.ReplicationException.UnavailableException;
114111
import org.apache.bookkeeper.stats.NullStatsLogger;
115112
import org.apache.bookkeeper.tools.cli.commands.bookie.LastMarkCommand;
113+
import org.apache.bookkeeper.tools.cli.commands.bookies.InfoCommand;
116114
import org.apache.bookkeeper.tools.cli.commands.bookies.ListBookiesCommand;
117115
import org.apache.bookkeeper.tools.cli.commands.client.SimpleTestCommand;
118116
import org.apache.bookkeeper.tools.cli.commands.cookie.CreateCookieCommand;
@@ -2538,46 +2536,10 @@ Options getOptions() {
25382536
return lOpts;
25392537
}
25402538

2541-
String getReadable(long val) {
2542-
String unit[] = {"", "KB", "MB", "GB", "TB"};
2543-
int cnt = 0;
2544-
double d = val;
2545-
while (d >= 1000 && cnt < unit.length - 1) {
2546-
d = d / 1000;
2547-
cnt++;
2548-
}
2549-
DecimalFormat df = new DecimalFormat("#.###");
2550-
df.setRoundingMode(RoundingMode.DOWN);
2551-
return cnt > 0 ? "(" + df.format(d) + unit[cnt] + ")" : unit[cnt];
2552-
}
2553-
25542539
@Override
25552540
public int runCmd(CommandLine cmdLine) throws Exception {
2556-
ClientConfiguration clientConf = new ClientConfiguration(bkConf);
2557-
clientConf.setDiskWeightBasedPlacementEnabled(true);
2558-
BookKeeper bk = new BookKeeper(clientConf);
2559-
2560-
Map<BookieSocketAddress, BookieInfo> map = bk.getBookieInfo();
2561-
if (map.size() == 0) {
2562-
System.out.println("Failed to retrieve bookie information from any of the bookies");
2563-
bk.close();
2564-
return 0;
2565-
}
2566-
2567-
System.out.println("Free disk space info:");
2568-
long totalFree = 0, total = 0;
2569-
for (Map.Entry<BookieSocketAddress, BookieInfo> e : map.entrySet()) {
2570-
BookieInfo bInfo = e.getValue();
2571-
BookieSocketAddress bookieId = e.getKey();
2572-
System.out.println(getBookieSocketAddrStringRepresentation(bookieId) + ":\tFree: "
2573-
+ bInfo.getFreeDiskSpace() + getReadable(bInfo.getFreeDiskSpace()) + "\tTotal: "
2574-
+ bInfo.getTotalDiskSpace() + getReadable(bInfo.getTotalDiskSpace()));
2575-
totalFree += bInfo.getFreeDiskSpace();
2576-
total += bInfo.getTotalDiskSpace();
2577-
}
2578-
System.out.println("Total free disk space in the cluster:\t" + totalFree + getReadable(totalFree));
2579-
System.out.println("Total disk capacity in the cluster:\t" + total + getReadable(total));
2580-
bk.close();
2541+
InfoCommand cmd = new InfoCommand();
2542+
cmd.apply(bkConf, new CliFlags());
25812543
return 0;
25822544
}
25832545
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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.bookies;
20+
21+
import java.io.IOException;
22+
import java.math.RoundingMode;
23+
import java.text.DecimalFormat;
24+
import java.util.Map;
25+
26+
import org.apache.bookkeeper.client.BKException;
27+
import org.apache.bookkeeper.client.BookKeeper;
28+
import org.apache.bookkeeper.client.BookieInfoReader.BookieInfo;
29+
import org.apache.bookkeeper.conf.ClientConfiguration;
30+
import org.apache.bookkeeper.conf.ServerConfiguration;
31+
import org.apache.bookkeeper.net.BookieSocketAddress;
32+
import org.apache.bookkeeper.tools.cli.helpers.BookieCommand;
33+
import org.apache.bookkeeper.tools.cli.helpers.CommandHelpers;
34+
import org.apache.bookkeeper.tools.framework.CliFlags;
35+
import org.apache.bookkeeper.tools.framework.CliSpec;
36+
37+
38+
/**
39+
* A bookie command to retrieve bookie info.
40+
*/
41+
public class InfoCommand extends BookieCommand<CliFlags> {
42+
43+
private static final String NAME = "info";
44+
private static final String DESC = "Retrieve bookie info such as free and total disk space.";
45+
46+
public InfoCommand() {
47+
super(CliSpec.newBuilder()
48+
.withName(NAME)
49+
.withFlags(new CliFlags())
50+
.withDescription(DESC)
51+
.build());
52+
}
53+
54+
String getReadable(long val) {
55+
String unit[] = {"", "KB", "MB", "GB", "TB"};
56+
int cnt = 0;
57+
double d = val;
58+
while (d >= 1000 && cnt < unit.length - 1) {
59+
d = d / 1000;
60+
cnt++;
61+
}
62+
DecimalFormat df = new DecimalFormat("#.###");
63+
df.setRoundingMode(RoundingMode.DOWN);
64+
return cnt > 0 ? "(" + df.format(d) + unit[cnt] + ")" : unit[cnt];
65+
}
66+
67+
68+
@Override
69+
public boolean apply(ServerConfiguration conf, CliFlags cmdFlags) {
70+
71+
ClientConfiguration clientConf = new ClientConfiguration(conf);
72+
clientConf.setDiskWeightBasedPlacementEnabled(true);
73+
try (BookKeeper bk = new BookKeeper(clientConf)) {
74+
Map<BookieSocketAddress, BookieInfo> map = bk.getBookieInfo();
75+
if (map.size() == 0) {
76+
System.out.println("Failed to retrieve bookie information from any of the bookies");
77+
bk.close();
78+
return true;
79+
}
80+
81+
System.out.println("Free disk space info:");
82+
long totalFree = 0, total = 0;
83+
for (Map.Entry<BookieSocketAddress, BookieInfo> e : map.entrySet()) {
84+
BookieInfo bInfo = e.getValue();
85+
BookieSocketAddress bookieId = e.getKey();
86+
System.out.println(CommandHelpers.getBookieSocketAddrStringRepresentation(bookieId)
87+
+ ":\tFree: " + bInfo.getFreeDiskSpace() + getReadable(bInfo.getFreeDiskSpace())
88+
+ "\tTotal: " + bInfo.getTotalDiskSpace() + getReadable(bInfo.getTotalDiskSpace()));
89+
totalFree += bInfo.getFreeDiskSpace();
90+
total += bInfo.getTotalDiskSpace();
91+
}
92+
93+
System.out.println("Total free disk space in the cluster:\t" + totalFree + getReadable(totalFree));
94+
System.out.println("Total disk capacity in the cluster:\t" + total + getReadable(total));
95+
bk.close();
96+
97+
return true;
98+
} catch (IOException | InterruptedException | BKException e) {
99+
e.printStackTrace();
100+
}
101+
return true;
102+
}
103+
}

tools/ledger/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookiesCommandGroup.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.bookies.InfoCommand;
2425
import org.apache.bookkeeper.tools.cli.commands.bookies.ListBookiesCommand;
2526
import org.apache.bookkeeper.tools.common.BKFlags;
2627
import org.apache.bookkeeper.tools.framework.CliCommandGroup;
@@ -40,6 +41,7 @@ public class BookiesCommandGroup extends CliCommandGroup<BKFlags> {
4041
.withParent(BKCtl.NAME)
4142
.withCategory(CATEGORY_INFRA_SERVICE)
4243
.addCommand(new ListBookiesCommand())
44+
.addCommand(new InfoCommand())
4345
.build();
4446

4547
public BookiesCommandGroup() {
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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+
package org.apache.bookkeeper.tools.cli.commands.bookies;
19+
20+
import static org.mockito.ArgumentMatchers.eq;
21+
import static org.mockito.Mockito.any;
22+
import static org.mockito.Mockito.mock;
23+
import static org.mockito.Mockito.times;
24+
import static org.mockito.Mockito.verify;
25+
import static org.mockito.Mockito.when;
26+
import java.util.HashMap;
27+
import java.util.Map;
28+
import org.apache.bookkeeper.client.BookKeeper;
29+
import org.apache.bookkeeper.client.BookieInfoReader;
30+
import org.apache.bookkeeper.conf.AbstractConfiguration;
31+
import org.apache.bookkeeper.conf.ClientConfiguration;
32+
import org.apache.bookkeeper.conf.ServerConfiguration;
33+
import org.apache.bookkeeper.net.BookieSocketAddress;
34+
import org.apache.bookkeeper.tools.cli.helpers.BookieCommandTestBase;
35+
import org.junit.Before;
36+
import org.junit.Test;
37+
import org.junit.runner.RunWith;
38+
import org.powermock.api.mockito.PowerMockito;
39+
import org.powermock.core.classloader.annotations.PrepareForTest;
40+
import org.powermock.modules.junit4.PowerMockRunner;
41+
42+
/**
43+
* Unit test of {@link InfoCommand}.
44+
*/
45+
@RunWith(PowerMockRunner.class)
46+
@PrepareForTest({InfoCommand.class})
47+
public class InfoCommandTest extends BookieCommandTestBase {
48+
49+
private BookieSocketAddress bookieId;
50+
private BookieInfoReader.BookieInfo bInfo;
51+
private BookKeeper bk;
52+
private Map<BookieSocketAddress, BookieInfoReader.BookieInfo> map = new HashMap<>();
53+
54+
public InfoCommandTest() {
55+
super(1, 0);
56+
}
57+
58+
@Before
59+
public void setup() throws Exception {
60+
super.setup();
61+
62+
PowerMockito.whenNew(ServerConfiguration.class)
63+
.withNoArguments()
64+
.thenReturn(conf);
65+
66+
PowerMockito.whenNew(ClientConfiguration.class)
67+
.withParameterTypes(AbstractConfiguration.class)
68+
.withArguments(eq(conf))
69+
.thenReturn(mock(ClientConfiguration.class));
70+
71+
this.bk = mock(BookKeeper.class);
72+
PowerMockito.whenNew(BookKeeper.class)
73+
.withParameterTypes(ClientConfiguration.class)
74+
.withArguments(any(ClientConfiguration.class))
75+
.thenReturn(bk);
76+
77+
this.bookieId = new BookieSocketAddress("localhost", 9999);
78+
this.bInfo = mock(BookieInfoReader.BookieInfo.class);
79+
map.put(bookieId, bInfo);
80+
when(bk.getBookieInfo()).thenReturn(map);
81+
}
82+
83+
@Test
84+
public void testCommand() throws Exception {
85+
InfoCommand cmd = new InfoCommand();
86+
cmd.apply(bkFlags, new String[]{""});
87+
88+
PowerMockito.verifyNew(ClientConfiguration.class, times(1))
89+
.withArguments(eq(conf));
90+
PowerMockito.verifyNew(BookKeeper.class, times(1))
91+
.withArguments(any(ClientConfiguration.class));
92+
93+
verify(bk, times(1)).getBookieInfo();
94+
verify(bInfo, times(1 * 3)).getFreeDiskSpace();
95+
verify(bInfo, times(1 * 3)).getTotalDiskSpace();
96+
}
97+
}

0 commit comments

Comments
 (0)