anmolanmol1234 commented on code in PR #7272:
URL: https://github.com/apache/hadoop/pull/7272#discussion_r1930121904
##########
hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsBlobClient.java:
##########
@@ -377,8 +390,199 @@ public AbfsRestOperation createPath(final String path,
final String eTag,
final ContextEncryptionAdapter contextEncryptionAdapter,
final TracingContext tracingContext) throws AzureBlobFileSystemException
{
- // TODO: [FnsOverBlob][HADOOP-19232] To be implemented as part of ingress
support.
- throw new NotImplementedException("Create Path operation on Blob endpoint
yet to be implemented.");
+ return createPath(path, isFile, overwrite, permissions, isAppendBlob, eTag,
+ contextEncryptionAdapter, tracingContext, false);
+ }
+
+ /**
+ * Get Rest Operation for API
+ * <a
href="https://learn.microsoft.com/en-us/rest/api/storageservices/put-blob">Put
Blob</a>.
+ * Creates a file or directory (marker file) at the specified path.
+ *
+ * @param path the path of the directory to be created.
+ * @param isFile whether the path is a file.
+ * @param overwrite whether to overwrite if the path already exists.
+ * @param permissions the permissions to set on the path.
+ * @param isAppendBlob whether the path is an append blob.
+ * @param eTag the eTag of the path.
+ * @param contextEncryptionAdapter the context encryption adapter.
+ * @param tracingContext the tracing context.
+ * @param isCreateCalledFromMarkers whether the create is called from
markers.
+ * @return the executed rest operation containing the response from the
server.
+ * @throws AzureBlobFileSystemException if the rest operation fails.
+ */
+ public AbfsRestOperation createPath(final String path,
+ final boolean isFile,
+ final boolean overwrite,
+ final AzureBlobFileSystemStore.Permissions permissions,
+ final boolean isAppendBlob,
+ final String eTag,
+ final ContextEncryptionAdapter contextEncryptionAdapter,
+ final TracingContext tracingContext,
+ boolean isCreateCalledFromMarkers) throws AzureBlobFileSystemException {
+ final List<AbfsHttpHeader> requestHeaders = createDefaultHeaders();
+ if (!getIsNamespaceEnabled() && !isCreateCalledFromMarkers) {
+ AbfsHttpOperation op1Result = null;
+ try {
+ op1Result = getPathStatus(path, tracingContext,
+ null, true).getResult();
+ } catch (AbfsRestOperationException ex) {
+ if (ex.getStatusCode() == HTTP_NOT_FOUND) {
+ LOG.debug("No directory/path found: {}", path);
+ } else {
+ throw ex;
+ }
+ }
+ if (op1Result != null) {
+ boolean isDir = checkIsDir(op1Result);
+ if (isFile == isDir) {
+ throw new AbfsRestOperationException(HTTP_CONFLICT,
+ AzureServiceErrorCode.PATH_CONFLICT.getErrorCode(),
+ PATH_EXISTS,
+ null);
+ }
+ }
+ Path parentPath = new Path(path).getParent();
+ if (parentPath != null && !parentPath.isRoot()) {
+ createMarkers(parentPath, overwrite, permissions, isAppendBlob, eTag,
+ contextEncryptionAdapter, tracingContext);
+ }
+ }
+ if (isFile) {
+ addEncryptionKeyRequestHeaders(path, requestHeaders, true,
+ contextEncryptionAdapter, tracingContext);
+ } else {
+ requestHeaders.add(new AbfsHttpHeader(X_MS_META_HDI_ISFOLDER, TRUE));
+ }
+ requestHeaders.add(new AbfsHttpHeader(CONTENT_LENGTH, ZERO));
+ if (isAppendBlob) {
+ requestHeaders.add(new AbfsHttpHeader(X_MS_BLOB_TYPE, APPEND_BLOB_TYPE));
+ } else {
+ requestHeaders.add(new AbfsHttpHeader(X_MS_BLOB_TYPE, BLOCK_BLOB_TYPE));
+ }
+ if (!overwrite) {
+ requestHeaders.add(new AbfsHttpHeader(IF_NONE_MATCH,
AbfsHttpConstants.STAR));
+ }
+ if (eTag != null && !eTag.isEmpty()) {
+ requestHeaders.add(new AbfsHttpHeader(HttpHeaderConfigurations.IF_MATCH,
eTag));
+ }
+
+ final AbfsUriQueryBuilder abfsUriQueryBuilder =
createDefaultUriQueryBuilder();
+ appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION,
abfsUriQueryBuilder);
+
+ final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
+ final AbfsRestOperation op = getAbfsRestOperation(
+ AbfsRestOperationType.PutBlob,
+ HTTP_METHOD_PUT, url, requestHeaders);
+ try {
+ op.execute(tracingContext);
+ } catch (AzureBlobFileSystemException ex) {
+ // If we have no HTTP response, throw the original exception.
+ if (!op.hasResult()) {
+ throw ex;
+ }
+ if (!isFile && op.getResult().getStatusCode() == HTTP_CONFLICT) {
+ // This ensures that we don't throw ex only for existing directory but
if a blob exists we throw exception.
+ AbfsHttpOperation opResult = null;
+ try {
+ opResult = this.getPathStatus(path, true, tracingContext,
null).getResult();
+ } catch (AbfsRestOperationException e) {
+ if (opResult != null) {
+ throw e;
+ }
+ }
+ if (opResult != null && checkIsDir(opResult)) {
+ return op;
+ }
+ }
+ throw ex;
+ }
+ return op;
+ }
+
+ /**
+ * Creates marker blobs for the parent directories of the specified path.
+ *
+ * @param path The path for which parent directories need to be created.
+ * @param overwrite A flag indicating whether existing directories should be
overwritten.
+ * @param permissions The permissions to be set for the created directories.
+ * @param isAppendBlob A flag indicating whether the created blob should be
of type APPEND_BLOB.
+ * @param eTag The eTag to be matched for conditional requests.
+ * @param contextEncryptionAdapter The encryption adapter for context
encryption.
+ * @param tracingContext The tracing context for the operation.
+ * @throws AzureBlobFileSystemException If the creation of any parent
directory fails.
+ */
+ private void createMarkers(final Path path,
+ final boolean overwrite,
+ final AzureBlobFileSystemStore.Permissions permissions,
+ final boolean isAppendBlob,
+ final String eTag,
+ final ContextEncryptionAdapter contextEncryptionAdapter,
+ final TracingContext tracingContext) throws AzureBlobFileSystemException
{
+ ArrayList<Path> keysToCreateAsFolder = new ArrayList<>();
+ checkParentChainForFile(path, tracingContext,
+ keysToCreateAsFolder);
+ for (Path pathToCreate : keysToCreateAsFolder) {
+ createPath(pathToCreate.toUri().getPath(), false, overwrite, permissions,
+ isAppendBlob, eTag, contextEncryptionAdapter, tracingContext, true);
+ }
+ }
+
+ /**
+ * Checks for the entire parent hierarchy and returns if any directory
exists and
+ * throws an exception if any file exists.
+ * @param path path to check the hierarchy for.
+ * @param tracingContext the tracingcontext.
+ */
+ private void checkParentChainForFile(Path path, TracingContext
tracingContext,
+ List<Path> keysToCreateAsFolder) throws AzureBlobFileSystemException {
+ AbfsHttpOperation opResult = null;
+ try {
+ opResult = getPathStatus(path.toUri().getPath(),
+ tracingContext, null, false).getResult();
+ } catch (AbfsRestOperationException ex) {
+ if (ex.getStatusCode() == HTTP_NOT_FOUND) {
+ LOG.debug("No explicit directory/path found: {}", path);
+ } else {
+ throw ex;
Review Comment:
taken
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]