Skip to content

Commit 65a5bf3

Browse files
authored
HADOOP-19226: [ABFS][FNSOverBlob] Implementing Azure Rest APIs on Blob Endpoint for AbfsBlobClient (#6944)
Contributed by Anuj Modi
1 parent 919bd18 commit 65a5bf3

22 files changed

+1609
-98
lines changed

hadoop-tools/hadoop-azure/src/config/checkstyle-suppressions.xml

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
files="org[\\/]apache[\\/]hadoop[\\/]fs[\\/]azurebfs[\\/]AzureBlobFileSystemStore.java"/>
4747
<suppress checks="ParameterNumber"
4848
files="org[\\/]apache[\\/]hadoop[\\/]fs[\\/]azurebfs[\\/]services[\\/]AbfsClient.java"/>
49+
<suppress checks="ParameterNumber"
50+
files="org[\\/]apache[\\/]hadoop[\\/]fs[\\/]azurebfs[\\/]services[\\/]AbfsBlobClient.java"/>
51+
<suppress checks="ParameterNumber"
52+
files="org[\\/]apache[\\/]hadoop[\\/]fs[\\/]azurebfs[\\/]contracts[\\/]services[\\/]AppendRequestParameters.java"/>
4953
<suppress checks="ParameterNumber|MagicNumber"
5054
files="org[\\/]apache[\\/]hadoop[\\/]fs[\\/]azurebfs[\\/]utils[\\/]Base64.java"/>
5155
<suppress checks="ParameterNumber|VisibilityModifier"

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AbfsConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ public boolean isDfsToBlobFallbackEnabled() {
508508
*/
509509
public void validateConfiguredServiceType(boolean isHNSEnabled)
510510
throws InvalidConfigurationValueException {
511-
// Todo: [FnsOverBlob] - Remove this check, Failing FS Init with Blob Endpoint Until FNS over Blob is ready.
511+
// TODO: [FnsOverBlob][HADOOP-19179] Remove this check when FNS over Blob is ready.
512512
if (getFsConfiguredServiceType() == AbfsServiceType.BLOB) {
513513
throw new InvalidConfigurationValueException(FS_DEFAULT_NAME_KEY,
514514
"Blob Endpoint Support not yet available");

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AzureBlobFileSystem.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,7 @@ private boolean fileSystemExists() throws IOException {
14571457
try {
14581458
checkException(null, ex);
14591459
// Because HEAD request won't contain message body,
1460-
// there is not way to get the storage error code
1460+
// there is no way to get the storage error code
14611461
// workaround here is to check its status code.
14621462
} catch (FileNotFoundException e) {
14631463
statIncrement(ERROR_IGNORED);

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AzureBlobFileSystemStore.java

+74-74
Large diffs are not rendered by default.

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/constants/AbfsHttpConstants.java

+44-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,44 @@ public final class AbfsHttpConstants {
5050
public static final String DEFAULT_LEASE_BREAK_PERIOD = "0";
5151
public static final String DEFAULT_TIMEOUT = "90";
5252
public static final String APPEND_BLOB_TYPE = "appendblob";
53-
public static final String TOKEN_VERSION = "2";
53+
54+
//Abfs Http Client Constants for Blob Endpoint APIs.
55+
56+
/**
57+
* HTTP Header Value to denote resource type as container.
58+
* {@value}.
59+
*/
60+
public static final String CONTAINER = "container";
61+
62+
/**
63+
* HTTP Header Value to denote component as metadata.
64+
* {@value}.
65+
*/
66+
public static final String METADATA = "metadata";
67+
68+
/**
69+
* HTTP Header Value to denote component as block.
70+
* {@value}.
71+
*/
72+
public static final String BLOCK = "block";
73+
74+
/**
75+
* HTTP Header Value to denote component as blocklist.
76+
* {@value}.
77+
*/
78+
public static final String BLOCKLIST = "blocklist";
79+
80+
/**
81+
* HTTP Header Value to denote component as lease.
82+
* {@value}.
83+
*/
84+
public static final String LEASE = "lease";
85+
86+
/**
87+
* HTTP Header Value to denote bock list type as committed.
88+
* {@value}.
89+
*/
90+
public static final String BLOCK_TYPE_COMMITTED = "committed";
5491

5592
public static final String JAVA_VENDOR = "java.vendor";
5693
public static final String JAVA_VERSION = "java.version";
@@ -60,6 +97,10 @@ public final class AbfsHttpConstants {
6097

6198
public static final String APN_VERSION = "APN/1.0";
6299
public static final String CLIENT_VERSION = "Azure Blob FS/" + VersionInfo.getVersion();
100+
/**
101+
* {@value}.
102+
*/
103+
public static final String TOKEN_VERSION = "2";
63104

64105
// Abfs Http Verb
65106
public static final String HTTP_METHOD_DELETE = "DELETE";
@@ -92,6 +133,7 @@ public final class AbfsHttpConstants {
92133
public static final String HTTP_HEADER_PREFIX = "x-ms-";
93134
public static final String HASH = "#";
94135
public static final String TRUE = "true";
136+
public static final String ZERO = "0";
95137

96138
public static final String PLUS_ENCODE = "%20";
97139
public static final String FORWARD_SLASH_ENCODE = "%2F";
@@ -101,6 +143,7 @@ public final class AbfsHttpConstants {
101143
public static final String GMT_TIMEZONE = "GMT";
102144
public static final String APPLICATION_JSON = "application/json";
103145
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
146+
public static final String APPLICATION_XML = "application/xml";
104147
public static final String XMS_PROPERTIES_ENCODING_ASCII = "ISO-8859-1";
105148
public static final String XMS_PROPERTIES_ENCODING_UNICODE = "UTF-8";
106149

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/constants/FSOperationType.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ public enum FSOperationType {
4545
SET_OWNER("SO"),
4646
SET_ACL("SA"),
4747
TEST_OP("TS"),
48-
WRITE("WR"),
49-
INIT("IN");
48+
WRITE("WR");
5049

5150
private final String opCode;
5251

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/constants/HttpHeaderConfigurations.java

+30-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ public final class HttpHeaderConfigurations {
5959
public static final String X_MS_ACL = "x-ms-acl";
6060
public static final String X_MS_PERMISSIONS = "x-ms-permissions";
6161
public static final String X_MS_UMASK = "x-ms-umask";
62-
public static final String X_MS_NAMESPACE_ENABLED = "x-ms-namespace-enabled";
6362
public static final String X_MS_ABFS_CLIENT_LATENCY = "x-ms-abfs-client-latency";
6463
public static final String X_MS_ENCRYPTION_KEY = "x-ms-encryption-key";
6564
public static final String X_MS_ENCRYPTION_KEY_SHA256 = "x-ms-encryption-key-sha256";
@@ -70,10 +69,40 @@ public final class HttpHeaderConfigurations {
7069
public static final String X_MS_LEASE_ACTION = "x-ms-lease-action";
7170
public static final String X_MS_LEASE_DURATION = "x-ms-lease-duration";
7271
public static final String X_MS_LEASE_ID = "x-ms-lease-id";
72+
73+
/**
74+
* Http Request Header for denoting the lease id of source in copy operation.
75+
* {@value}
76+
*/
77+
public static final String X_MS_SOURCE_LEASE_ID = "x-ms-source-lease-id";
7378
public static final String X_MS_PROPOSED_LEASE_ID = "x-ms-proposed-lease-id";
7479
public static final String X_MS_LEASE_BREAK_PERIOD = "x-ms-lease-break-period";
7580
public static final String EXPECT = "Expect";
7681
public static final String X_MS_RANGE_GET_CONTENT_MD5 = "x-ms-range-get-content-md5";
7782

83+
/**
84+
* Http Response Header for denoting directory.
85+
* {@value}
86+
*/
87+
public static final String X_MS_META_HDI_ISFOLDER = "x-ms-meta-hdi_isfolder";
88+
89+
/**
90+
* Http Response Header prefix for user-defined properties.
91+
* {@value}
92+
*/
93+
public static final String X_MS_METADATA_PREFIX = "x-ms-meta-";
94+
95+
/**
96+
* Http Request Header for denoting the source of copy operation.
97+
* {@value}
98+
*/
99+
public static final String X_MS_COPY_SOURCE = "x-ms-copy-source";
100+
101+
/**
102+
* Http Request Header for denoting MD5 hash of the blob content.
103+
* {@value}
104+
*/
105+
public static final String X_MS_BLOB_CONTENT_MD5 = "x-ms-blob-content-md5";
106+
78107
private HttpHeaderConfigurations() {}
79108
}

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/constants/HttpQueryParams.java

+26
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,32 @@ public final class HttpQueryParams {
4242
public static final String QUERY_PARAM_BLOBTYPE = "blobtype";
4343
public static final String QUERY_PARAM_PAGINATED = "paginated";
4444

45+
// query parameters for Blob Endpoint Rest APIs
46+
47+
/**
48+
* Http Query parameter for specifying resource type.
49+
* {@value}
50+
*/
51+
public static final String QUERY_PARAM_RESTYPE = "restype";
52+
53+
/**
54+
* Http Query parameter for specifying component.
55+
* {@value}
56+
*/
57+
public static final String QUERY_PARAM_COMP = "comp";
58+
59+
/**
60+
* Http Query parameter for specifying blockId.
61+
* {@value}
62+
*/
63+
public static final String QUERY_PARAM_BLOCKID = "blockid";
64+
65+
/**
66+
* Http Query parameter for specifying block list type.
67+
* {@value}
68+
*/
69+
public static final String QUERY_PARAM_BLOCKLISTTYPE = "blocklisttype";
70+
4571
//query params for SAS
4672
public static final String QUERY_PARAM_SAOID = "saoid";
4773
public static final String QUERY_PARAM_SKOID = "skoid";

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/contracts/services/AppendRequestParameters.java

+59
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,19 @@ public enum Mode {
3636
private final String leaseId;
3737
private boolean isExpectHeaderEnabled;
3838
private boolean isRetryDueToExpect;
39+
private final BlobAppendRequestParameters blobParams;
3940

41+
42+
/**
43+
* Constructor to be used for interacting with AbfsDfsClient.
44+
* @param position position in remote blob at which append should happen
45+
* @param offset position in the buffer to be appended
46+
* @param length length of the data to be appended
47+
* @param mode mode of the append operation
48+
* @param isAppendBlob true if the blob is append-blob
49+
* @param leaseId leaseId of the blob to be appended
50+
* @param isExpectHeaderEnabled true if the expect header is enabled
51+
*/
4052
public AppendRequestParameters(final long position,
4153
final int offset,
4254
final int length,
@@ -52,6 +64,37 @@ public AppendRequestParameters(final long position,
5264
this.leaseId = leaseId;
5365
this.isExpectHeaderEnabled = isExpectHeaderEnabled;
5466
this.isRetryDueToExpect = false;
67+
this.blobParams = null;
68+
}
69+
70+
/**
71+
* Constructor to be used for interacting with AbfsBlobClient.
72+
* @param position position in remote blob at which append should happen
73+
* @param offset position in the buffer to be appended
74+
* @param length length of the data to be appended
75+
* @param mode mode of the append operation
76+
* @param isAppendBlob true if the blob is append-blob
77+
* @param leaseId leaseId of the blob to be appended
78+
* @param isExpectHeaderEnabled true if the expect header is enabled
79+
* @param blobParams parameters specific to append operation on Blob Endpoint.
80+
*/
81+
public AppendRequestParameters(final long position,
82+
final int offset,
83+
final int length,
84+
final Mode mode,
85+
final boolean isAppendBlob,
86+
final String leaseId,
87+
final boolean isExpectHeaderEnabled,
88+
final BlobAppendRequestParameters blobParams) {
89+
this.position = position;
90+
this.offset = offset;
91+
this.length = length;
92+
this.mode = mode;
93+
this.isAppendBlob = isAppendBlob;
94+
this.leaseId = leaseId;
95+
this.isExpectHeaderEnabled = isExpectHeaderEnabled;
96+
this.isRetryDueToExpect = false;
97+
this.blobParams = blobParams;
5598
}
5699

57100
public long getPosition() {
@@ -86,6 +129,22 @@ public boolean isRetryDueToExpect() {
86129
return isRetryDueToExpect;
87130
}
88131

132+
/**
133+
* Returns BlockId of the block blob to be appended.
134+
* @return blockId
135+
*/
136+
public String getBlockId() {
137+
return blobParams.getBlockId();
138+
}
139+
140+
/**
141+
* Returns ETag of the block blob.
142+
* @return eTag
143+
*/
144+
public String getETag() {
145+
return blobParams.getETag();
146+
}
147+
89148
public void setRetryDueToExpect(boolean retryDueToExpect) {
90149
isRetryDueToExpect = retryDueToExpect;
91150
}

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/contracts/services/AzureServiceErrorCode.java

+2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@
3434
public enum AzureServiceErrorCode {
3535
FILE_SYSTEM_ALREADY_EXISTS("FilesystemAlreadyExists", HttpURLConnection.HTTP_CONFLICT, null),
3636
PATH_ALREADY_EXISTS("PathAlreadyExists", HttpURLConnection.HTTP_CONFLICT, null),
37+
BLOB_ALREADY_EXISTS("BlobAlreadyExists", HttpURLConnection.HTTP_CONFLICT, null),
3738
INTERNAL_OPERATION_ABORT("InternalOperationAbortError", HttpURLConnection.HTTP_CONFLICT, null),
3839
PATH_CONFLICT("PathConflict", HttpURLConnection.HTTP_CONFLICT, null),
3940
FILE_SYSTEM_NOT_FOUND("FilesystemNotFound", HttpURLConnection.HTTP_NOT_FOUND, null),
4041
PATH_NOT_FOUND("PathNotFound", HttpURLConnection.HTTP_NOT_FOUND, null),
42+
BLOB_PATH_NOT_FOUND("BlobNotFound", HttpURLConnection.HTTP_NOT_FOUND, null),
4143
PRE_CONDITION_FAILED("PreconditionFailed", HttpURLConnection.HTTP_PRECON_FAILED, null),
4244
SOURCE_PATH_NOT_FOUND("SourcePathNotFound", HttpURLConnection.HTTP_NOT_FOUND, null),
4345
INVALID_SOURCE_OR_DESTINATION_RESOURCE_TYPE("InvalidSourceOrDestinationResourceType", HttpURLConnection.HTTP_CONFLICT, null),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.hadoop.fs.azurebfs.contracts.services;
20+
21+
/**
22+
* Following parameters are used by AbfsBlobClient only.
23+
* Blob Endpoint Append API requires blockId and eTag to be passed in the request.
24+
*/
25+
public class BlobAppendRequestParameters {
26+
private String blockId;
27+
private String eTag;
28+
29+
/**
30+
* Constructor to be used for interacting with AbfsBlobClient.
31+
* @param blockId blockId of the block to be appended
32+
* @param eTag eTag of the blob being appended
33+
*/
34+
public BlobAppendRequestParameters(String blockId, String eTag) {
35+
this.blockId = blockId;
36+
this.eTag = eTag;
37+
}
38+
39+
public String getBlockId() {
40+
return blockId;
41+
}
42+
43+
public String getETag() {
44+
return eTag;
45+
}
46+
}

0 commit comments

Comments
 (0)