Skip to content

Commit d860f71

Browse files
Address review comments
1 parent ab9b3f0 commit d860f71

File tree

12 files changed

+271
-224
lines changed

12 files changed

+271
-224
lines changed

hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/debug/TestFindContainerKeys.java

Lines changed: 138 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,22 @@
1919
import com.google.gson.Gson;
2020
import com.google.gson.GsonBuilder;
2121
import org.apache.hadoop.hdds.client.BlockID;
22+
import org.apache.hadoop.hdds.client.RatisReplicationConfig;
2223
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
23-
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
2424
import org.apache.hadoop.hdds.utils.db.DBStore;
2525
import org.apache.hadoop.hdds.utils.db.DBStoreBuilder;
2626
import org.apache.hadoop.hdds.utils.db.Table;
2727
import org.apache.hadoop.ozone.ClientVersion;
28+
import org.apache.hadoop.ozone.debug.container.ContainerCommands;
2829
import org.apache.hadoop.ozone.debug.container.ContainerKeyInfo;
2930
import org.apache.hadoop.ozone.debug.container.ContainerKeyInfoResponse;
3031
import org.apache.hadoop.ozone.debug.container.FindContainerKeys;
3132
import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
3233
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
3334
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo;
35+
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfoGroup;
3436
import org.apache.hadoop.ozone.om.request.OMRequestTestUtils;
3537
import org.junit.jupiter.api.AfterEach;
36-
import org.junit.jupiter.api.Assertions;
3738
import org.junit.jupiter.api.BeforeEach;
3839
import org.junit.jupiter.api.Test;
3940
import org.junit.jupiter.api.io.TempDir;
@@ -50,14 +51,15 @@
5051
import java.util.Map;
5152

5253
import static java.nio.charset.StandardCharsets.UTF_8;
54+
import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor.ONE;
5355
import static org.apache.hadoop.ozone.OzoneConsts.OM_KEY_PREFIX;
5456
import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.DIRECTORY_TABLE;
5557
import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.FILE_TABLE;
5658
import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.KEY_TABLE;
59+
import static org.assertj.core.api.Assertions.assertThat;
5760

5861
/**
59-
* This class tests `ozone debug ckscanner` CLI that reads from RocksDB
60-
* and gets keys for container ids.
62+
* Test class for {@link FindContainerKeys}.
6163
*/
6264
public class TestFindContainerKeys {
6365
private DBStore dbStore;
@@ -66,37 +68,8 @@ public class TestFindContainerKeys {
6668
private StringWriter stdout, stderr;
6769
private PrintWriter pstdout, pstderr;
6870
private CommandLine cmd;
69-
private static final Gson GSON =
70-
new GsonBuilder().setPrettyPrinting().create();
71-
private static final ContainerKeyInfo KEY_ONE =
72-
new ContainerKeyInfo(1L, "vol1", -123L, "bucket1", -456L, "dir1/key1",
73-
-789L);
74-
private static final ContainerKeyInfo KEY_TWO =
75-
new ContainerKeyInfo(2L, "vol1", 0L, "bucket1", 0L, "key2", 0L);
76-
private static final ContainerKeyInfo KEY_THREE =
77-
new ContainerKeyInfo(3L, "vol1", 0L, "bucket1", 0L, "key3", 0L);
78-
79-
private static final Map<Long, List<ContainerKeyInfo>> CONTAINER_KEYS =
80-
new HashMap<>();
81-
82-
static {
83-
List<ContainerKeyInfo> list1 = new ArrayList<>();
84-
list1.add(KEY_ONE);
85-
List<ContainerKeyInfo> list2 = new ArrayList<>();
86-
list2.add(KEY_TWO);
87-
List<ContainerKeyInfo> list3 = new ArrayList<>();
88-
list3.add(KEY_THREE);
89-
CONTAINER_KEYS.put(1L, list1);
90-
CONTAINER_KEYS.put(2L, list2);
91-
CONTAINER_KEYS.put(3L, list3);
92-
}
93-
94-
private static final ContainerKeyInfoResponse KEYS_FOUND_OUTPUT =
95-
new ContainerKeyInfoResponse(3, CONTAINER_KEYS);
96-
97-
private static final String KEYS_NOT_FOUND_OUTPUT =
98-
"No keys were found for container IDs: [1, 2, 3]\n" +
99-
"Keys processed: 3\n";
71+
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
72+
private String[] cmdArgs;
10073

10174
@BeforeEach
10275
public void setup() throws IOException {
@@ -107,6 +80,7 @@ public void setup() throws IOException {
10780
pstderr = new PrintWriter(stderr);
10881

10982
cmd = new CommandLine(new OzoneDebug())
83+
.addSubcommand(new ContainerCommands())
11084
.addSubcommand(new FindContainerKeys())
11185
.setOut(pstdout)
11286
.setErr(pstderr);
@@ -115,6 +89,9 @@ public void setup() throws IOException {
11589
.setPath(tempDir.toPath()).addTable(KEY_TABLE).addTable(FILE_TABLE)
11690
.addTable(DIRECTORY_TABLE)
11791
.build();
92+
93+
cmdArgs =
94+
new String[]{"find-keys", "--om-db", dbStore.getDbLocation().getAbsolutePath(), "--container-ids", "1 2 3"};
11895
}
11996

12097
@AfterEach
@@ -127,44 +104,114 @@ public void shutdown() throws IOException {
127104
}
128105

129106
@Test
130-
void testWhenThereAreKeysForContainerIds() throws IOException {
131-
132-
// create keys for tables
107+
void testFSO() throws Exception {
108+
/*
109+
Structure:
110+
keyName (container id)
111+
112+
/vol1/bucet1
113+
- key1 (1)
114+
- dir1
115+
- key2 (2)
116+
- dir2
117+
- key3 (3)
118+
- key4 (3)
119+
- key5 (4)
120+
*/
133121
long volumeId = -123L;
134122
long bucketId = -456L;
135-
long dirObjectId = -789L;
136-
createDirectory(volumeId, bucketId, bucketId, dirObjectId, "dir1");
137-
createFile(volumeId, bucketId, "key1", -987L, dirObjectId, 1L);
138-
createKey("key2", 2L);
139-
createKey("key3", 3L);
140-
141-
String[] cmdArgs =
142-
{"ckscanner", "--om-db", dbStore.getDbLocation().getAbsolutePath(),
143-
"--container-ids", "1 2 3"};
123+
long dirObjectId1 = -789L;
124+
long dirObjectId2 = -788L;
125+
createDirectory(volumeId, bucketId, bucketId, dirObjectId1, "dir1");
126+
createDirectory(volumeId, bucketId, dirObjectId1, dirObjectId2, "dir2");
127+
createFile(volumeId, bucketId, "key1", -987L, bucketId, 1L);
128+
createFile(volumeId, bucketId, "key2", -986L, dirObjectId1, 2L);
129+
createFile(volumeId, bucketId, "key3", -985L, dirObjectId2, 3L);
130+
createFile(volumeId, bucketId, "key4", -984L, dirObjectId2, 3L);
131+
createFile(volumeId, bucketId, "key5", -983L, dirObjectId2, 4L);
144132

145133
closeDbStore();
146134

147135
int exitCode = cmd.execute(cmdArgs);
148-
Assertions.assertEquals(0, exitCode);
136+
assertThat(exitCode).isEqualTo(0);
137+
138+
// Create expected response
139+
List<ContainerKeyInfo> expectedKeysForContainer1 = new ArrayList<>();
140+
expectedKeysForContainer1.add(new ContainerKeyInfo(1L, "vol1", volumeId, "bucket1", bucketId, "key1", bucketId));
141+
List<ContainerKeyInfo> expectedKeysForContainer2 = new ArrayList<>();
142+
expectedKeysForContainer2.add(
143+
new ContainerKeyInfo(2L, "vol1", volumeId, "bucket1", bucketId, "dir1/key2", dirObjectId1));
144+
List<ContainerKeyInfo> expectedKeysForContainer3 = new ArrayList<>();
145+
expectedKeysForContainer3.add(
146+
new ContainerKeyInfo(3L, "vol1", volumeId, "bucket1", bucketId, "dir1/dir2/key3", dirObjectId2));
147+
expectedKeysForContainer3.add(
148+
new ContainerKeyInfo(3L, "vol1", volumeId, "bucket1", bucketId, "dir1/dir2/key4", dirObjectId2));
149+
Map<Long, List<ContainerKeyInfo>> expectedContainerIdToKeyInfos = new HashMap<>();
150+
expectedContainerIdToKeyInfos.put(1L, expectedKeysForContainer1);
151+
expectedContainerIdToKeyInfos.put(2L, expectedKeysForContainer2);
152+
expectedContainerIdToKeyInfos.put(3L, expectedKeysForContainer3);
153+
ContainerKeyInfoResponse expectedResponse = new ContainerKeyInfoResponse(5, expectedContainerIdToKeyInfos);
154+
assertThat(GSON.fromJson(stdout.toString(), ContainerKeyInfoResponse.class)).isEqualTo(expectedResponse);
155+
156+
assertThat(stderr.toString()).isEmpty();
157+
}
149158

150-
Assertions.assertEquals(
151-
GSON.fromJson(stdout.toString(), ContainerKeyInfoResponse.class),
152-
KEYS_FOUND_OUTPUT);
159+
@Test
160+
void testNonFSO() throws Exception {
161+
/*
162+
Structure:
163+
keyName (container id)
164+
165+
/vol1/bucket1
166+
- key1 (1)
167+
- dir1/key2 (2)
168+
- dir1/dir2/key3 (3)
169+
- dir1/dir2/key4 (3)
170+
- key5 (4)
171+
*/
172+
createKey("key1", 1L);
173+
createKey("dir1/key2", 2L);
174+
createKey("dir1/dir2/key3", 3L);
175+
createKey("dir1/dir2/key4", 3L);
176+
createKey("key5", 4L);
153177

154-
Assertions.assertTrue(stderr.toString().isEmpty());
178+
closeDbStore();
179+
180+
int exitCode = cmd.execute(cmdArgs);
181+
assertThat(exitCode).isEqualTo(0);
182+
183+
// Create expected response
184+
List<ContainerKeyInfo> expectedKeysForContainer1 = new ArrayList<>();
185+
expectedKeysForContainer1.add(new ContainerKeyInfo(1L, "vol1", 0, "bucket1", 0, "key1", 0));
186+
List<ContainerKeyInfo> expectedKeysForContainer2 = new ArrayList<>();
187+
expectedKeysForContainer2.add(
188+
new ContainerKeyInfo(2L, "vol1", 0, "bucket1", 0, "dir1/key2", 0));
189+
List<ContainerKeyInfo> expectedKeysForContainer3 = new ArrayList<>();
190+
expectedKeysForContainer3.add(
191+
new ContainerKeyInfo(3L, "vol1", 0, "bucket1", 0, "dir1/dir2/key3", 0));
192+
expectedKeysForContainer3.add(
193+
new ContainerKeyInfo(3L, "vol1", 0, "bucket1", 0, "dir1/dir2/key4", 0));
194+
Map<Long, List<ContainerKeyInfo>> expectedContainerIdToKeyInfos = new HashMap<>();
195+
expectedContainerIdToKeyInfos.put(1L, expectedKeysForContainer1);
196+
expectedContainerIdToKeyInfos.put(2L, expectedKeysForContainer2);
197+
expectedContainerIdToKeyInfos.put(3L, expectedKeysForContainer3);
198+
ContainerKeyInfoResponse expectedResponse = new ContainerKeyInfoResponse(5, expectedContainerIdToKeyInfos);
199+
assertThat(GSON.fromJson(stdout.toString(), ContainerKeyInfoResponse.class)).isEqualTo(expectedResponse);
200+
201+
assertThat(stderr.toString()).isEmpty();
155202
}
156203

157204
/**
158205
* Close db store because of the lock.
159206
*/
160207
private void closeDbStore() throws IOException {
161-
if (dbStore != null) {
208+
if (dbStore != null && !dbStore.isClosed()) {
162209
dbStore.close();
163210
}
164211
}
165212

166213
@Test
167-
void testWhenThereAreNotKeysForContainerIds() throws IOException {
214+
void testWhenThereAreNoKeysForContainerIds() throws Exception {
168215

169216
// create keys for tables
170217
long volumeId = -123L;
@@ -173,83 +220,67 @@ void testWhenThereAreNotKeysForContainerIds() throws IOException {
173220
createKey("key2", 5L);
174221
createKey("key3", 6L);
175222

176-
String[] cmdArgs =
177-
{"ckscanner", "--om-db", dbStore.getDbLocation().getAbsolutePath(),
178-
"--container-ids", "1 2 3"};
179-
180223
closeDbStore();
181224

182225
int exitCode = cmd.execute(cmdArgs);
183-
Assertions.assertEquals(0, exitCode);
226+
assertThat(exitCode).isEqualTo(0);
184227

185-
Assertions.assertTrue(stderr.toString().contains(KEYS_NOT_FOUND_OUTPUT));
228+
assertThat(stderr.toString()).contains("No keys were found for container IDs: [1, 2, 3]\n" + "Keys processed: 3\n");
186229

187-
Assertions.assertTrue(stdout.toString().isEmpty());
230+
assertThat(stdout.toString()).isEmpty();
188231
}
189232

190-
private void createFile(long volumeId, long bucketId, String keyName,
191-
long objectId, long parentId, long containerId)
192-
throws IOException {
193-
Table<byte[], byte[]> table = dbStore.getTable(FILE_TABLE);
233+
private void createFile(long volumeId, long bucketId, String keyName, long objectId, long parentId, long containerId)
234+
throws Exception {
235+
try (Table<byte[], byte[]> table = dbStore.getTable(FILE_TABLE)) {
236+
// format: /volumeId/bucketId/parentId(bucketId)/keyName
237+
String key =
238+
OM_KEY_PREFIX + volumeId + OM_KEY_PREFIX + bucketId + OM_KEY_PREFIX + parentId + OM_KEY_PREFIX + keyName;
194239

195-
// format: /volumeId/bucketId/parentId(bucketId)/keyName
196-
String key =
197-
OM_KEY_PREFIX + volumeId + OM_KEY_PREFIX +
198-
bucketId + OM_KEY_PREFIX + parentId +
199-
OM_KEY_PREFIX + keyName;
240+
OmKeyInfo value = getOmKeyInfo("vol1", "bucket1", keyName, containerId, objectId, parentId);
200241

201-
OmKeyInfo value =
202-
getOmKeyInfo("vol1", "bucket1", keyName, containerId, objectId,
203-
parentId);
204-
205-
table.put(key.getBytes(UTF_8),
206-
value.getProtobuf(ClientVersion.CURRENT_VERSION).toByteArray());
242+
table.put(key.getBytes(UTF_8), value.getProtobuf(ClientVersion.CURRENT_VERSION).toByteArray());
243+
}
207244
}
208245

209-
private void createKey(String keyName, long containerId) throws IOException {
210-
Table<byte[], byte[]> table = dbStore.getTable(KEY_TABLE);
246+
private void createKey(String keyName, long containerId) throws Exception {
247+
try (Table<byte[], byte[]> table = dbStore.getTable(KEY_TABLE)) {
248+
String volumeName = "vol1";
249+
String bucketName = "bucket1";
250+
// format: /volumeName/bucketName/keyName
251+
String key = OM_KEY_PREFIX + volumeName + OM_KEY_PREFIX + bucketName + OM_KEY_PREFIX + keyName;
211252

212-
String volumeName = "vol1";
213-
String bucketName = "bucket1";
214-
// format: /volumeName/bucketName/keyName
215-
String key = OM_KEY_PREFIX + volumeName + OM_KEY_PREFIX + bucketName +
216-
OM_KEY_PREFIX + keyName;
253+
// generate table value
254+
OmKeyInfo value = getOmKeyInfo(volumeName, bucketName, keyName, containerId, 0, 0);
217255

218-
// generate table value
219-
OmKeyInfo value =
220-
getOmKeyInfo(volumeName, bucketName, keyName, containerId, 0, 0);
221-
222-
table.put(key.getBytes(UTF_8),
223-
value.getProtobuf(ClientVersion.CURRENT_VERSION).toByteArray());
256+
table.put(key.getBytes(UTF_8), value.getProtobuf(ClientVersion.CURRENT_VERSION).toByteArray());
257+
}
224258
}
225259

226-
private void createDirectory(long volumeId, long bucketId, long parentId,
227-
long objectId, String keyName)
228-
throws IOException {
229-
Table<byte[], byte[]> table = dbStore.getTable(DIRECTORY_TABLE);
260+
private void createDirectory(long volumeId, long bucketId, long parentId, long objectId, String keyName)
261+
throws Exception {
262+
try (Table<byte[], byte[]> table = dbStore.getTable(DIRECTORY_TABLE)) {
230263

231-
// format: /volumeId/bucketId/parentId(bucketId)/keyName
232-
String key =
233-
OM_KEY_PREFIX + volumeId + OM_KEY_PREFIX + bucketId + OM_KEY_PREFIX +
234-
parentId + OM_KEY_PREFIX + keyName;
264+
// format: /volumeId/bucketId/parentId(bucketId)/keyName
265+
String key =
266+
OM_KEY_PREFIX + volumeId + OM_KEY_PREFIX + bucketId + OM_KEY_PREFIX + parentId + OM_KEY_PREFIX + keyName;
235267

236-
OmDirectoryInfo value =
237-
OMRequestTestUtils.createOmDirectoryInfo(keyName, objectId, parentId);
268+
OmDirectoryInfo value = OMRequestTestUtils.createOmDirectoryInfo(keyName, objectId, parentId);
238269

239-
table.put(key.getBytes(UTF_8), value.getProtobuf().toByteArray());
270+
table.put(key.getBytes(UTF_8), value.getProtobuf().toByteArray());
271+
}
240272
}
241273

242274
private static OmKeyInfo getOmKeyInfo(String volumeName, String bucketName,
243275
String keyName, long containerId,
244276
long objectId,
245277
long parentId) {
246-
return OMRequestTestUtils.createOmKeyInfo(volumeName, bucketName,
247-
keyName, HddsProtos.ReplicationType.STAND_ALONE,
248-
HddsProtos.ReplicationFactor.ONE, objectId, parentId, 1, 1, 1, false,
249-
new ArrayList<>(
250-
Collections.singletonList(
251-
new OmKeyLocationInfo.Builder().setBlockID(
252-
new BlockID(containerId, 1)).build())));
278+
return OMRequestTestUtils
279+
.createOmKeyInfo(volumeName, bucketName, keyName, RatisReplicationConfig.getInstance(ONE), objectId, parentId,
280+
new OmKeyLocationInfoGroup(0L, Collections.singletonList(new OmKeyLocationInfo.Builder()
281+
.setBlockID(new BlockID(containerId, 1))
282+
.build())))
283+
.build();
253284
}
254285

255286
}

hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ default String getOzonePathKey(long volumeId, long bucketId,
510510
}
511511

512512
/**
513-
* Given ozone path key, component id, return the corresponding
513+
* Given ozone path key, component id, return the corresponding
514514
* DB path key for delete table.
515515
*
516516
* @param objectId - object Id
@@ -611,4 +611,26 @@ String getMultipartKey(long volumeId, long bucketId,
611611
*/
612612
boolean containsIncompleteMPUs(String volume, String bucket)
613613
throws IOException;
614+
615+
/**
616+
* Helper method to generate /volumeId/bucketId/ DB key prefix from given
617+
* volume name and bucket name as a prefix for FSO buckets.
618+
*
619+
* @param volumeName volume name
620+
* @param bucketName bucket name
621+
* @return /volumeId/bucketId/
622+
* e.g. /-9223372036854772480/-9223372036854771968/
623+
*/
624+
String getOzonePathKeyForFso(String volumeName, String bucketName)
625+
throws IOException;
626+
627+
/**
628+
* Helper method to generate /volumeId/bucketId DB key prefix from given
629+
* volume id and bucket id as a prefix for FSO buckets.
630+
* @param volumeId volume id
631+
* @param bucketId bucket id
632+
* @return /volumeId/bucketId
633+
* e.g. /-9223372036854772480/-9223372036854771968/
634+
*/
635+
String getOzonePathKeyForFso(long volumeId, long bucketId);
614636
}

0 commit comments

Comments
 (0)