|
@@ -21,8 +21,13 @@ package org.apache.hadoop.hdds.scm.storage;
|
|
|
import org.apache.hadoop.hdds.scm.XceiverClientAsyncReply;
|
|
|
import org.apache.hadoop.hdds.scm.container.common.helpers
|
|
|
.BlockNotCommittedException;
|
|
|
+import org.apache.hadoop.hdds.security.token.OzoneBlockTokenIdentifier;
|
|
|
+import org.apache.hadoop.hdds.security.token.OzoneBlockTokenSelector;
|
|
|
+import org.apache.hadoop.io.Text;
|
|
|
import org.apache.hadoop.ozone.common.Checksum;
|
|
|
import org.apache.hadoop.ozone.common.ChecksumData;
|
|
|
+import org.apache.hadoop.security.UserGroupInformation;
|
|
|
+import org.apache.hadoop.security.token.Token;
|
|
|
import org.apache.ratis.thirdparty.com.google.protobuf.ByteString;
|
|
|
import org.apache.hadoop.hdds.scm.XceiverClientSpi;
|
|
|
import org.apache.hadoop.hdds.scm.container.common.helpers
|
|
@@ -97,14 +102,19 @@ public final class ContainerProtocolCalls {
|
|
|
.setBlockID(datanodeBlockID);
|
|
|
String id = xceiverClient.getPipeline().getFirstNode().getUuidString();
|
|
|
|
|
|
- ContainerCommandRequestProto request = ContainerCommandRequestProto
|
|
|
+ ContainerCommandRequestProto.Builder builder = ContainerCommandRequestProto
|
|
|
.newBuilder()
|
|
|
.setCmdType(Type.GetBlock)
|
|
|
.setContainerID(datanodeBlockID.getContainerID())
|
|
|
.setTraceID(traceID)
|
|
|
.setDatanodeUuid(id)
|
|
|
- .setGetBlock(readBlockRequest)
|
|
|
- .build();
|
|
|
+ .setGetBlock(readBlockRequest);
|
|
|
+ String encodedToken = getEncodedBlockToken(getService(datanodeBlockID));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
ContainerCommandResponseProto response = xceiverClient.sendCommand(request);
|
|
|
validateContainerResponse(response);
|
|
|
|
|
@@ -129,13 +139,19 @@ public final class ContainerProtocolCalls {
|
|
|
ContainerProtos.GetCommittedBlockLengthRequestProto.newBuilder().
|
|
|
setBlockID(blockID.getDatanodeBlockIDProtobuf());
|
|
|
String id = xceiverClient.getPipeline().getFirstNode().getUuidString();
|
|
|
- ContainerCommandRequestProto request =
|
|
|
+ ContainerCommandRequestProto.Builder builder =
|
|
|
ContainerCommandRequestProto.newBuilder()
|
|
|
.setCmdType(Type.GetCommittedBlockLength)
|
|
|
.setContainerID(blockID.getContainerID())
|
|
|
.setTraceID(traceID)
|
|
|
.setDatanodeUuid(id)
|
|
|
- .setGetCommittedBlockLength(getBlockLengthRequestBuilder).build();
|
|
|
+ .setGetCommittedBlockLength(getBlockLengthRequestBuilder);
|
|
|
+ String encodedToken = getEncodedBlockToken(new Text(blockID.
|
|
|
+ getContainerBlockID().toString()));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
ContainerCommandResponseProto response = xceiverClient.sendCommand(request);
|
|
|
validateContainerResponse(response);
|
|
|
return response.getGetCommittedBlockLength();
|
|
@@ -156,11 +172,17 @@ public final class ContainerProtocolCalls {
|
|
|
PutBlockRequestProto.Builder createBlockRequest =
|
|
|
PutBlockRequestProto.newBuilder().setBlockData(containerBlockData);
|
|
|
String id = xceiverClient.getPipeline().getFirstNode().getUuidString();
|
|
|
- ContainerCommandRequestProto request =
|
|
|
+ ContainerCommandRequestProto.Builder builder =
|
|
|
ContainerCommandRequestProto.newBuilder().setCmdType(Type.PutBlock)
|
|
|
.setContainerID(containerBlockData.getBlockID().getContainerID())
|
|
|
.setTraceID(traceID).setDatanodeUuid(id)
|
|
|
- .setPutBlock(createBlockRequest).build();
|
|
|
+ .setPutBlock(createBlockRequest);
|
|
|
+ String encodedToken =
|
|
|
+ getEncodedBlockToken(getService(containerBlockData.getBlockID()));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
ContainerCommandResponseProto response = xceiverClient.sendCommand(request);
|
|
|
validateContainerResponse(response);
|
|
|
return response.getPutBlock();
|
|
@@ -184,11 +206,18 @@ public final class ContainerProtocolCalls {
|
|
|
PutBlockRequestProto.Builder createBlockRequest =
|
|
|
PutBlockRequestProto.newBuilder().setBlockData(containerBlockData);
|
|
|
String id = xceiverClient.getPipeline().getFirstNode().getUuidString();
|
|
|
- ContainerCommandRequestProto request =
|
|
|
+ ContainerCommandRequestProto.Builder builder =
|
|
|
ContainerCommandRequestProto.newBuilder().setCmdType(Type.PutBlock)
|
|
|
.setContainerID(containerBlockData.getBlockID().getContainerID())
|
|
|
.setTraceID(traceID).setDatanodeUuid(id)
|
|
|
- .setPutBlock(createBlockRequest).build();
|
|
|
+ .setPutBlock(createBlockRequest);
|
|
|
+ String encodedToken =
|
|
|
+ getEncodedBlockToken(getService(containerBlockData.getBlockID()));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
+ xceiverClient.sendCommand(request);
|
|
|
return xceiverClient.sendCommandAsync(request);
|
|
|
}
|
|
|
|
|
@@ -203,20 +232,25 @@ public final class ContainerProtocolCalls {
|
|
|
* @throws IOException if there is an I/O error while performing the call
|
|
|
*/
|
|
|
public static ReadChunkResponseProto readChunk(XceiverClientSpi xceiverClient,
|
|
|
- ChunkInfo chunk, BlockID blockID, String traceID) throws IOException {
|
|
|
+ ChunkInfo chunk, BlockID blockID, String traceID) throws IOException {
|
|
|
ReadChunkRequestProto.Builder readChunkRequest = ReadChunkRequestProto
|
|
|
.newBuilder()
|
|
|
.setBlockID(blockID.getDatanodeBlockIDProtobuf())
|
|
|
.setChunkData(chunk);
|
|
|
String id = xceiverClient.getPipeline().getFirstNode().getUuidString();
|
|
|
- ContainerCommandRequestProto request = ContainerCommandRequestProto
|
|
|
+ ContainerCommandRequestProto.Builder builder = ContainerCommandRequestProto
|
|
|
.newBuilder()
|
|
|
.setCmdType(Type.ReadChunk)
|
|
|
.setContainerID(blockID.getContainerID())
|
|
|
.setTraceID(traceID)
|
|
|
.setDatanodeUuid(id)
|
|
|
- .setReadChunk(readChunkRequest)
|
|
|
- .build();
|
|
|
+ .setReadChunk(readChunkRequest);
|
|
|
+ String encodedToken = getEncodedBlockToken(new Text(blockID.
|
|
|
+ getContainerBlockID().toString()));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
ContainerCommandResponseProto response = xceiverClient.sendCommand(request);
|
|
|
validateContainerResponse(response);
|
|
|
return response.getReadChunk();
|
|
@@ -241,14 +275,19 @@ public final class ContainerProtocolCalls {
|
|
|
.setChunkData(chunk)
|
|
|
.setData(data);
|
|
|
String id = xceiverClient.getPipeline().getFirstNode().getUuidString();
|
|
|
- ContainerCommandRequestProto request = ContainerCommandRequestProto
|
|
|
+ ContainerCommandRequestProto.Builder builder = ContainerCommandRequestProto
|
|
|
.newBuilder()
|
|
|
.setCmdType(Type.WriteChunk)
|
|
|
.setContainerID(blockID.getContainerID())
|
|
|
.setTraceID(traceID)
|
|
|
.setDatanodeUuid(id)
|
|
|
- .setWriteChunk(writeChunkRequest)
|
|
|
- .build();
|
|
|
+ .setWriteChunk(writeChunkRequest);
|
|
|
+ String encodedToken = getEncodedBlockToken(new Text(blockID.
|
|
|
+ getContainerBlockID().toString()));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
ContainerCommandResponseProto response = xceiverClient.sendCommand(request);
|
|
|
validateContainerResponse(response);
|
|
|
}
|
|
@@ -272,10 +311,16 @@ public final class ContainerProtocolCalls {
|
|
|
.setBlockID(blockID.getDatanodeBlockIDProtobuf())
|
|
|
.setChunkData(chunk).setData(data);
|
|
|
String id = xceiverClient.getPipeline().getFirstNode().getUuidString();
|
|
|
- ContainerCommandRequestProto request =
|
|
|
+ ContainerCommandRequestProto.Builder builder =
|
|
|
ContainerCommandRequestProto.newBuilder().setCmdType(Type.WriteChunk)
|
|
|
.setContainerID(blockID.getContainerID()).setTraceID(traceID)
|
|
|
- .setDatanodeUuid(id).setWriteChunk(writeChunkRequest).build();
|
|
|
+ .setDatanodeUuid(id).setWriteChunk(writeChunkRequest);
|
|
|
+ String encodedToken = getEncodedBlockToken(new Text(blockID.
|
|
|
+ getContainerBlockID().toString()));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
return xceiverClient.sendCommandAsync(request);
|
|
|
}
|
|
|
|
|
@@ -293,8 +338,8 @@ public final class ContainerProtocolCalls {
|
|
|
* @throws IOException
|
|
|
*/
|
|
|
public static PutSmallFileResponseProto writeSmallFile(
|
|
|
- XceiverClientSpi client, BlockID blockID, byte[] data, String traceID)
|
|
|
- throws IOException {
|
|
|
+ XceiverClientSpi client, BlockID blockID, byte[] data,
|
|
|
+ String traceID) throws IOException {
|
|
|
|
|
|
BlockData containerBlockData =
|
|
|
BlockData.newBuilder().setBlockID(blockID.getDatanodeBlockIDProtobuf())
|
|
@@ -323,14 +368,19 @@ public final class ContainerProtocolCalls {
|
|
|
.build();
|
|
|
|
|
|
String id = client.getPipeline().getFirstNode().getUuidString();
|
|
|
- ContainerCommandRequestProto request =
|
|
|
+ ContainerCommandRequestProto.Builder builder =
|
|
|
ContainerCommandRequestProto.newBuilder()
|
|
|
.setCmdType(Type.PutSmallFile)
|
|
|
.setContainerID(blockID.getContainerID())
|
|
|
.setTraceID(traceID)
|
|
|
.setDatanodeUuid(id)
|
|
|
- .setPutSmallFile(putSmallFileRequest)
|
|
|
- .build();
|
|
|
+ .setPutSmallFile(putSmallFileRequest);
|
|
|
+ String encodedToken = getEncodedBlockToken(new Text(blockID.
|
|
|
+ getContainerBlockID().toString()));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
ContainerCommandResponseProto response = client.sendCommand(request);
|
|
|
validateContainerResponse(response);
|
|
|
return response.getPutSmallFile();
|
|
@@ -341,10 +391,11 @@ public final class ContainerProtocolCalls {
|
|
|
* @param client - client
|
|
|
* @param containerID - ID of container
|
|
|
* @param traceID - traceID
|
|
|
+ * @param encodedToken - encodedToken if security is enabled
|
|
|
* @throws IOException
|
|
|
*/
|
|
|
public static void createContainer(XceiverClientSpi client, long containerID,
|
|
|
- String traceID) throws IOException {
|
|
|
+ String traceID, String encodedToken) throws IOException {
|
|
|
ContainerProtos.CreateContainerRequestProto.Builder createRequest =
|
|
|
ContainerProtos.CreateContainerRequestProto
|
|
|
.newBuilder();
|
|
@@ -354,6 +405,9 @@ public final class ContainerProtocolCalls {
|
|
|
String id = client.getPipeline().getFirstNode().getUuidString();
|
|
|
ContainerCommandRequestProto.Builder request =
|
|
|
ContainerCommandRequestProto.newBuilder();
|
|
|
+ if (encodedToken != null) {
|
|
|
+ request.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
request.setCmdType(ContainerProtos.Type.CreateContainer);
|
|
|
request.setContainerID(containerID);
|
|
|
request.setCreateContainer(createRequest.build());
|
|
@@ -370,10 +424,11 @@ public final class ContainerProtocolCalls {
|
|
|
* @param client
|
|
|
* @param force whether or not to forcibly delete the container.
|
|
|
* @param traceID
|
|
|
+ * @param encodedToken - encodedToken if security is enabled
|
|
|
* @throws IOException
|
|
|
*/
|
|
|
public static void deleteContainer(XceiverClientSpi client, long containerID,
|
|
|
- boolean force, String traceID) throws IOException {
|
|
|
+ boolean force, String traceID, String encodedToken) throws IOException {
|
|
|
ContainerProtos.DeleteContainerRequestProto.Builder deleteRequest =
|
|
|
ContainerProtos.DeleteContainerRequestProto.newBuilder();
|
|
|
deleteRequest.setForceDelete(force);
|
|
@@ -386,6 +441,9 @@ public final class ContainerProtocolCalls {
|
|
|
request.setDeleteContainer(deleteRequest);
|
|
|
request.setTraceID(traceID);
|
|
|
request.setDatanodeUuid(id);
|
|
|
+ if(encodedToken != null) {
|
|
|
+ request.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
ContainerCommandResponseProto response =
|
|
|
client.sendCommand(request.build());
|
|
|
validateContainerResponse(response);
|
|
@@ -397,10 +455,12 @@ public final class ContainerProtocolCalls {
|
|
|
* @param client
|
|
|
* @param containerID
|
|
|
* @param traceID
|
|
|
+ * @param encodedToken - encodedToken if security is enabled
|
|
|
* @throws IOException
|
|
|
*/
|
|
|
public static void closeContainer(XceiverClientSpi client,
|
|
|
- long containerID, String traceID) throws IOException {
|
|
|
+ long containerID, String traceID, String encodedToken)
|
|
|
+ throws IOException {
|
|
|
String id = client.getPipeline().getFirstNode().getUuidString();
|
|
|
|
|
|
ContainerCommandRequestProto.Builder request =
|
|
@@ -410,6 +470,9 @@ public final class ContainerProtocolCalls {
|
|
|
request.setCloseContainer(CloseContainerRequestProto.getDefaultInstance());
|
|
|
request.setTraceID(traceID);
|
|
|
request.setDatanodeUuid(id);
|
|
|
+ if(encodedToken != null) {
|
|
|
+ request.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
ContainerCommandResponseProto response =
|
|
|
client.sendCommand(request.build());
|
|
|
validateContainerResponse(response);
|
|
@@ -418,13 +481,14 @@ public final class ContainerProtocolCalls {
|
|
|
/**
|
|
|
* readContainer call that gets meta data from an existing container.
|
|
|
*
|
|
|
- * @param client - client
|
|
|
- * @param traceID - trace ID
|
|
|
+ * @param client - client
|
|
|
+ * @param traceID - trace ID
|
|
|
+ * @param encodedToken - encodedToken if security is enabled
|
|
|
* @throws IOException
|
|
|
*/
|
|
|
public static ReadContainerResponseProto readContainer(
|
|
|
XceiverClientSpi client, long containerID,
|
|
|
- String traceID) throws IOException {
|
|
|
+ String traceID, String encodedToken) throws IOException {
|
|
|
String id = client.getPipeline().getFirstNode().getUuidString();
|
|
|
|
|
|
ContainerCommandRequestProto.Builder request =
|
|
@@ -434,6 +498,9 @@ public final class ContainerProtocolCalls {
|
|
|
request.setReadContainer(ReadContainerRequestProto.getDefaultInstance());
|
|
|
request.setDatanodeUuid(id);
|
|
|
request.setTraceID(traceID);
|
|
|
+ if(encodedToken != null) {
|
|
|
+ request.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
ContainerCommandResponseProto response =
|
|
|
client.sendCommand(request.build());
|
|
|
validateContainerResponse(response);
|
|
@@ -461,14 +528,19 @@ public final class ContainerProtocolCalls {
|
|
|
.build();
|
|
|
String id = client.getPipeline().getFirstNode().getUuidString();
|
|
|
|
|
|
- ContainerCommandRequestProto request = ContainerCommandRequestProto
|
|
|
+ ContainerCommandRequestProto.Builder builder = ContainerCommandRequestProto
|
|
|
.newBuilder()
|
|
|
.setCmdType(Type.GetSmallFile)
|
|
|
.setContainerID(blockID.getContainerID())
|
|
|
.setTraceID(traceID)
|
|
|
.setDatanodeUuid(id)
|
|
|
- .setGetSmallFile(getSmallFileRequest)
|
|
|
- .build();
|
|
|
+ .setGetSmallFile(getSmallFileRequest);
|
|
|
+ String encodedToken = getEncodedBlockToken(new Text(blockID.
|
|
|
+ getContainerBlockID().toString()));
|
|
|
+ if (encodedToken != null) {
|
|
|
+ builder.setEncodedToken(encodedToken);
|
|
|
+ }
|
|
|
+ ContainerCommandRequestProto request = builder.build();
|
|
|
ContainerCommandResponseProto response = client.sendCommand(request);
|
|
|
validateContainerResponse(response);
|
|
|
|
|
@@ -494,4 +566,30 @@ public final class ContainerProtocolCalls {
|
|
|
throw new StorageContainerException(
|
|
|
response.getMessage(), response.getResult());
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a url encoded block token. Service param should match the service
|
|
|
+ * field of token.
|
|
|
+ * @param service
|
|
|
+ *
|
|
|
+ * */
|
|
|
+ private static String getEncodedBlockToken(Text service)
|
|
|
+ throws IOException {
|
|
|
+ UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
|
|
|
+ Token<OzoneBlockTokenIdentifier> token =
|
|
|
+ OzoneBlockTokenSelector.selectBlockToken(service, ugi.getTokens());
|
|
|
+ if (token != null) {
|
|
|
+ return token.encodeToUrlString();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Text getService(DatanodeBlockID blockId) {
|
|
|
+ return new Text(new StringBuffer()
|
|
|
+ .append("conID: ")
|
|
|
+ .append(blockId.getContainerID())
|
|
|
+ .append(" locID: ")
|
|
|
+ .append(blockId.getLocalID())
|
|
|
+ .toString());
|
|
|
+ }
|
|
|
}
|