From fed2bef647d9a15fe020ad5d3bb89fcb77ed30e6 Mon Sep 17 00:00:00 2001 From: Mukul Kumar Singh Date: Wed, 23 May 2018 14:15:35 +0530 Subject: [PATCH] HDDS-85. Send Container State Info while sending the container report from Datanode to SCM. Contributed by Shashikant Banerjee. --- .../proto/DatanodeContainerProtocol.proto | 1 + .../common/helpers/ContainerData.java | 8 ++++ .../common/impl/ContainerManagerImpl.java | 45 +++++++++++++++++-- .../common/interfaces/ContainerManager.java | 2 +- .../ContainerReportHandler.java | 4 +- .../container/ozoneimpl/OzoneContainer.java | 4 +- .../common/impl/TestContainerPersistence.java | 2 +- 7 files changed, 57 insertions(+), 9 deletions(-) diff --git a/hadoop-hdds/common/src/main/proto/DatanodeContainerProtocol.proto b/hadoop-hdds/common/src/main/proto/DatanodeContainerProtocol.proto index 1138297892..53da18abb5 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 14ee33a32f..d1746f2bde 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 boolean isValid() { 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 faee5d0f7d..9355364eac 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.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 @@ .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 boolean isOpen(long containerID) throws StorageContainerException { 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 SCMNodeReport getNodeReport() throws IOException { * @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 ContainerReportsRequestProto getContainerReport() throws IOException { .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 ContainerReportsRequestProto getContainerReport() throws IOException { .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 3a1a73d83a..ba70953710 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 @@ void closeContainer(long containerID) * @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 ba6b4185df..fbea2901ec 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 void handle(SCMCommand command, OzoneContainer container, 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 b497cdc6d0..6758479077 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 ContainerReportsRequestProto getContainerReport() throws IOException { * @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 89ee6739ec..4975fd323c 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 void testGetContainerReports() throws Exception{ } // 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();