diff --git a/hadoop-hdds/common/src/main/proto/DatanodeContainerProtocol.proto b/hadoop-hdds/common/src/main/proto/DatanodeContainerProtocol.proto index 11382978922..53da18abb54 100644 --- a/hadoop-hdds/common/src/main/proto/DatanodeContainerProtocol.proto +++ b/hadoop-hdds/common/src/main/proto/DatanodeContainerProtocol.proto @@ -131,6 +131,7 @@ enum Result { UNCLOSED_CONTAINER_IO = 25; DELETE_ON_OPEN_CONTAINER = 26; CLOSED_CONTAINER_RETRY = 27; + INVALID_CONTAINER_STATE = 28; } /** diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/helpers/ContainerData.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/helpers/ContainerData.java index 14ee33a32f4..d1746f2bde6 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/helpers/ContainerData.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/helpers/ContainerData.java @@ -339,6 +339,14 @@ public class ContainerData { return !(ContainerLifeCycleState.INVALID == state); } + /** + * checks if the container is closed. + * @return - boolean + */ + public synchronized boolean isClosed() { + return ContainerLifeCycleState.CLOSED == state; + } + /** * Marks this container as closed. */ diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/ContainerManagerImpl.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/ContainerManagerImpl.java index faee5d0f7df..9355364eac7 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/ContainerManagerImpl.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/impl/ContainerManagerImpl.java @@ -26,6 +26,8 @@ import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.container.common.helpers .StorageContainerException; import org.apache.hadoop.hdfs.server.datanode.StorageLocation; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState; import org.apache.hadoop.hdds.protocol.DatanodeDetails; import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos; import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos @@ -100,6 +102,8 @@ import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos .Result.UNCLOSED_CONTAINER_IO; import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos .Result.UNSUPPORTED_REQUEST; +import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos. + Result.INVALID_CONTAINER_STATE; import static org.apache.hadoop.ozone.OzoneConsts.CONTAINER_EXTENSION; /** @@ -706,6 +710,39 @@ public class ContainerManagerImpl implements ContainerManager { return containerData.isOpen(); } + /** + * Returns LifeCycle State of the container + * @param containerID - Id of the container + * @return LifeCycle State of the container + * @throws StorageContainerException + */ + private HddsProtos.LifeCycleState getState(long containerID) + throws StorageContainerException { + LifeCycleState state; + final ContainerData data = containerMap.get(containerID); + if (data == null) { + throw new StorageContainerException( + "Container status not found: " + containerID, CONTAINER_NOT_FOUND); + } + switch (data.getState()) { + case OPEN: + state = LifeCycleState.OPEN; + break; + case CLOSING: + state = LifeCycleState.CLOSING; + break; + case CLOSED: + state = LifeCycleState.CLOSED; + break; + default: + throw new StorageContainerException( + "Invalid Container state found: " + containerID, + INVALID_CONTAINER_STATE); + } + + return state; + } + /** * Supports clean shutdown of container. * @@ -835,14 +872,14 @@ public class ContainerManagerImpl implements ContainerManager { * @throws IOException */ @Override - public List getContainerReports() throws IOException { + public List getClosedContainerReports() throws IOException { LOG.debug("Starting container report iteration."); // No need for locking since containerMap is a ConcurrentSkipListMap // And we can never get the exact state since close might happen // after we iterate a point. return containerMap.entrySet().stream() .filter(containerData -> - !containerData.getValue().isOpen()) + containerData.getValue().isClosed()) .map(containerData -> containerData.getValue()) .collect(Collectors.toList()); } @@ -870,6 +907,7 @@ public class ContainerManagerImpl implements ContainerManager { .setType(ContainerReportsRequestProto.reportType.fullReport); for (ContainerData container: containers) { + long containerId = container.getContainerID(); StorageContainerDatanodeProtocolProtos.ContainerInfo.Builder ciBuilder = StorageContainerDatanodeProtocolProtos.ContainerInfo.newBuilder(); ciBuilder.setContainerID(container.getContainerID()) @@ -879,7 +917,8 @@ public class ContainerManagerImpl implements ContainerManager { .setReadCount(container.getReadCount()) .setWriteCount(container.getWriteCount()) .setReadBytes(container.getReadBytes()) - .setWriteBytes(container.getWriteBytes()); + .setWriteBytes(container.getWriteBytes()) + .setState(getState(containerId)); crBuilder.addReports(ciBuilder.build()); } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/ContainerManager.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/ContainerManager.java index 3a1a73d83a3..ba70953710a 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/ContainerManager.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/interfaces/ContainerManager.java @@ -185,7 +185,7 @@ public interface ContainerManager extends RwLock { * @return List of all closed containers. * @throws IOException */ - List getContainerReports() throws IOException; + List getClosedContainerReports() throws IOException; /** * Increase pending deletion blocks count number of specified container. diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/ContainerReportHandler.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/ContainerReportHandler.java index ba6b4185df3..fbea2901ece 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/ContainerReportHandler.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/ContainerReportHandler.java @@ -63,13 +63,13 @@ public class ContainerReportHandler implements CommandHandler { invocationCount++; long startTime = Time.monotonicNow(); try { - ContainerReportsRequestProto contianerReport = + ContainerReportsRequestProto containerReport = container.getContainerReport(); // TODO : We send this report to all SCMs.Check if it is enough only to // send to the leader once we have RAFT enabled SCMs. for (EndpointStateMachine endPoint : connectionManager.getValues()) { - endPoint.getEndPoint().sendContainerReport(contianerReport); + endPoint.getEndPoint().sendContainerReport(containerReport); } } catch (IOException ex) { LOG.error("Unable to process the Container Report command.", ex); diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/OzoneContainer.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/OzoneContainer.java index b497cdc6d04..6758479077c 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/OzoneContainer.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/ozoneimpl/OzoneContainer.java @@ -265,8 +265,8 @@ public class OzoneContainer { * @return - List of closed containers. * @throws IOException */ - public List getContainerReports() throws IOException { - return this.manager.getContainerReports(); + public List getClosedContainerReports() throws IOException { + return this.manager.getClosedContainerReports(); } @VisibleForTesting diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerPersistence.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerPersistence.java index 89ee6739ec6..4975fd323c1 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerPersistence.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/container/common/impl/TestContainerPersistence.java @@ -307,7 +307,7 @@ public class TestContainerPersistence { } // The container report only returns reports of closed containers. - List reports = containerManager.getContainerReports(); + List reports = containerManager.getClosedContainerReports(); Assert.assertEquals(4, reports.size()); for(ContainerData report : reports) { long actualContainerID = report.getContainerID();