Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.util.stream.Collectors.toList;

Expand All @@ -51,6 +53,8 @@
*/
public class TarContainerPacker
implements ContainerPacker<KeyValueContainerData> {
private static final Logger LOG =
LoggerFactory.getLogger(TarContainerPacker.class);

static final String CHUNKS_DIR_NAME = OzoneConsts.STORAGE_DIR_CHUNKS;

Expand Down Expand Up @@ -152,6 +156,20 @@ public void pack(Container<KeyValueContainerData> container,
try (OutputStream compressed = compress(output);
ArchiveOutputStream archiveOutput = tar(compressed)) {

if (!containerData.getDbFile().exists()) {
LOG.warn("DBfile {} not exist",
containerData.getDbFile().toPath().toString());
return;
} else if (!new File(containerData.getChunksPath()).exists()) {
LOG.warn("Chunkfile {} not exist",
containerData.getDbFile().toPath().toString());
return;
} else if (!container.getContainerFile().exists()) {
LOG.warn("Containerfile {} not exist",
containerData.getDbFile().toPath().toString());
return;
}

Comment on lines +159 to +172
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to utilize Container.scanMetadata() instead? More complete checks without introducing duplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok,I will change it.thank you very much!

includePath(containerData.getDbFile().toPath(), DB_DIR_NAME,
archiveOutput);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,17 @@ public void replicate(ReplicationTask task) {
LOG.info("Container {} is downloaded with size {}, starting to import.",
containerID, bytes);
task.setTransferredBytes(bytes);

importContainer(containerID, path);
LOG.info("Container {} is replicated successfully", containerID);
task.setStatus(Status.DONE);
// if tar is null, the tar size is 45 bytes
if (bytes <= 45) {
task.setStatus(Status.FAILED);
LOG.warn("Container {} is downloaded with size {}, " +
"if size less than 45 bytes the tar file is null",
containerID, bytes);
Comment on lines +124 to +129
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these kind of tar-specific details should be handled by TarContainerPacker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hello,I think it should be check in the DownloadAndImportReplicator,because of the source datanode will through outputstream to the tar,if tar is null,the task status should be set failed,the tar size check in TarContainerPacker I think is not useful.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider the case if someone wanted to introduce a new implementation of ContainerPacker, eg. based on zip. This check would not make sense, or at least would need different number of minimum bytes, for the other implementation.

} else {
importContainer(containerID, path);
LOG.info("Container {} is replicated successfully", containerID);
task.setStatus(Status.DONE);
}
} catch (Exception e) {
LOG.error("Container {} replication was unsuccessful.", containerID, e);
task.setStatus(Status.FAILED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
Expand Down Expand Up @@ -238,6 +239,55 @@ public void testContainerImportExport() throws Exception {
}
}

@Test
public void testContainerMissingFileImportExport() throws Exception {
long containerId = keyValueContainer.getContainerData().getContainerID();
createContainer();
long numberOfKeysToWrite = 12;
closeContainer();
populate(numberOfKeysToWrite);

//destination path
File folderToExport = folder.newFile("exported.tar.gz");
TarContainerPacker packer = new TarContainerPacker();

//if missing chunksfile
File chunkfile = new File(keyValueContainer.
getContainerData().getChunksPath());
Files.delete(chunkfile.toPath());
Assert.assertFalse(chunkfile.exists());
//export the container
try (FileOutputStream fos = new FileOutputStream(folderToExport)) {
keyValueContainer
.exportContainerData(fos, packer);
}

//delete the original one
keyValueContainer.delete();

//create a new one
KeyValueContainerData containerData =
new KeyValueContainerData(containerId,
keyValueContainerData.getLayOutVersion(),
keyValueContainerData.getMaxSize(), UUID.randomUUID().toString(),
datanodeId.toString());
KeyValueContainer container = new KeyValueContainer(containerData, CONF);

HddsVolume containerVolume = volumeChoosingPolicy.chooseVolume(volumeSet
.getVolumesList(), 1);
String hddsVolumeDir = containerVolume.getHddsRootDir().toString();

container.populatePathFields(scmId, containerVolume, hddsVolumeDir);
long bytes = Files.size(folderToExport.toPath());
Assert.assertTrue(bytes <= 45);

try (FileInputStream fis = new FileInputStream(folderToExport)) {
container.importContainerData(fis, packer);
} catch (Exception ex) {
assertTrue(ex instanceof NullPointerException);
Comment on lines +285 to +287
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • This passes even if importContainerData does not throw, which is not expected.
  • Some exception other than NullPointerException may better describe the error.
  • Assert.assertThrows or LambdaTestUtils.intercept could provide more details if the assertion fails (eg. if not the expected kind of exception was thrown).

}
}

/**
* Create the container on disk.
*/
Expand Down