HDFS-11585. Ozone: Support force update a container. Contributed by Yuanbo Liu.

This commit is contained in:
Anu Engineer 2017-06-20 11:13:12 -07:00 committed by Owen O'Malley
parent 8d289df627
commit 3b0996e2a1
4 changed files with 39 additions and 8 deletions

View File

@ -232,6 +232,7 @@ message ReadContainerResponseProto {
message UpdateContainerRequestProto { message UpdateContainerRequestProto {
required Pipeline pipeline = 1; required Pipeline pipeline = 1;
required ContainerData containerData = 2; required ContainerData containerData = 2;
optional bool forceUpdate = 3 [default = false];
} }
message UpdateContainerResponseProto { message UpdateContainerResponseProto {

View File

@ -319,7 +319,9 @@ private ContainerCommandResponseProto handleUpdateContainer(
ContainerData data = ContainerData.getFromProtBuf( ContainerData data = ContainerData.getFromProtBuf(
msg.getUpdateContainer().getContainerData()); msg.getUpdateContainer().getContainerData());
this.containerManager.updateContainer(pipeline, containerName, data); boolean forceUpdate = msg.getUpdateContainer().getForceUpdate();
this.containerManager.updateContainer(
pipeline, containerName, data, forceUpdate);
return ContainerUtils.getContainerResponse(msg); return ContainerUtils.getContainerResponse(msg);
} }

View File

@ -76,10 +76,11 @@ void deleteContainer(Pipeline pipeline, String containerName,
* @param pipeline container nodes * @param pipeline container nodes
* @param containerName name of the container * @param containerName name of the container
* @param data container data * @param data container data
* @param forceUpdate if true, update container forcibly.
* @throws StorageContainerException * @throws StorageContainerException
*/ */
void updateContainer(Pipeline pipeline, String containerName, void updateContainer(Pipeline pipeline, String containerName,
ContainerData data) throws StorageContainerException; ContainerData data, boolean forceUpdate) throws StorageContainerException;
/** /**
* As simple interface for container Iterations. * As simple interface for container Iterations.

View File

@ -19,6 +19,7 @@
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.hdfs.ozone.protocol.proto.ContainerProtos; import org.apache.hadoop.hdfs.ozone.protocol.proto.ContainerProtos;
import org.apache.hadoop.hdfs.server.datanode.StorageLocation; import org.apache.hadoop.hdfs.server.datanode.StorageLocation;
import org.apache.hadoop.ozone.OzoneConfigKeys; import org.apache.hadoop.ozone.OzoneConfigKeys;
@ -654,7 +655,7 @@ public void testUpdateContainer() throws IOException {
String containerName = OzoneUtils.getRequestID(); String containerName = OzoneUtils.getRequestID();
ContainerData data = new ContainerData(containerName); ContainerData data = new ContainerData(containerName);
data.addMetadata("VOLUME", "shire"); data.addMetadata("VOLUME", "shire");
data.addMetadata("owner)", "bilbo"); data.addMetadata("owner", "bilbo");
containerManager.createContainer( containerManager.createContainer(
createSingleNodePipeline(containerName), createSingleNodePipeline(containerName),
@ -665,12 +666,12 @@ public void testUpdateContainer() throws IOException {
ContainerData newData = new ContainerData(containerName); ContainerData newData = new ContainerData(containerName);
newData.addMetadata("VOLUME", "shire_new"); newData.addMetadata("VOLUME", "shire_new");
newData.addMetadata("owner)", "bilbo_new"); newData.addMetadata("owner", "bilbo_new");
containerManager.updateContainer( containerManager.updateContainer(
createSingleNodePipeline(containerName), createSingleNodePipeline(containerName),
containerName, containerName,
newData); newData, false);
Assert.assertEquals(1, containerManager.getContainerMap().size()); Assert.assertEquals(1, containerManager.getContainerMap().size());
Assert.assertTrue(containerManager.getContainerMap() Assert.assertTrue(containerManager.getContainerMap()
@ -681,7 +682,7 @@ public void testUpdateContainer() throws IOException {
.get(containerName).getContainer(); .get(containerName).getContainer();
Assert.assertEquals(actualNewData.getAllMetadata().get("VOLUME"), Assert.assertEquals(actualNewData.getAllMetadata().get("VOLUME"),
"shire_new"); "shire_new");
Assert.assertEquals(actualNewData.getAllMetadata().get("owner)"), Assert.assertEquals(actualNewData.getAllMetadata().get("owner"),
"bilbo_new"); "bilbo_new");
// Verify container data on disk // Verify container data on disk
@ -699,16 +700,42 @@ public void testUpdateContainer() throws IOException {
.getFromProtBuf(actualContainerDataProto); .getFromProtBuf(actualContainerDataProto);
Assert.assertEquals(actualContainerData.getAllMetadata().get("VOLUME"), Assert.assertEquals(actualContainerData.getAllMetadata().get("VOLUME"),
"shire_new"); "shire_new");
Assert.assertEquals(actualContainerData.getAllMetadata().get("owner)"), Assert.assertEquals(actualContainerData.getAllMetadata().get("owner"),
"bilbo_new"); "bilbo_new");
} }
// Test force update flag.
// Delete container file then try to update without force update flag.
FileUtil.fullyDelete(newContainerFile);
try {
containerManager.updateContainer(createSingleNodePipeline(containerName),
containerName, newData, false);
} catch (StorageContainerException ex) {
Assert.assertEquals("Container file not exists or "
+ "corrupted. Name: " + containerName, ex.getMessage());
}
// Update with force flag, it should be success.
newData = new ContainerData(containerName);
newData.addMetadata("VOLUME", "shire_new_1");
newData.addMetadata("owner", "bilbo_new_1");
containerManager.updateContainer(createSingleNodePipeline(containerName),
containerName, newData, true);
// Verify in-memory map
actualNewData = containerManager.getContainerMap()
.get(containerName).getContainer();
Assert.assertEquals(actualNewData.getAllMetadata().get("VOLUME"),
"shire_new_1");
Assert.assertEquals(actualNewData.getAllMetadata().get("owner"),
"bilbo_new_1");
// Update a non-existing container // Update a non-existing container
exception.expect(StorageContainerException.class); exception.expect(StorageContainerException.class);
exception.expectMessage("Container doesn't exist."); exception.expectMessage("Container doesn't exist.");
containerManager.updateContainer( containerManager.updateContainer(
createSingleNodePipeline("non_exist_container"), createSingleNodePipeline("non_exist_container"),
"non_exist_container", newData); "non_exist_container", newData, false);
} }
private KeyData writeKeyHelper(Pipeline pipeline, private KeyData writeKeyHelper(Pipeline pipeline,