diff --git a/sdk/storage/azure-storage-file-share/CHANGELOG.md b/sdk/storage/azure-storage-file-share/CHANGELOG.md index 7d314d9e8466b..1f69d2178a0ae 100644 --- a/sdk/storage/azure-storage-file-share/CHANGELOG.md +++ b/sdk/storage/azure-storage-file-share/CHANGELOG.md @@ -3,6 +3,8 @@ ## 12.33.0-beta.1 (Unreleased) ### Features Added +- Added support for retrieving file and directory properties by file ID +- Added support for retrieving a file's hard links by file ID on SMB shares. - Added support for change feed on premium file shares. Added `ShareCreateOptions.setChangeFeedEnabled`, `setChangeFeedRetentionInDays` and `ShareSetPropertiesOptions.setChangeFeedEnabled`, `setChangeFeedRetentionInDays` to enable and configure change feed. diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareAsyncClient.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareAsyncClient.java index 1900beac97b1b..0cd2790f5cc0d 100644 --- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareAsyncClient.java +++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareAsyncClient.java @@ -21,6 +21,7 @@ import com.azure.storage.common.implementation.SasImplUtils; import com.azure.storage.common.implementation.StorageImplUtils; import com.azure.storage.file.share.implementation.AzureFileStorageImpl; +import com.azure.storage.file.share.implementation.ShareErrors; import com.azure.storage.file.share.implementation.models.SharePermission; import com.azure.storage.file.share.implementation.util.ModelHelper; import com.azure.storage.file.share.implementation.util.ShareSasImplUtil; @@ -173,6 +174,27 @@ public ShareDirectoryAsyncClient getDirectoryClient(String directoryName) { serviceVersion, sasToken); } + /** + * Creates a directory client that addresses a directory by its file ID. + * + *
Call {@link ShareDirectoryAsyncClient#getProperties()} on the returned client to retrieve properties without + * knowing the directory path. Obtain the ID from {@link FileSmbProperties#getFileId()} in a path-based properties + * response. Other service operations require a path-addressed client.
+ * + *{@code
+ * Mono properties = shareAsyncClient.getDirectoryClientByFileId(fileId).getProperties();
+ * }
+ *
+ * @param fileId The file ID of the directory.
+ * @return A client for interacting with the directory by ID.
+ * @throws IllegalArgumentException If {@code fileId} is null or blank.
+ */
+ public ShareDirectoryAsyncClient getDirectoryClientByFileId(String fileId) {
+ ShareErrors.validateFileId(fileId);
+ return new ShareDirectoryAsyncClient(azureFileStorageClient, shareName, "", fileId, snapshot, accountName,
+ serviceVersion, sasToken);
+ }
+
/**
* Constructs a {@link ShareFileAsyncClient} that interacts with the specified file.
*
@@ -187,6 +209,28 @@ public ShareFileAsyncClient getFileClient(String filePath) {
serviceVersion, sasToken);
}
+ /**
+ * Creates a file client that addresses a file by its file ID.
+ *
+ * Call {@link ShareFileAsyncClient#getProperties()} on the returned client to retrieve properties without knowing + * the file path. Obtain the ID from {@link FileSmbProperties#getFileId()} in a path-based properties response. + * The returned client supports property retrieval and {@link ShareFileAsyncClient#getFileLinks()} (SMB only). + * Other service operations require a path-addressed client.
+ * + *{@code
+ * Mono properties = shareAsyncClient.getFileClientByFileId(fileId).getProperties();
+ * }
+ *
+ * @param fileId The file ID of the file.
+ * @return A client for interacting with the file by ID.
+ * @throws IllegalArgumentException If {@code fileId} is null or blank.
+ */
+ public ShareFileAsyncClient getFileClientByFileId(String fileId) {
+ ShareErrors.validateFileId(fileId);
+ return new ShareFileAsyncClient(azureFileStorageClient, shareName, "", fileId, snapshot, accountName,
+ serviceVersion, sasToken);
+ }
+
/**
* Creates a new {@link ShareAsyncClient} linked to the {@code snapshot} of this share resource.
*
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareClient.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareClient.java
index ad7b672c3d7b5..24097375a410e 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareClient.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareClient.java
@@ -22,6 +22,7 @@
import com.azure.storage.common.implementation.SasImplUtils;
import com.azure.storage.common.implementation.StorageImplUtils;
import com.azure.storage.file.share.implementation.AzureFileStorageImpl;
+import com.azure.storage.file.share.implementation.ShareErrors;
import com.azure.storage.file.share.implementation.models.SharePermission;
import com.azure.storage.file.share.implementation.models.ShareSignedIdentifierWrapper;
import com.azure.storage.file.share.implementation.models.ShareStats;
@@ -180,6 +181,27 @@ public ShareDirectoryClient getDirectoryClient(String directoryName) {
serviceVersion, sasToken);
}
+ /**
+ * Creates a directory client that addresses a directory by its file ID.
+ *
+ * Call {@link ShareDirectoryClient#getProperties()} on the returned client to retrieve properties without + * knowing the directory path. Obtain the ID from {@link FileSmbProperties#getFileId()} in a path-based properties + * response. Other service operations require a path-addressed client.
+ * + *{@code
+ * ShareDirectoryProperties properties = shareClient.getDirectoryClientByFileId(fileId).getProperties();
+ * }
+ *
+ * @param fileId The file ID of the directory.
+ * @return A client for interacting with the directory by ID.
+ * @throws IllegalArgumentException If {@code fileId} is null or blank.
+ */
+ public ShareDirectoryClient getDirectoryClientByFileId(String fileId) {
+ ShareErrors.validateFileId(fileId);
+ return new ShareDirectoryClient(azureFileStorageClient, shareName, "", fileId, snapshot, accountName,
+ serviceVersion, sasToken);
+ }
+
/**
* Constructs a {@link ShareFileClient} that interacts with the specified file.
*
@@ -196,6 +218,30 @@ public ShareFileClient getFileClient(String filePath) {
azureFileStorageClient, shareName, filePath, snapshot, accountName, serviceVersion, sasToken);
}
+ /**
+ * Creates a file client that addresses a file by its file ID.
+ *
+ * Call {@link ShareFileClient#getProperties()} on the returned client to retrieve properties without knowing + * the file path. Obtain the ID from {@link FileSmbProperties#getFileId()} in a path-based properties response. + * The returned client supports property retrieval and {@link ShareFileClient#getFileLinks()} (SMB only). + * Other service operations require a path-addressed client.
+ * + *{@code
+ * ShareFileProperties properties = shareClient.getFileClientByFileId(fileId).getProperties();
+ * }
+ *
+ * @param fileId The file ID of the file.
+ * @return A client for interacting with the file by ID.
+ * @throws IllegalArgumentException If {@code fileId} is null or blank.
+ */
+ public ShareFileClient getFileClientByFileId(String fileId) {
+ ShareErrors.validateFileId(fileId);
+ ShareFileAsyncClient asyncClient = new ShareFileAsyncClient(azureFileStorageClient, shareName, "", fileId,
+ snapshot, accountName, serviceVersion, sasToken);
+ return new ShareFileClient(asyncClient, azureFileStorageClient, shareName, "", fileId, snapshot, accountName,
+ serviceVersion, sasToken);
+ }
+
/**
* Creates a new {@link ShareAsyncClient} linked to the {@code snapshot} of this share resource.
*
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareDirectoryAsyncClient.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareDirectoryAsyncClient.java
index 575d1d9f9b912..5b273b90b4614 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareDirectoryAsyncClient.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareDirectoryAsyncClient.java
@@ -23,6 +23,7 @@
import com.azure.storage.common.implementation.SasImplUtils;
import com.azure.storage.common.implementation.StorageImplUtils;
import com.azure.storage.file.share.implementation.AzureFileStorageImpl;
+import com.azure.storage.file.share.implementation.ShareErrors;
import com.azure.storage.file.share.implementation.models.CopyFileSmbInfo;
import com.azure.storage.file.share.implementation.models.DestinationLeaseAccessConditions;
import com.azure.storage.file.share.implementation.models.ListFilesIncludeType;
@@ -69,6 +70,10 @@
* Service. Operations allowed by the client are creating, deleting and listing subdirectory and file, retrieving
* properties, setting metadata and list or force close handles of the directory or file.
*
+ * Clients addressed by file ID support property retrieval. Other service operations, including existence checks, + * and child-client creation throw {@link IllegalStateException} or signal it through the returned publisher. + * Use a path-addressed client for these operations.
+ * *Instantiating an Asynchronous Directory Client
* * @@ -93,6 +98,7 @@ public class ShareDirectoryAsyncClient { private final AzureFileStorageImpl azureFileStorageClient; private final String shareName; private final String directoryPath; + private final String fileId; private final String snapshot; private final String accountName; private final ShareServiceVersion serviceVersion; @@ -110,10 +116,17 @@ public class ShareDirectoryAsyncClient { */ ShareDirectoryAsyncClient(AzureFileStorageImpl azureFileStorageClient, String shareName, String directoryPath, String snapshot, String accountName, ShareServiceVersion serviceVersion, AzureSasCredential sasToken) { + this(azureFileStorageClient, shareName, directoryPath, "", snapshot, accountName, serviceVersion, sasToken); + } + + ShareDirectoryAsyncClient(AzureFileStorageImpl azureFileStorageClient, String shareName, String directoryPath, + String fileId, String snapshot, String accountName, ShareServiceVersion serviceVersion, + AzureSasCredential sasToken) { Objects.requireNonNull(shareName, "'shareName' cannot be null."); Objects.requireNonNull(directoryPath); this.shareName = shareName; this.directoryPath = directoryPath; + this.fileId = fileId; this.snapshot = snapshot; this.azureFileStorageClient = azureFileStorageClient; this.accountName = accountName; @@ -123,8 +136,9 @@ public class ShareDirectoryAsyncClient { ShareDirectoryAsyncClient(ShareDirectoryAsyncClient directoryAsyncClient) { this(directoryAsyncClient.azureFileStorageClient, directoryAsyncClient.shareName, - Utility.urlEncode(directoryAsyncClient.directoryPath), directoryAsyncClient.snapshot, - directoryAsyncClient.accountName, directoryAsyncClient.serviceVersion, directoryAsyncClient.sasToken); + Utility.urlEncode(directoryAsyncClient.directoryPath), directoryAsyncClient.fileId, + directoryAsyncClient.snapshot, directoryAsyncClient.accountName, directoryAsyncClient.serviceVersion, + directoryAsyncClient.sasToken); } /** @@ -133,14 +147,26 @@ public class ShareDirectoryAsyncClient { * @return the URL of the storage directory client */ public String getDirectoryUrl() { - StringBuilder directoryUrlString = new StringBuilder(azureFileStorageClient.getUrl()).append("/") - .append(shareName) - .append("/") - .append(directoryPath); + String directoryUrlString = azureFileStorageClient.getUrl() + "/" + shareName; + if (fileId.isEmpty()) { + directoryUrlString += "/" + directoryPath; + } if (snapshot != null) { - directoryUrlString.append("?sharesnapshot=").append(snapshot); + directoryUrlString = Utility.appendQueryParameter(directoryUrlString, "sharesnapshot", snapshot); + } + if (!fileId.isEmpty()) { + directoryUrlString = Utility.appendQueryParameter(directoryUrlString, "fileid", Utility.urlEncode(fileId)); } - return directoryUrlString.toString(); + return directoryUrlString; + } + + /** + * Gets the file ID used to address the directory, or an empty string when the client is path-addressed. + * + * @return The file ID. + */ + public String getFileId() { + return fileId; } /** @@ -160,8 +186,10 @@ public ShareServiceVersion getServiceVersion() { * * @param fileName Name of the file * @return a ShareFileAsyncClient that interacts with the specified share + * @throws IllegalStateException If this client is addressed by file ID. */ public ShareFileAsyncClient getFileClient(String fileName) { + ShareErrors.validatePathOperation(fileId, "getFileClient"); String filePath = directoryPath + "/" + fileName; // Support for root directory if (directoryPath.isEmpty()) { @@ -179,8 +207,10 @@ public ShareFileAsyncClient getFileClient(String fileName) { * * @param subdirectoryName Name of the directory * @return a ShareDirectoryAsyncClient that interacts with the specified directory + * @throws IllegalStateException If this client is addressed by file ID. */ public ShareDirectoryAsyncClient getSubdirectoryClient(String subdirectoryName) { + ShareErrors.validatePathOperation(fileId, "getSubdirectoryClient"); StringBuilder directoryPathBuilder = new StringBuilder().append(this.directoryPath); if (!this.directoryPath.isEmpty() && !this.directoryPath.endsWith("/")) { directoryPathBuilder.append("/"); @@ -202,6 +232,7 @@ public ShareDirectoryAsyncClient getSubdirectoryClient(String subdirectoryName) * * * @return Flag indicating existence of the directory. + * @throws IllegalStateException If this client is addressed by file ID, emitted through the returned publisher. */ @ServiceMethod(returns = ReturnType.SINGLE) public MonoRetrieve directory properties
* + *This operation accepts path-addressed and file-ID-addressed clients. To retrieve properties without knowing + * the directory path, use {@link ShareAsyncClient#getDirectoryClientByFileId(String)}. Service availability determines + * whether a file-ID request succeeds; the client does not check the share protocol. If the service does not + * support property retrieval by ID for the share, use a path-addressed client.
+ * * *
* shareDirectoryAsyncClient.getProperties().subscribe(properties -> {
@@ -661,6 +701,11 @@ public Mono> getPropertiesWithResponse() {
Mono> getPropertiesWithResponse(Context context) {
context = context == null ? Context.NONE : context;
+ if (!fileId.isEmpty()) {
+ return azureFileStorageClient.getDirectories()
+ .getPropertiesByFileIdWithResponseAsync(shareName, fileId, snapshot, null, null, context)
+ .map(ModelHelper::mapShareDirectoryPropertiesResponse);
+ }
return azureFileStorageClient.getDirectories()
.getPropertiesWithResponseAsync(shareName, directoryPath, snapshot, null, context)
.map(ModelHelper::mapShareDirectoryPropertiesResponse);
@@ -770,6 +815,7 @@ public Mono> setPropertiesWithResponse(ShareDirecto
Mono> setPropertiesWithResponse(FileSmbProperties smbProperties, String filePermission,
FilePermissionFormat filePermissionFormat, FilePosixProperties posixProperties, Context context) {
+ ShareErrors.validatePathOperation(fileId, "setProperties");
context = context == null ? Context.NONE : context;
smbProperties = smbProperties == null ? new FileSmbProperties() : smbProperties;
posixProperties = posixProperties == null ? new FilePosixProperties() : posixProperties;
@@ -870,6 +916,7 @@ public Mono> setMetadataWithResponse(Map
Mono> setMetadataWithResponse(Map metadata,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "setMetadata");
context = context == null ? Context.NONE : context;
return azureFileStorageClient.getDirectories()
.setMetadataWithResponseAsync(shareName, directoryPath, null, metadata, context)
@@ -977,6 +1024,7 @@ public PagedFlux listFilesAndDirectories(ShareListFilesAndDirecto
PagedFlux listFilesAndDirectoriesWithOptionalTimeout(ShareListFilesAndDirectoriesOptions options,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listFilesAndDirectories");
final ShareListFilesAndDirectoriesOptions modifiedOptions
= options == null ? new ShareListFilesAndDirectoriesOptions() : options;
@@ -1046,6 +1094,7 @@ public PagedFlux listHandles(Integer maxResultPerPage, boolean recur
PagedFlux listHandlesWithOptionalTimeout(Integer maxResultPerPage, boolean recursive, Duration timeout,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "listHandles");
Function>> retriever = marker -> StorageImplUtils
.applyOptionalTimeout(this.azureFileStorageClient.getDirectories()
.listHandlesWithResponseAsync(shareName, directoryPath, marker, maxResultPerPage, null, snapshot,
@@ -1118,6 +1167,7 @@ public Mono> forceCloseHandleWithResponse(String hand
}
Mono> forceCloseHandleWithResponse(String handleId, Context context) {
+ ShareErrors.validatePathOperation(fileId, "forceCloseHandle");
return this.azureFileStorageClient.getDirectories()
.forceCloseHandlesWithResponseAsync(shareName, directoryPath, handleId, null, null, snapshot, false,
context)
@@ -1161,6 +1211,7 @@ public Mono forceCloseAllHandles(boolean recursive) {
}
PagedFlux forceCloseAllHandlesWithTimeout(boolean recursive, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "forceCloseAllHandles");
Function>> retriever = marker -> StorageImplUtils
.applyOptionalTimeout(this.azureFileStorageClient.getDirectories()
.forceCloseHandlesWithResponseAsync(shareName, directoryPath, "*", null, marker, snapshot, recursive,
@@ -1242,6 +1293,7 @@ public Mono> renameWithResponse(ShareFileRen
}
Mono> renameWithResponse(ShareFileRenameOptions options, Context context) {
+ ShareErrors.validatePathOperation(fileId, "rename");
StorageImplUtils.assertNotNull("options", options);
context = context == null ? Context.NONE : context;
@@ -2156,6 +2208,7 @@ public String generateSas(ShareServiceSasSignatureValues shareServiceSasSignatur
@Deprecated
public String generateSas(ShareServiceSasSignatureValues shareServiceSasSignatureValues,
Consumer stringToSignHandler, Context context) {
+ ShareErrors.validatePathOperation(fileId, "generateSas");
return new ShareSasImplUtil(shareServiceSasSignatureValues, getShareName(), getDirectoryPath())
.generateSas(SasImplUtils.extractSharedKeyCredential(getHttpPipeline()), stringToSignHandler, context);
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareDirectoryClient.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareDirectoryClient.java
index 416626a7113e8..69f94cc0001cd 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareDirectoryClient.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareDirectoryClient.java
@@ -20,14 +20,15 @@
import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
import com.azure.storage.common.StorageSharedKeyCredential;
+import com.azure.storage.common.Utility;
import com.azure.storage.common.implementation.SasImplUtils;
import com.azure.storage.common.implementation.StorageImplUtils;
import com.azure.storage.file.share.implementation.AzureFileStorageImpl;
+import com.azure.storage.file.share.implementation.ShareErrors;
import com.azure.storage.file.share.implementation.models.CopyFileSmbInfo;
import com.azure.storage.file.share.implementation.models.DestinationLeaseAccessConditions;
import com.azure.storage.file.share.implementation.models.DirectoriesCreateHeaders;
import com.azure.storage.file.share.implementation.models.DirectoriesForceCloseHandlesHeaders;
-import com.azure.storage.file.share.implementation.models.DirectoriesGetPropertiesHeaders;
import com.azure.storage.file.share.implementation.models.DirectoriesListHandlesHeaders;
import com.azure.storage.file.share.implementation.models.DirectoriesSetMetadataHeaders;
import com.azure.storage.file.share.implementation.models.DirectoriesSetPropertiesHeaders;
@@ -75,6 +76,9 @@
* Service. Operations allowed by the client are creating, deleting and listing subdirectory and file, retrieving
* properties, setting metadata and list or force close handles of the directory or file.
*
+ * Clients addressed by file ID support property retrieval. Other service operations, including existence checks,
+ * and child-client creation throw {@link IllegalStateException}. Use a path-addressed client for these operations.
+ *
* Instantiating an Synchronous Directory Client
*
*
@@ -100,6 +104,7 @@ public class ShareDirectoryClient {
private final AzureFileStorageImpl azureFileStorageClient;
private final String shareName;
private final String directoryPath;
+ private final String fileId;
private final String snapshot;
private final String accountName;
private final ShareServiceVersion serviceVersion;
@@ -118,24 +123,34 @@ public class ShareDirectoryClient {
*/
ShareDirectoryClient(AzureFileStorageImpl azureFileStorageClient, String shareName, String directoryPath,
String snapshot, String accountName, ShareServiceVersion serviceVersion, AzureSasCredential sasToken) {
+ this(azureFileStorageClient, shareName, directoryPath, "", snapshot, accountName, serviceVersion, sasToken);
+ }
+
+ ShareDirectoryClient(AzureFileStorageImpl azureFileStorageClient, String shareName, String directoryPath,
+ String fileId, String snapshot, String accountName, ShareServiceVersion serviceVersion,
+ AzureSasCredential sasToken) {
Objects.requireNonNull(shareName, "'shareName' cannot be null.");
Objects.requireNonNull(directoryPath);
this.shareName = shareName;
this.directoryPath = directoryPath;
+ this.fileId = fileId;
this.snapshot = snapshot;
this.azureFileStorageClient = azureFileStorageClient;
this.accountName = accountName;
this.serviceVersion = serviceVersion;
this.sasToken = sasToken;
- StringBuilder directoryUrlString = new StringBuilder(azureFileStorageClient.getUrl()).append("/")
- .append(shareName)
- .append("/")
- .append(directoryPath);
+ String directoryUrlString = azureFileStorageClient.getUrl() + "/" + shareName;
+ if (fileId.isEmpty()) {
+ directoryUrlString += "/" + directoryPath;
+ }
if (snapshot != null) {
- directoryUrlString.append("?sharesnapshot=").append(snapshot);
+ directoryUrlString = Utility.appendQueryParameter(directoryUrlString, "sharesnapshot", snapshot);
+ }
+ if (!fileId.isEmpty()) {
+ directoryUrlString = Utility.appendQueryParameter(directoryUrlString, "fileid", Utility.urlEncode(fileId));
}
- this.directoryUrl = directoryUrlString.toString();
+ this.directoryUrl = directoryUrlString;
}
/**
@@ -147,6 +162,15 @@ public String getDirectoryUrl() {
return this.directoryUrl;
}
+ /**
+ * Gets the file ID used to address the directory, or an empty string when the client is path-addressed.
+ *
+ * @return The file ID.
+ */
+ public String getFileId() {
+ return fileId;
+ }
+
/**
* Gets the service version the client is using.
*
@@ -164,8 +188,10 @@ public ShareServiceVersion getServiceVersion() {
*
* @param fileName Name of the file
* @return a ShareFileClient that interacts with the specified share
+ * @throws IllegalStateException If this client is addressed by file ID.
*/
public ShareFileClient getFileClient(String fileName) {
+ ShareErrors.validatePathOperation(fileId, "getFileClient");
String filePath = directoryPath + "/" + fileName;
// Support for root directory
if (directoryPath.isEmpty()) {
@@ -184,8 +210,10 @@ public ShareFileClient getFileClient(String fileName) {
*
* @param subdirectoryName Name of the directory
* @return a ShareDirectoryClient that interacts with the specified directory
+ * @throws IllegalStateException If this client is addressed by file ID.
*/
public ShareDirectoryClient getSubdirectoryClient(String subdirectoryName) {
+ ShareErrors.validatePathOperation(fileId, "getSubdirectoryClient");
boolean needPathDelimiter = !this.directoryPath.isEmpty() && !this.directoryPath.endsWith("/");
String subDirectoryPath = this.directoryPath + (needPathDelimiter ? "/" : "") + subdirectoryName;
return new ShareDirectoryClient(azureFileStorageClient, shareName, subDirectoryPath, snapshot, accountName,
@@ -204,6 +232,7 @@ public ShareDirectoryClient getSubdirectoryClient(String subdirectoryName) {
*
*
* @return Flag indicating existence of the directory.
+ * @throws IllegalStateException If this client is addressed by file ID.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Boolean exists() {
@@ -225,9 +254,11 @@ public Boolean exists() {
* @param timeout An optional timeout value beyond which a {@link RuntimeException} will be raised.
* @param context Additional context that is passed through the Http pipeline during the service call.
* @return Flag indicating existence of the directory.
+ * @throws IllegalStateException If this client is addressed by file ID.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response existsWithResponse(Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "exists");
try {
Response response = getPropertiesWithResponse(timeout, context);
return new SimpleResponse<>(response, true);
@@ -342,6 +373,7 @@ public Response createWithResponse(FileSmbProperties smbProp
@ServiceMethod(returns = ReturnType.SINGLE)
public Response createWithResponse(ShareDirectoryCreateOptions options, Duration timeout,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "create");
Context finalContext = context == null ? Context.NONE : context;
ShareDirectoryCreateOptions finalOptions = options == null ? new ShareDirectoryCreateOptions() : options;
@@ -494,6 +526,7 @@ public void delete() {
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response deleteWithResponse(Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "delete");
Context finalContext = context == null ? Context.NONE : context;
Callable> operation = () -> this.azureFileStorageClient.getDirectories()
.deleteNoCustomHeadersWithResponse(shareName, directoryPath, null, finalContext);
@@ -578,6 +611,11 @@ public Response deleteIfExistsWithResponse(Duration timeout, Context co
*
* Retrieve directory properties
*
+ * This operation accepts path-addressed and file-ID-addressed clients. To retrieve properties without knowing
+ * the directory path, use {@link ShareClient#getDirectoryClientByFileId(String)}. Service availability determines
+ * whether a file-ID request succeeds; the client does not check the share protocol. If the service does not
+ * support property retrieval by ID for the share, use a path-addressed client.
+ *
*
*
* ShareDirectoryProperties response = shareDirectoryClient.getProperties();
@@ -623,9 +661,11 @@ public ShareDirectoryProperties getProperties() {
@ServiceMethod(returns = ReturnType.SINGLE)
public Response getPropertiesWithResponse(Duration timeout, Context context) {
Context finalContext = context == null ? Context.NONE : context;
- Callable> operation
- = () -> this.azureFileStorageClient.getDirectories()
- .getPropertiesWithResponse(shareName, directoryPath, snapshot, null, finalContext);
+ Callable> operation = fileId.isEmpty()
+ ? () -> this.azureFileStorageClient.getDirectories()
+ .getPropertiesWithResponse(shareName, directoryPath, snapshot, null, finalContext)
+ : () -> this.azureFileStorageClient.getDirectories()
+ .getPropertiesByFileIdWithResponse(shareName, fileId, snapshot, null, null, finalContext);
return ModelHelper
.mapShareDirectoryPropertiesResponse(sendRequest(operation, timeout, ShareStorageException.class));
@@ -724,6 +764,7 @@ public Response setPropertiesWithResponse(FileSmbProperties
@ServiceMethod(returns = ReturnType.SINGLE)
public Response setPropertiesWithResponse(ShareDirectorySetPropertiesOptions options,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "setProperties");
Context finalContext = context == null ? Context.NONE : context;
ShareDirectorySetPropertiesOptions finalOptions
= options == null ? new ShareDirectorySetPropertiesOptions() : options;
@@ -831,6 +872,7 @@ public ShareDirectorySetMetadataInfo setMetadata(Map metadata) {
@ServiceMethod(returns = ReturnType.SINGLE)
public Response setMetadataWithResponse(Map metadata,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "setMetadata");
Context finalContext = context == null ? Context.NONE : context;
Callable> operation
= () -> this.azureFileStorageClient.getDirectories()
@@ -941,6 +983,7 @@ public PagedIterable listFilesAndDirectories(String prefix, Integ
@ServiceMethod(returns = ReturnType.COLLECTION)
public PagedIterable listFilesAndDirectories(ShareListFilesAndDirectoriesOptions options,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listFilesAndDirectories");
Context finalContext = context == null ? Context.NONE : context;
final ShareListFilesAndDirectoriesOptions modifiedOptions
@@ -1016,6 +1059,7 @@ public PagedIterable listHandles(Integer maxResultsPerPage, boolean
PagedIterable listHandlesWithOptionalTimeout(Integer maxResultPerPage, boolean recursive,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listHandles");
Context finalContext = context == null ? Context.NONE : context;
Function> retriever = (marker) -> {
Callable> operation
@@ -1092,6 +1136,7 @@ public CloseHandlesInfo forceCloseHandle(String handleId) {
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response forceCloseHandleWithResponse(String handleId, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "forceCloseHandle");
Context finalContext = context == null ? Context.NONE : context;
Callable> operation
@@ -1135,6 +1180,7 @@ public Response forceCloseHandleWithResponse(String handleId,
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public CloseHandlesInfo forceCloseAllHandles(boolean recursive, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "forceCloseAllHandles");
Context finalContext = context == null ? Context.NONE : context;
Function> retriever = (marker) -> {
@@ -1221,6 +1267,7 @@ public ShareDirectoryClient rename(String destinationPath) {
@ServiceMethod(returns = ReturnType.SINGLE)
public Response renameWithResponse(ShareFileRenameOptions options, Duration timeout,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "rename");
StorageImplUtils.assertNotNull("options", options);
Context finalContext = context == null ? Context.NONE : context;
@@ -2056,6 +2103,7 @@ public String generateSas(ShareServiceSasSignatureValues shareServiceSasSignatur
@Deprecated
public String generateSas(ShareServiceSasSignatureValues shareServiceSasSignatureValues,
Consumer stringToSignHandler, Context context) {
+ ShareErrors.validatePathOperation(fileId, "generateSas");
return new ShareSasImplUtil(shareServiceSasSignatureValues, getShareName(), getDirectoryPath())
.generateSas(SasImplUtils.extractSharedKeyCredential(getHttpPipeline()), stringToSignHandler, context);
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileAsyncClient.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileAsyncClient.java
index c6e2bde18e29c..67dc5c906881f 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileAsyncClient.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileAsyncClient.java
@@ -36,6 +36,7 @@
import com.azure.storage.common.implementation.StorageImplUtils;
import com.azure.storage.common.implementation.UploadUtils;
import com.azure.storage.file.share.implementation.AzureFileStorageImpl;
+import com.azure.storage.file.share.implementation.ShareErrors;
import com.azure.storage.file.share.implementation.models.CopyFileSmbInfo;
import com.azure.storage.file.share.implementation.models.DestinationLeaseAccessConditions;
import com.azure.storage.file.share.implementation.models.FilesDownloadHeaders;
@@ -60,6 +61,7 @@
import com.azure.storage.file.share.models.ShareFileDownloadHeaders;
import com.azure.storage.file.share.models.ShareFileHttpHeaders;
import com.azure.storage.file.share.models.ShareFileInfo;
+import com.azure.storage.file.share.models.ShareFileLinks;
import com.azure.storage.file.share.models.ShareFileMetadataInfo;
import com.azure.storage.file.share.models.ShareFilePermission;
import com.azure.storage.file.share.models.ShareFileProperties;
@@ -125,6 +127,10 @@
* Service. Operations allowed by the client are creating, copying, uploading, downloading, deleting and listing on a
* file, retrieving properties, setting metadata and list or force close handles of the file.
*
+ * Use {@link ShareAsyncClient#getFileClientByFileId(String)} to retrieve properties without knowing the file path.
+ * File-ID clients support {@link #getProperties()} and {@link #getFileLinks()} (SMB only).
+ * Other service operations require a path-addressed client.
+ *
* Instantiating an Asynchronous File Client
*
*
@@ -149,6 +155,7 @@ public class ShareFileAsyncClient {
private final AzureFileStorageImpl azureFileStorageClient;
private final String shareName;
private final String filePath;
+ private final String fileId;
private final String snapshot;
private final String accountName;
private final ShareServiceVersion serviceVersion;
@@ -164,11 +171,17 @@ public class ShareFileAsyncClient {
* @param snapshot The snapshot of the share
*/
ShareFileAsyncClient(AzureFileStorageImpl azureFileStorageClient, String shareName, String filePath,
+ String snapshot, String accountName, ShareServiceVersion serviceVersion, AzureSasCredential sasToken) {
+ this(azureFileStorageClient, shareName, filePath, "", snapshot, accountName, serviceVersion, sasToken);
+ }
+
+ ShareFileAsyncClient(AzureFileStorageImpl azureFileStorageClient, String shareName, String filePath, String fileId,
String snapshot, String accountName, ShareServiceVersion serviceVersion, AzureSasCredential sasToken) {
Objects.requireNonNull(shareName, "'shareName' cannot be null.");
Objects.requireNonNull(filePath, "'filePath' cannot be null.");
this.shareName = shareName;
this.filePath = filePath;
+ this.fileId = fileId;
this.snapshot = snapshot;
this.azureFileStorageClient = azureFileStorageClient;
this.accountName = accountName;
@@ -178,8 +191,8 @@ public class ShareFileAsyncClient {
ShareFileAsyncClient(ShareFileAsyncClient fileAsyncClient) {
this(fileAsyncClient.azureFileStorageClient, fileAsyncClient.shareName,
- Utility.urlEncode(fileAsyncClient.filePath), fileAsyncClient.snapshot, fileAsyncClient.accountName,
- fileAsyncClient.serviceVersion, fileAsyncClient.sasToken);
+ Utility.urlEncode(fileAsyncClient.filePath), fileAsyncClient.fileId, fileAsyncClient.snapshot,
+ fileAsyncClient.accountName, fileAsyncClient.serviceVersion, fileAsyncClient.sasToken);
}
/**
@@ -197,14 +210,17 @@ public String getAccountUrl() {
* @return the URL of the storage file client
*/
public String getFileUrl() {
- StringBuilder fileUrlstring = new StringBuilder(azureFileStorageClient.getUrl()).append("/")
- .append(shareName)
- .append("/")
- .append(filePath);
+ String fileUrlstring = azureFileStorageClient.getUrl() + "/" + shareName;
+ if (fileId.isEmpty()) {
+ fileUrlstring += "/" + filePath;
+ }
if (snapshot != null) {
- fileUrlstring.append("?sharesnapshot=").append(snapshot);
+ fileUrlstring = Utility.appendQueryParameter(fileUrlstring, "sharesnapshot", snapshot);
+ }
+ if (!fileId.isEmpty()) {
+ fileUrlstring = Utility.appendQueryParameter(fileUrlstring, "fileid", Utility.urlEncode(fileId));
}
- return fileUrlstring.toString();
+ return fileUrlstring;
}
/**
@@ -216,10 +232,53 @@ public ShareServiceVersion getServiceVersion() {
return serviceVersion;
}
+ /**
+ * Gets the file ID used to address the file, or an empty string when the client is path-addressed.
+ *
+ * @return The file ID.
+ */
+ public String getFileId() {
+ return fileId;
+ }
+
AzureSasCredential getSasToken() {
return sasToken;
}
+ /**
+ * SMB only. Gets the hard links to this file. This operation is available only for a file-ID-addressed client.
+ *
+ * @param requestConditions Conditions to apply to the request.
+ * @return A response containing the file properties and hard links.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getFileLinksWithResponse(ShareRequestConditions requestConditions) {
+ try {
+ ShareErrors.assertFileIdAddressed(fileId, "getFileLinks");
+ return withContext(context -> getFileLinksWithResponse(requestConditions, context));
+ } catch (RuntimeException exception) {
+ return monoError(LOGGER, exception);
+ }
+ }
+
+ Mono> getFileLinksWithResponse(ShareRequestConditions requestConditions, Context context) {
+ ShareRequestConditions conditions
+ = requestConditions == null ? new ShareRequestConditions() : requestConditions;
+ return azureFileStorageClient.getFiles()
+ .getHardLinksWithResponseAsync(shareName, fileId, snapshot, null, null, conditions.getLeaseId(), context)
+ .map(ModelHelper::getFileLinksResponse);
+ }
+
+ /**
+ * SMB only. Gets the file links. This operation is available only for a file-ID-addressed client.
+ *
+ * @return The file properties and hard links.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono getFileLinks() {
+ return getFileLinksWithResponse(null).flatMap(FluxUtil::toMono);
+ }
+
/**
* Determines if the file this client represents exists in the cloud.
*
@@ -261,6 +320,7 @@ public Mono> existsWithResponse() {
}
Mono> existsWithResponse(Context context) {
+ ShareErrors.validatePathOperation(fileId, "exists");
return this.getPropertiesWithResponse(null, context)
.map(cp -> (Response) new SimpleResponse<>(cp, true))
.onErrorResume(ModelHelper::checkDoesNotExistStatusCode, t -> {
@@ -464,6 +524,7 @@ Mono> createWithResponse(long maxSize, ShareFileHttpHead
FileSmbProperties smbProperties, String filePermission, FilePermissionFormat filePermissionFormat,
FilePosixProperties filePosixProperties, Map metadata, ShareRequestConditions requestConditions,
FilePropertySemantics filePropertySemantics, BinaryData binaryData, Context context) {
+ ShareErrors.validatePathOperation(fileId, "create");
final Context contextLocal = context == null ? Context.NONE : context;
final ShareRequestConditions requestConditionsLocal
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
@@ -652,6 +713,7 @@ public PollerFlux beginCopy(String sourceUrl, FileSmbPr
*/
public PollerFlux beginCopy(String sourceUrl, ShareFileCopyOptions options,
Duration pollInterval) {
+ ShareErrors.validatePathOperation(fileId, "beginCopy");
final ShareRequestConditions finalRequestConditions = options.getDestinationRequestConditions() == null
? new ShareRequestConditions()
@@ -878,6 +940,7 @@ public Mono> abortCopyWithResponse(String copyId, ShareRequestCon
Mono> abortCopyWithResponse(String copyId, ShareRequestConditions requestConditions,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "abortCopy");
requestConditions = requestConditions == null ? new ShareRequestConditions() : requestConditions;
return azureFileStorageClient.getFiles()
.abortCopyNoCustomHeadersWithResponseAsync(shareName, filePath, copyId, null,
@@ -1007,6 +1070,7 @@ public Mono> downloadToFileWithResponse(String dow
Mono> downloadToFileWithResponse(String downloadFilePath, ShareFileRange range,
ShareRequestConditions requestConditions, Context context) {
+ ShareErrors.validatePathOperation(fileId, "downloadToFile");
return Mono.using(() -> channelSetup(downloadFilePath, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW),
channel -> getPropertiesWithResponse(requestConditions, context)
.flatMap(response -> downloadResponseInChunk(response, channel, range, requestConditions, context)),
@@ -1185,6 +1249,7 @@ public Mono downloadWithResponse(ShareFileDownlo
}
Mono downloadWithResponse(ShareFileDownloadOptions options, Context context) {
+ ShareErrors.validatePathOperation(fileId, "download");
options = options == null ? new ShareFileDownloadOptions() : options;
ShareFileRange range = options.getRange() == null ? new ShareFileRange(0) : options.getRange();
ShareRequestConditions requestConditions
@@ -1349,6 +1414,7 @@ public Mono> deleteWithResponse(ShareRequestConditions requestCon
}
Mono> deleteWithResponse(ShareRequestConditions requestConditions, Context context) {
+ ShareErrors.validatePathOperation(fileId, "delete");
requestConditions = requestConditions == null ? new ShareRequestConditions() : requestConditions;
return azureFileStorageClient.getFiles()
.deleteNoCustomHeadersWithResponseAsync(shareName, filePath, null, requestConditions.getLeaseId(), context);
@@ -1445,6 +1511,11 @@ Mono> deleteIfExistsWithResponse(ShareRequestConditions reques
*
* Retrieve file properties
*
+ * This operation accepts path-addressed and file-ID-addressed clients. To address a file by ID, use
+ * {@link ShareAsyncClient#getFileClientByFileId(String)}. Service availability determines whether a file-ID request
+ * succeeds; the client does not check the share protocol. If the service does not support property retrieval by ID
+ * for the share, use a path-addressed client.
+ *
*
*
* shareFileAsyncClient.getProperties()
@@ -1530,6 +1601,12 @@ Mono> getPropertiesWithResponse(ShareRequestCondit
Context context) {
requestConditions = requestConditions == null ? new ShareRequestConditions() : requestConditions;
context = context == null ? Context.NONE : context;
+ if (!fileId.isEmpty()) {
+ return azureFileStorageClient.getFiles()
+ .getPropertiesByFileIdWithResponseAsync(shareName, fileId, snapshot, null, null,
+ requestConditions.getLeaseId(), context)
+ .map(ModelHelper::getPropertiesResponse);
+ }
return azureFileStorageClient.getFiles()
.getPropertiesWithResponseAsync(shareName, filePath, snapshot, null, requestConditions.getLeaseId(),
context)
@@ -1779,6 +1856,7 @@ public Mono> setPropertiesWithResponse(ShareFileSetPrope
Mono> setPropertiesWithResponse(long newFileSize, ShareFileHttpHeaders httpHeaders,
FileSmbProperties smbProperties, String filePermission, FilePermissionFormat filePermissionFormat,
FilePosixProperties fileposixProperties, ShareRequestConditions requestConditions, Context context) {
+ ShareErrors.validatePathOperation(fileId, "setProperties");
context = context == null ? Context.NONE : context;
requestConditions = requestConditions == null ? new ShareRequestConditions() : requestConditions;
smbProperties = smbProperties == null ? new FileSmbProperties() : smbProperties;
@@ -1922,6 +2000,7 @@ public Mono> setMetadataWithResponse(Map> setMetadataWithResponse(Map metadata,
ShareRequestConditions requestConditions, Context context) {
+ ShareErrors.validatePathOperation(fileId, "setMetadata");
requestConditions = requestConditions == null ? new ShareRequestConditions() : requestConditions;
context = context == null ? Context.NONE : context;
try {
@@ -2132,6 +2211,7 @@ public Mono> uploadWithResponse(ShareFileUploadOpt
}
Mono> uploadWithResponse(ShareFileUploadOptions options, Context context) {
+ ShareErrors.validatePathOperation(fileId, "upload");
try {
StorageImplUtils.assertNotNull("options", options);
ShareRequestConditions validatedRequestConditions = options.getRequestConditions() == null
@@ -2301,6 +2381,7 @@ public Mono> uploadRangeWithResponse(ShareFileUplo
* One-shot upload range.
*/
Mono> uploadRangeWithResponse(ShareFileUploadRangeOptions options, Context context) {
+ ShareErrors.validatePathOperation(fileId, "uploadRange");
ShareRequestConditions requestConditions
= options.getRequestConditions() == null ? new ShareRequestConditions() : options.getRequestConditions();
long rangeOffset = (options.getOffset() == null) ? 0L : options.getOffset();
@@ -2465,6 +2546,7 @@ public Mono> uploadRangeFromUrlWithRes
Mono>
uploadRangeFromUrlWithResponse(ShareFileUploadRangeFromUrlOptions options, Context context) {
+ ShareErrors.validatePathOperation(fileId, "uploadRangeFromUrl");
ShareRequestConditions modifiedRequestConditions = options.getDestinationRequestConditions() == null
? new ShareRequestConditions()
: options.getDestinationRequestConditions();
@@ -2588,6 +2670,7 @@ public Mono> clearRangeWithResponse(long length, l
Mono> clearRangeWithResponse(long length, long offset,
ShareRequestConditions requestConditions, Context context) {
+ ShareErrors.validatePathOperation(fileId, "clearRange");
requestConditions = requestConditions == null ? new ShareRequestConditions() : requestConditions;
ShareFileRange range = new ShareFileRange(offset, offset + length - 1);
context = context == null ? Context.NONE : context;
@@ -2622,6 +2705,7 @@ Mono> clearRangeWithResponse(long length, long off
* @param uploadFilePath The path where store the source file to upload
* @return An empty response.
* @throws UncheckedIOException If an I/O error occurs.
+ * @throws IllegalStateException If this client is addressed by file ID, emitted through the returned publisher.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono uploadFromFile(String uploadFilePath) {
@@ -2655,10 +2739,12 @@ public Mono uploadFromFile(String uploadFilePath) {
* @param requestConditions {@link ShareRequestConditions}
* @return An empty response.
* @throws UncheckedIOException If an I/O error occurs.
+ * @throws IllegalStateException If this client is addressed by file ID, emitted through the returned publisher.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono uploadFromFile(String uploadFilePath, ShareRequestConditions requestConditions) {
try {
+ ShareErrors.validatePathOperation(fileId, "uploadFromFile");
return Mono.using(() -> channelSetup(uploadFilePath, StandardOpenOption.READ),
channel -> Flux.fromIterable(sliceFile(uploadFilePath))
.flatMap(chunk -> uploadWithResponse(
@@ -2958,6 +3044,7 @@ PagedFlux listAllRangesInternal(ShareFileRange range, ShareR
Mono> listRangesWithResponse(ShareFileRange range,
ShareRequestConditions requestConditions, String previousSnapshot, Boolean supportRename, String marker,
Integer maxResultsPerPage, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listRanges");
ShareRequestConditions finalRequestConditions
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
@@ -3024,6 +3111,7 @@ public PagedFlux listHandles(Integer maxResultsPerPage) {
}
PagedFlux listHandlesWithOptionalTimeout(Integer maxResultsPerPage, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listHandles");
Function>> retriever = marker -> StorageImplUtils
.applyOptionalTimeout(this.azureFileStorageClient.getFiles()
.listHandlesWithResponseAsync(shareName, filePath, marker, maxResultsPerPage, null, snapshot, context),
@@ -3095,6 +3183,7 @@ public Mono> forceCloseHandleWithResponse(String hand
}
Mono> forceCloseHandleWithResponse(String handleId, Context context) {
+ ShareErrors.validatePathOperation(fileId, "forceCloseHandle");
context = context == null ? Context.NONE : context;
return azureFileStorageClient.getFiles()
.forceCloseHandlesWithResponseAsync(shareName, filePath, handleId, null, null, snapshot, context)
@@ -3136,6 +3225,7 @@ public Mono forceCloseAllHandles() {
}
PagedFlux forceCloseAllHandlesWithOptionalTimeout(Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "forceCloseAllHandles");
Function>> retriever = marker -> StorageImplUtils
.applyOptionalTimeout(
this.azureFileStorageClient.getFiles()
@@ -3221,6 +3311,7 @@ public Mono> renameWithResponse(ShareFileRenameOp
}
Mono> renameWithResponse(ShareFileRenameOptions options, Context context) {
+ ShareErrors.validatePathOperation(fileId, "rename");
StorageImplUtils.assertNotNull("options", options);
context = context == null ? Context.NONE : context;
@@ -3439,6 +3530,7 @@ public String generateSas(ShareServiceSasSignatureValues shareServiceSasSignatur
*/
public String generateSas(ShareServiceSasSignatureValues shareServiceSasSignatureValues,
Consumer stringToSignHandler, Context context) {
+ ShareErrors.validatePathOperation(fileId, "generateSas");
return new ShareSasImplUtil(shareServiceSasSignatureValues, getShareName(), getFilePath())
.generateSas(SasImplUtils.extractSharedKeyCredential(getHttpPipeline()), stringToSignHandler, context);
}
@@ -3490,6 +3582,7 @@ public Mono> createHardLinkWithResponse(ShareFileCreateH
Mono> createHardLinkWithResponse(String targetFile,
ShareRequestConditions requestConditions, Context context) {
+ ShareErrors.validatePathOperation(fileId, "createHardLink");
context = context == null ? Context.NONE : context;
requestConditions = requestConditions == null ? new ShareRequestConditions() : requestConditions;
return this.azureFileStorageClient.getFiles()
@@ -3545,6 +3638,7 @@ public Mono> createSymbolicLinkWithResponse(ShareFileCre
Mono> createSymbolicLinkWithResponse(String linkText, Map metadata,
OffsetDateTime fileCreationTime, OffsetDateTime fileLastWriteTime, String owner, String group,
ShareRequestConditions requestConditions, Context context) {
+ ShareErrors.validatePathOperation(fileId, "createSymbolicLink");
context = context == null ? Context.NONE : context;
requestConditions = requestConditions == null ? new ShareRequestConditions() : requestConditions;
String fileCreationTimeString = FileSmbProperties.parseFileSMBDate(fileCreationTime);
@@ -3596,6 +3690,7 @@ public Mono> getSymbolicLinkWithResponse() {
}
Mono> getSymbolicLinkWithResponse(Context context) {
+ ShareErrors.validatePathOperation(fileId, "getSymbolicLink");
context = context == null ? Context.NONE : context;
return this.azureFileStorageClient.getFiles()
.getSymbolicLinkWithResponseAsync(shareName, filePath, null, snapshot, null, context)
@@ -3630,6 +3725,7 @@ public String generateUserDelegationSas(ShareServiceSasSignatureValues shareServ
*/
public String generateUserDelegationSas(ShareServiceSasSignatureValues shareServiceSasSignatureValues,
UserDelegationKey userDelegationKey, Consumer stringToSignHandler, Context context) {
+ ShareErrors.validatePathOperation(fileId, "generateUserDelegationSas");
return new ShareSasImplUtil(shareServiceSasSignatureValues, getShareName(), getFilePath())
.generateUserDelegationSas(userDelegationKey, accountName, stringToSignHandler, context);
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileClient.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileClient.java
index 81febcdf9130d..c97912c2fa606 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileClient.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileClient.java
@@ -33,15 +33,18 @@
import com.azure.storage.common.implementation.StorageSeekableByteChannel;
import com.azure.storage.common.implementation.UploadUtils;
import com.azure.storage.file.share.implementation.AzureFileStorageImpl;
+import com.azure.storage.file.share.implementation.ShareErrors;
import com.azure.storage.file.share.implementation.models.CopyFileSmbInfo;
import com.azure.storage.file.share.implementation.models.DestinationLeaseAccessConditions;
import com.azure.storage.file.share.implementation.models.FilesCreateHardLinkHeaders;
import com.azure.storage.file.share.implementation.models.FilesCreateHeaders;
import com.azure.storage.file.share.implementation.models.FilesCreateSymbolicLinkHeaders;
import com.azure.storage.file.share.implementation.models.FilesForceCloseHandlesHeaders;
+import com.azure.storage.file.share.implementation.models.FilesGetHardLinksHeaders;
import com.azure.storage.file.share.implementation.models.FilesGetPropertiesHeaders;
import com.azure.storage.file.share.implementation.models.FilesGetRangeListHeaders;
import com.azure.storage.file.share.implementation.models.FilesGetSymbolicLinkHeaders;
+import com.azure.storage.file.share.implementation.models.HardLinkList;
import com.azure.storage.file.share.implementation.models.FilesListHandlesHeaders;
import com.azure.storage.file.share.implementation.models.FilesSetHttpHeadersHeaders;
import com.azure.storage.file.share.implementation.models.FilesSetMetadataHeaders;
@@ -66,6 +69,7 @@
import com.azure.storage.file.share.models.ShareFileDownloadResponse;
import com.azure.storage.file.share.models.ShareFileHttpHeaders;
import com.azure.storage.file.share.models.ShareFileInfo;
+import com.azure.storage.file.share.models.ShareFileLinks;
import com.azure.storage.file.share.models.ShareFileMetadataInfo;
import com.azure.storage.file.share.models.ShareFilePermission;
import com.azure.storage.file.share.models.ShareFileProperties;
@@ -119,6 +123,10 @@
* This class provides a client that contains all the operations for interacting files under Azure Storage File Service.
* Operations allowed by the client are creating, uploading, copying, listing, downloading, and deleting files.
*
+ * Use {@link ShareClient#getFileClientByFileId(String)} to retrieve properties without knowing the file path.
+ * File-ID clients support {@link #getProperties()} and {@link #getFileLinks()} (SMB only).
+ * Other service operations require a path-addressed client.
+ *
* Instantiating a synchronous File Client
*
*
@@ -144,6 +152,7 @@ public class ShareFileClient {
private final AzureFileStorageImpl azureFileStorageClient;
private final String shareName;
private final String filePath;
+ private final String fileId;
private final String snapshot;
private final String accountName;
private final ShareServiceVersion serviceVersion;
@@ -163,25 +172,36 @@ public class ShareFileClient {
ShareFileClient(ShareFileAsyncClient shareFileAsyncClient, AzureFileStorageImpl azureFileStorageClient,
String shareName, String filePath, String snapshot, String accountName, ShareServiceVersion serviceVersion,
AzureSasCredential sasToken) {
+ this(shareFileAsyncClient, azureFileStorageClient, shareName, filePath, "", snapshot, accountName,
+ serviceVersion, sasToken);
+ }
+
+ ShareFileClient(ShareFileAsyncClient shareFileAsyncClient, AzureFileStorageImpl azureFileStorageClient,
+ String shareName, String filePath, String fileId, String snapshot, String accountName,
+ ShareServiceVersion serviceVersion, AzureSasCredential sasToken) {
this.shareFileAsyncClient = shareFileAsyncClient;
Objects.requireNonNull(shareName, "'shareName' cannot be null.");
Objects.requireNonNull(filePath, "'filePath' cannot be null.");
this.shareName = shareName;
this.filePath = filePath;
+ this.fileId = fileId;
this.snapshot = snapshot;
this.azureFileStorageClient = azureFileStorageClient;
this.accountName = accountName;
this.serviceVersion = serviceVersion;
this.sasToken = sasToken;
- StringBuilder fileUrlstring = new StringBuilder(azureFileStorageClient.getUrl()).append("/")
- .append(shareName)
- .append("/")
- .append(filePath);
+ String fileUrlstring = azureFileStorageClient.getUrl() + "/" + shareName;
+ if (fileId.isEmpty()) {
+ fileUrlstring += "/" + filePath;
+ }
if (snapshot != null) {
- fileUrlstring.append("?sharesnapshot=").append(snapshot);
+ fileUrlstring = Utility.appendQueryParameter(fileUrlstring, "sharesnapshot", snapshot);
}
- this.fileUrlString = fileUrlstring.toString();
+ if (!fileId.isEmpty()) {
+ fileUrlstring = Utility.appendQueryParameter(fileUrlstring, "fileid", Utility.urlEncode(fileId));
+ }
+ this.fileUrlString = fileUrlstring;
}
/**
@@ -202,6 +222,15 @@ public String getFileUrl() {
return this.fileUrlString;
}
+ /**
+ * Gets the file ID used to address the file, or an empty string when the client is path-addressed.
+ *
+ * @return The file ID.
+ */
+ public String getFileId() {
+ return fileId;
+ }
+
/**
* Gets the service version the client is using.
*
@@ -211,6 +240,56 @@ public ShareServiceVersion getServiceVersion() {
return this.serviceVersion;
}
+ /**
+ * SMB only. Gets the hard links to this file. This operation is available only for a file-ID-addressed client.
+ *
+ * @return A response containing the file properties and hard links.
+ */
+ public Response getFileLinksWithResponse() {
+ return getFileLinksWithResponse(null, null, Context.NONE);
+ }
+
+ /**
+ * SMB only. Gets the hard links to this file. This operation is available only for a file-ID-addressed client.
+ *
+ * @param requestConditions Conditions to apply to the request.
+ * @return A response containing the file properties and hard links.
+ */
+ public Response getFileLinksWithResponse(ShareRequestConditions requestConditions) {
+ return getFileLinksWithResponse(requestConditions, null, Context.NONE);
+ }
+
+ /**
+ * SMB only. Gets the hard links to this file. This operation is available only for a file-ID-addressed client.
+ *
+ * @param requestConditions Conditions to apply to the request.
+ * @param timeout An optional timeout applied to the operation.
+ * @param context Additional context passed through the HTTP pipeline.
+ * @return A response containing the file properties and hard links.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Response getFileLinksWithResponse(ShareRequestConditions requestConditions, Duration timeout,
+ Context context) {
+ ShareErrors.assertFileIdAddressed(fileId, "getFileLinks");
+ ShareRequestConditions conditions
+ = requestConditions == null ? new ShareRequestConditions() : requestConditions;
+ Context finalContext = context == null ? Context.NONE : context;
+ Callable> operation = () -> azureFileStorageClient
+ .getFiles()
+ .getHardLinksWithResponse(shareName, fileId, snapshot, null, null, conditions.getLeaseId(), finalContext);
+ return ModelHelper.getFileLinksResponse(sendRequest(operation, timeout, ShareStorageException.class));
+ }
+
+ /**
+ * SMB only. Gets the file links. This operation is available only for a file-ID-addressed client.
+ *
+ * @return The file properties and hard links.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public ShareFileLinks getFileLinks() {
+ return getFileLinksWithResponse().getValue();
+ }
+
/**
* Opens a file input stream to download the file.
*
@@ -229,6 +308,7 @@ public final StorageFileInputStream openInputStream() {
* @throws ShareStorageException If a storage service error occurred.
*/
public final StorageFileInputStream openInputStream(ShareFileRange range) {
+ ShareErrors.validatePathOperation(fileId, "openInputStream");
return new StorageFileInputStream(shareFileAsyncClient, range.getStart(),
range.getEnd() == null ? null : (range.getEnd() - range.getStart() + 1));
}
@@ -253,6 +333,7 @@ public final StorageFileOutputStream getFileOutputStream() {
* @throws ShareStorageException If a storage service error occurred.
*/
public final StorageFileOutputStream getFileOutputStream(long offset) {
+ ShareErrors.validatePathOperation(fileId, "getFileOutputStream");
return new StorageFileOutputStream(shareFileAsyncClient, offset);
}
@@ -262,6 +343,7 @@ public final StorageFileOutputStream getFileOutputStream(long offset) {
* @return The opened channel.
*/
public SeekableByteChannel getFileSeekableByteChannelWrite(ShareFileSeekableByteChannelWriteOptions options) {
+ ShareErrors.validatePathOperation(fileId, "getFileSeekableByteChannelWrite");
Objects.requireNonNull(options, "'options' cannot be null.");
if (options.isOverwriteMode()) {
@@ -282,6 +364,7 @@ public SeekableByteChannel getFileSeekableByteChannelWrite(ShareFileSeekableByte
* @return The opened channel.
*/
public SeekableByteChannel getFileSeekableByteChannelRead(ShareFileSeekableByteChannelReadOptions options) {
+ ShareErrors.validatePathOperation(fileId, "getFileSeekableByteChannelRead");
ShareRequestConditions conditions = options != null ? options.getRequestConditions() : null;
Long configuredChunkSize = options != null ? options.getChunkSizeInBytes() : null;
int chunkSize
@@ -326,6 +409,7 @@ public Boolean exists() {
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response existsWithResponse(Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "exists");
try {
Response response = getPropertiesWithResponse(timeout, context);
return new SimpleResponse<>(response, true);
@@ -531,6 +615,7 @@ public Response createWithResponse(long maxSize, ShareFileHttpHea
@ServiceMethod(returns = ReturnType.SINGLE)
public Response createWithResponse(ShareFileCreateOptions options, Duration timeout,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "create");
StorageImplUtils.assertNotNull("options", options);
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions requestConditions
@@ -721,6 +806,7 @@ public SyncPoller beginCopy(String sourceUrl, FileSmbPr
*/
public SyncPoller beginCopy(String sourceUrl, ShareFileCopyOptions options,
Duration pollInterval) {
+ ShareErrors.validatePathOperation(fileId, "beginCopy");
final ShareRequestConditions finalRequestConditions = options.getDestinationRequestConditions() == null
? new ShareRequestConditions()
: options.getDestinationRequestConditions();
@@ -936,6 +1022,7 @@ public Response abortCopyWithResponse(String copyId, Duration timeout, Con
@ServiceMethod(returns = ReturnType.SINGLE)
public Response abortCopyWithResponse(String copyId, ShareRequestConditions requestConditions,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "abortCopy");
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions finalRequestConditions
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
@@ -1310,6 +1397,7 @@ public Response deleteWithResponse(Duration timeout, Context context) {
@ServiceMethod(returns = ReturnType.SINGLE)
public Response deleteWithResponse(ShareRequestConditions requestConditions, Duration timeout,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "delete");
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions finalRequestConditions
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
@@ -1398,6 +1486,11 @@ public Response deleteIfExistsWithResponse(ShareRequestConditions reque
*
* Retrieve file properties
*
+ * This operation accepts path-addressed and file-ID-addressed clients. To address a file by ID, use
+ * {@link ShareClient#getFileClientByFileId(String)}. Service availability determines whether a file-ID request
+ * succeeds; the client does not check the share protocol. If the service does not support property retrieval by ID
+ * for the share, use a path-addressed client.
+ *
*
*
* ShareFileProperties properties = fileClient.getProperties();
@@ -1480,9 +1573,13 @@ public Response getPropertiesWithResponse(ShareRequestCondi
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions finalRequestConditions
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
- Callable> operation = () -> this.azureFileStorageClient.getFiles()
- .getPropertiesWithResponse(shareName, filePath, snapshot, null, finalRequestConditions.getLeaseId(),
- finalContext);
+ Callable> operation = fileId.isEmpty()
+ ? () -> this.azureFileStorageClient.getFiles()
+ .getPropertiesWithResponse(shareName, filePath, snapshot, null, finalRequestConditions.getLeaseId(),
+ finalContext)
+ : () -> this.azureFileStorageClient.getFiles()
+ .getPropertiesByFileIdWithResponse(shareName, fileId, snapshot, null, null,
+ finalRequestConditions.getLeaseId(), finalContext);
return ModelHelper.getPropertiesResponse(sendRequest(operation, timeout, ShareStorageException.class));
}
@@ -1716,6 +1813,7 @@ public Response setPropertiesWithResponse(long newFileSize, Share
@ServiceMethod(returns = ReturnType.SINGLE)
public Response setPropertiesWithResponse(ShareFileSetPropertiesOptions options, Duration timeout,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "setProperties");
StorageImplUtils.assertNotNull("options", options);
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions finalRequestConditions
@@ -1869,6 +1967,7 @@ public Response setMetadataWithResponse(Map setMetadataWithResponse(Map metadata,
ShareRequestConditions requestConditions, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "setMetadata");
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions finalRequestConditions
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
@@ -2276,6 +2375,7 @@ public Response uploadRangeFromUrlWithResponse(
@ServiceMethod(returns = ReturnType.SINGLE)
public Response
uploadRangeFromUrlWithResponse(ShareFileUploadRangeFromUrlOptions options, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "uploadRangeFromUrl");
ShareRequestConditions finalRequestConditions = options.getDestinationRequestConditions() == null
? new ShareRequestConditions()
: options.getDestinationRequestConditions();
@@ -2390,6 +2490,7 @@ public Response clearRangeWithResponse(long length, long of
@ServiceMethod(returns = ReturnType.SINGLE)
public Response clearRangeWithResponse(long length, long offset,
ShareRequestConditions requestConditions, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "clearRange");
ShareRequestConditions finalRequestConditions
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
ShareFileRange range = new ShareFileRange(offset, offset + length - 1);
@@ -2420,6 +2521,7 @@ public Response clearRangeWithResponse(long length, long of
* Azure Docs Upload.
*
* @param uploadFilePath The path where store the source file to upload
+ * @throws IllegalStateException If this client is addressed by file ID.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public void uploadFromFile(String uploadFilePath) {
@@ -2447,6 +2549,7 @@ public void uploadFromFile(String uploadFilePath) {
*
* @param uploadFilePath The path where store the source file to upload
* @param requestConditions {@link ShareRequestConditions}
+ * @throws IllegalStateException If this client is addressed by file ID.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public void uploadFromFile(String uploadFilePath, ShareRequestConditions requestConditions) {
@@ -2546,6 +2649,7 @@ public PagedIterable listRanges(ShareFileRange range, Duration t
@ServiceMethod(returns = ReturnType.COLLECTION)
public PagedIterable listRanges(ShareFileRange range, ShareRequestConditions requestConditions,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listRanges");
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions finalRequestConditions
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
@@ -2735,6 +2839,7 @@ public ShareFileRangeList listRangesDiff(String previousSnapshot) {
@ServiceMethod(returns = ReturnType.SINGLE)
public Response listRangesDiffWithResponse(ShareFileListRangesDiffOptions options,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listRangesDiff");
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions requestConditions
= options.getRequestConditions() == null ? new ShareRequestConditions() : options.getRequestConditions();
@@ -2798,6 +2903,7 @@ public PagedIterable listHandles() {
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
public PagedIterable listHandles(Integer maxResultsPerPage, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listHandles");
Context finalContext = context == null ? Context.NONE : context;
try {
Callable> operation
@@ -2876,6 +2982,7 @@ public CloseHandlesInfo forceCloseHandle(String handleId) {
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response forceCloseHandleWithResponse(String handleId, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "forceCloseHandle");
Context finalContext = context == null ? Context.NONE : context;
Callable> operation = () -> azureFileStorageClient.getFiles()
.forceCloseHandlesWithResponse(shareName, filePath, handleId, null, null, snapshot, finalContext);
@@ -2913,6 +3020,7 @@ public Response forceCloseHandleWithResponse(String handleId,
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public CloseHandlesInfo forceCloseAllHandles(Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "forceCloseAllHandles");
Context finalContext = context == null ? Context.NONE : context;
try {
Callable> operation
@@ -3001,6 +3109,7 @@ public ShareFileClient rename(String destinationPath) {
@ServiceMethod(returns = ReturnType.SINGLE)
public Response renameWithResponse(ShareFileRenameOptions options, Duration timeout,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "rename");
StorageImplUtils.assertNotNull("options", options);
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions sourceRequestConditions = options.getSourceRequestConditions() == null
@@ -3223,6 +3332,7 @@ public String generateSas(ShareServiceSasSignatureValues shareServiceSasSignatur
*/
public String generateSas(ShareServiceSasSignatureValues shareServiceSasSignatureValues,
Consumer stringToSignHandler, Context context) {
+ ShareErrors.validatePathOperation(fileId, "generateSas");
return new ShareSasImplUtil(shareServiceSasSignatureValues, getShareName(), getFilePath())
.generateSas(SasImplUtils.extractSharedKeyCredential(getHttpPipeline()), stringToSignHandler, context);
}
@@ -3267,6 +3377,7 @@ public ShareFileInfo createHardLink(String targetFile) {
@ServiceMethod(returns = ReturnType.SINGLE)
public Response createHardLinkWithResponse(ShareFileCreateHardLinkOptions options, Duration timeout,
Context context) {
+ ShareErrors.validatePathOperation(fileId, "createHardLink");
StorageImplUtils.assertNotNull("options", options);
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions requestConditions
@@ -3318,6 +3429,7 @@ public ShareFileInfo createSymbolicLink(String linkText) {
*/
public Response createSymbolicLinkWithResponse(ShareFileCreateSymbolicLinkOptions options,
Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "createSymbolicLink");
StorageImplUtils.assertNotNull("options", options);
Context finalContext = context == null ? Context.NONE : context;
ShareRequestConditions requestConditions
@@ -3368,6 +3480,7 @@ public ShareFileSymbolicLinkInfo getSymbolicLink() {
* describing the symbolic link.
*/
public Response getSymbolicLinkWithResponse(Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "getSymbolicLink");
Context finalContext = context == null ? Context.NONE : context;
Callable> operation
@@ -3405,6 +3518,7 @@ public String generateUserDelegationSas(ShareServiceSasSignatureValues shareServ
*/
public String generateUserDelegationSas(ShareServiceSasSignatureValues shareServiceSasSignatureValues,
UserDelegationKey userDelegationKey, Consumer stringToSignHandler, Context context) {
+ ShareErrors.validatePathOperation(fileId, "generateUserDelegationSas");
return new ShareSasImplUtil(shareServiceSasSignatureValues, getShareName(), getFilePath())
.generateUserDelegationSas(userDelegationKey, accountName, stringToSignHandler, context);
}
@@ -3412,6 +3526,7 @@ public String generateUserDelegationSas(ShareServiceSasSignatureValues shareServ
ResponseBase listRangesWithResponse(ShareFileRange range,
ShareRequestConditions requestConditions, String previousSnapshot, Boolean supportRename, String marker,
Integer maxResultsPerPage, Duration timeout, Context context) {
+ ShareErrors.validatePathOperation(fileId, "listRanges");
ShareRequestConditions finalRequestConditions
= requestConditions == null ? new ShareRequestConditions() : requestConditions;
String rangeString = range == null ? null : range.toString();
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileClientBuilder.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileClientBuilder.java
index fe1fbc329ade4..44dbb88d833bd 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileClientBuilder.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/ShareFileClientBuilder.java
@@ -35,6 +35,7 @@
import com.azure.storage.common.policy.RequestRetryOptions;
import com.azure.storage.common.sas.CommonSasQueryParameters;
import com.azure.storage.file.share.implementation.AzureFileStorageImpl;
+import com.azure.storage.file.share.implementation.ShareErrors;
import com.azure.storage.file.share.implementation.util.BuilderHelper;
import com.azure.storage.file.share.models.ShareAudience;
import com.azure.storage.file.share.models.ShareTokenIntent;
@@ -162,6 +163,7 @@ public class ShareFileClientBuilder implements TokenCredentialTrait
*
- * Query parameters of the endpoint will be parsed in an attempt to generate a SAS token to authenticate
- * requests sent to the service.
+ * The {@code sharesnapshot} and {@code fileid} query parameters are parsed from the endpoint. Other query
+ * parameters are parsed in an attempt to generate a SAS token to authenticate requests sent to the service.
*
* @param endpoint The URL of the Azure Storage File instance to send service requests to and receive responses
* from.
@@ -340,10 +344,19 @@ public ShareFileClientBuilder endpoint(String endpoint) {
this.shareSnapshot = snapshotArray[0];
}
+ if (length >= 2) {
+ this.fileId = "";
+ }
+ String[] fileIdArray = queryParamsMap.remove("fileid");
+ if (fileIdArray != null) {
+ ShareErrors.validateFileId(fileIdArray[0]);
+ this.fileId = fileIdArray[0];
+ this.resourcePath = "";
+ }
+
// TODO (gapra): What happens if a user has custom queries?
// Attempt to get the SAS token from the URL passed
- String sasToken
- = new CommonSasQueryParameters(SasImplUtils.parseQueryString(fullUrl.getQuery()), false).encode();
+ String sasToken = new CommonSasQueryParameters(queryParamsMap, false).encode();
if (!CoreUtils.isNullOrEmpty(sasToken)) {
sasToken(sasToken);
}
@@ -367,6 +380,30 @@ public ShareFileClientBuilder shareName(String shareName) {
return this;
}
+ /**
+ * Sets the file ID used to address a file.
+ *
+ * Call {@link ShareFileClient#getProperties()} or {@link ShareFileAsyncClient#getProperties()} on the
+ * resulting client to retrieve properties without supplying the file path. File-ID clients also support
+ * {@link ShareFileClient#getFileLinks()} and {@link ShareFileAsyncClient#getFileLinks()} (SMB only).
+ * Other service operations require a path-addressed client.
+ *
+ * Setting a file ID clears the resource path. The file ID can also be read from the {@code fileid} query
+ * parameter when supplied in the endpoint. File IDs are supported only for file clients; building a directory
+ * client with a file ID configured throws {@link IllegalStateException}. Use {@link #resourcePath(String)} to
+ * clear the file ID and address a directory by path.
+ *
+ * @param fileId The file ID of the file.
+ * @return the updated ShareFileClientBuilder object
+ * @throws IllegalArgumentException If {@code fileId} is null or blank.
+ */
+ public ShareFileClientBuilder fileId(String fileId) {
+ ShareErrors.validateFileId(fileId);
+ this.fileId = fileId;
+ this.resourcePath = "";
+ return this;
+ }
+
/**
* Sets the shareSnapshot that the constructed clients will interact with. This shareSnapshot must be linked to the
* share that has been specified in the builder.
@@ -381,7 +418,8 @@ public ShareFileClientBuilder snapshot(String snapshot) {
}
/**
- * Sets the file that the constructed clients will interact with
+ * Sets the file or directory path that the constructed clients will interact with. Calling this method clears any
+ * file ID previously set with {@link #fileId(String)}.
*
* @param resourcePath Path of the file (or directory).
* @return the updated ShareFileClientBuilder object
@@ -389,6 +427,7 @@ public ShareFileClientBuilder snapshot(String snapshot) {
*/
public ShareFileClientBuilder resourcePath(String resourcePath) {
this.resourcePath = resourcePath;
+ this.fileId = "";
return this;
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/DirectoriesImpl.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/DirectoriesImpl.java
index f166775a06c68..466f68f0d3c69 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/DirectoriesImpl.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/DirectoriesImpl.java
@@ -631,6 +631,54 @@ Response renameNoCustomHeadersSync(@HostParam("url") String url, @PathPara
@HeaderParam("x-ms-source-allow-trailing-dot") Boolean allowSourceTrailingDot,
@HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
@HeaderParam("Accept") String accept, Context context);
+
+ @Get("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Mono> getPropertiesByFileId(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("restype") String restype,
+ @QueryParam("fileid") String fileId, @QueryParam("sharesnapshot") String sharesnapshot,
+ @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version,
+ @HeaderParam("x-ms-client-request-id") String requestId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Get("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Mono> getPropertiesByFileIdNoCustomHeaders(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("restype") String restype,
+ @QueryParam("fileid") String fileId, @QueryParam("sharesnapshot") String sharesnapshot,
+ @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version,
+ @HeaderParam("x-ms-client-request-id") String requestId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Get("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ ResponseBase getPropertiesByFileIdSync(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("restype") String restype,
+ @QueryParam("fileid") String fileId, @QueryParam("sharesnapshot") String sharesnapshot,
+ @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version,
+ @HeaderParam("x-ms-client-request-id") String requestId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Get("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Response getPropertiesByFileIdNoCustomHeadersSync(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("restype") String restype,
+ @QueryParam("fileid") String fileId, @QueryParam("sharesnapshot") String sharesnapshot,
+ @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version,
+ @HeaderParam("x-ms-client-request-id") String requestId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
}
/**
@@ -3767,4 +3815,262 @@ public Response renameNoCustomHeadersWithResponse(String shareName, String
throw ModelHelper.mapToShareStorageException(internalException);
}
}
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link ResponseBase} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getPropertiesByFileIdWithResponseAsync(
+ String shareName, String fileId, String sharesnapshot, Integer timeout, String requestId) {
+ return FluxUtil
+ .withContext(context -> getPropertiesByFileIdWithResponseAsync(shareName, fileId, sharesnapshot, timeout,
+ requestId, context))
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link ResponseBase} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getPropertiesByFileIdWithResponseAsync(
+ String shareName, String fileId, String sharesnapshot, Integer timeout, String requestId, Context context) {
+ final String restype = "directory";
+ final String accept = "application/xml";
+ return service
+ .getPropertiesByFileId(this.client.getUrl(), shareName, restype, fileId, sharesnapshot, timeout,
+ this.client.getVersion(), requestId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return A {@link Mono} that completes when a successful response is received.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono getPropertiesByFileIdAsync(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId) {
+ return getPropertiesByFileIdWithResponseAsync(shareName, fileId, sharesnapshot, timeout, requestId)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException)
+ .flatMap(ignored -> Mono.empty());
+ }
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return A {@link Mono} that completes when a successful response is received.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono getPropertiesByFileIdAsync(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId, Context context) {
+ return getPropertiesByFileIdWithResponseAsync(shareName, fileId, sharesnapshot, timeout, requestId, context)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException)
+ .flatMap(ignored -> Mono.empty());
+ }
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link Response} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getPropertiesByFileIdNoCustomHeadersWithResponseAsync(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId) {
+ return FluxUtil
+ .withContext(context -> getPropertiesByFileIdNoCustomHeadersWithResponseAsync(shareName, fileId,
+ sharesnapshot, timeout, requestId, context))
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link Response} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getPropertiesByFileIdNoCustomHeadersWithResponseAsync(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId, Context context) {
+ final String restype = "directory";
+ final String accept = "application/xml";
+ return service
+ .getPropertiesByFileIdNoCustomHeaders(this.client.getUrl(), shareName, restype, fileId, sharesnapshot,
+ timeout, this.client.getVersion(), requestId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link ResponseBase}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public ResponseBase getPropertiesByFileIdWithResponse(String shareName,
+ String fileId, String sharesnapshot, Integer timeout, String requestId, Context context) {
+ try {
+ final String restype = "directory";
+ final String accept = "application/xml";
+ return service.getPropertiesByFileIdSync(this.client.getUrl(), shareName, restype, fileId, sharesnapshot,
+ timeout, this.client.getVersion(), requestId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context);
+ } catch (ShareStorageExceptionInternal internalException) {
+ throw ModelHelper.mapToShareStorageException(internalException);
+ }
+ }
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public void getPropertiesByFileId(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId) {
+ getPropertiesByFileIdWithResponse(shareName, fileId, sharesnapshot, timeout, requestId, Context.NONE);
+ }
+
+ /**
+ * Returns all system properties for the directory identified by its file ID. The data returned does not include the
+ * files in the directory or any subdirectories.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link Response}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Response getPropertiesByFileIdNoCustomHeadersWithResponse(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId, Context context) {
+ try {
+ final String restype = "directory";
+ final String accept = "application/xml";
+ return service.getPropertiesByFileIdNoCustomHeadersSync(this.client.getUrl(), shareName, restype, fileId,
+ sharesnapshot, timeout, this.client.getVersion(), requestId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context);
+ } catch (ShareStorageExceptionInternal internalException) {
+ throw ModelHelper.mapToShareStorageException(internalException);
+ }
+ }
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/FilesImpl.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/FilesImpl.java
index e2391f3e79237..b0f43d2413ee3 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/FilesImpl.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/FilesImpl.java
@@ -38,6 +38,7 @@
import com.azure.storage.file.share.implementation.models.FilesDeleteHeaders;
import com.azure.storage.file.share.implementation.models.FilesDownloadHeaders;
import com.azure.storage.file.share.implementation.models.FilesForceCloseHandlesHeaders;
+import com.azure.storage.file.share.implementation.models.FilesGetHardLinksHeaders;
import com.azure.storage.file.share.implementation.models.FilesGetPropertiesHeaders;
import com.azure.storage.file.share.implementation.models.FilesGetRangeListHeaders;
import com.azure.storage.file.share.implementation.models.FilesGetSymbolicLinkHeaders;
@@ -49,6 +50,7 @@
import com.azure.storage.file.share.implementation.models.FilesStartCopyHeaders;
import com.azure.storage.file.share.implementation.models.FilesUploadRangeFromURLHeaders;
import com.azure.storage.file.share.implementation.models.FilesUploadRangeHeaders;
+import com.azure.storage.file.share.implementation.models.HardLinkList;
import com.azure.storage.file.share.implementation.models.ListHandlesResponse;
import com.azure.storage.file.share.implementation.models.ShareFileRangeWriteType;
import com.azure.storage.file.share.implementation.models.ShareStorageExceptionInternal;
@@ -104,6 +106,102 @@ public final class FilesImpl {
@ServiceInterface(name = "AzureFileStorageFiles")
public interface FilesService {
+ @Get("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Mono> getHardLinks(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("comp") String comp,
+ @QueryParam("sharesnapshot") String sharesnapshot, @QueryParam("fileid") String fileId,
+ @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version,
+ @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-lease-id") String leaseId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Get("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Mono> getHardLinksNoCustomHeaders(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("comp") String comp,
+ @QueryParam("sharesnapshot") String sharesnapshot, @QueryParam("fileid") String fileId,
+ @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version,
+ @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-lease-id") String leaseId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Get("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ ResponseBase getHardLinksSync(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("comp") String comp,
+ @QueryParam("sharesnapshot") String sharesnapshot, @QueryParam("fileid") String fileId,
+ @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version,
+ @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-lease-id") String leaseId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Get("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Response getHardLinksNoCustomHeadersSync(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("comp") String comp,
+ @QueryParam("sharesnapshot") String sharesnapshot, @QueryParam("fileid") String fileId,
+ @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version,
+ @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-lease-id") String leaseId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Head("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Mono> getPropertiesByFileId(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("fileid") String fileId,
+ @QueryParam("sharesnapshot") String sharesnapshot, @QueryParam("timeout") Integer timeout,
+ @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId,
+ @HeaderParam("x-ms-lease-id") String leaseId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Head("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Mono> getPropertiesByFileIdNoCustomHeaders(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("fileid") String fileId,
+ @QueryParam("sharesnapshot") String sharesnapshot, @QueryParam("timeout") Integer timeout,
+ @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId,
+ @HeaderParam("x-ms-lease-id") String leaseId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Head("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ ResponseBase getPropertiesByFileIdSync(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("fileid") String fileId,
+ @QueryParam("sharesnapshot") String sharesnapshot, @QueryParam("timeout") Integer timeout,
+ @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId,
+ @HeaderParam("x-ms-lease-id") String leaseId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
+ @Head("/{shareName}")
+ @ExpectedResponses({ 200 })
+ @UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
+ Response getPropertiesByFileIdNoCustomHeadersSync(@HostParam("url") String url,
+ @PathParam("shareName") String shareName, @QueryParam("fileid") String fileId,
+ @QueryParam("sharesnapshot") String sharesnapshot, @QueryParam("timeout") Integer timeout,
+ @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId,
+ @HeaderParam("x-ms-lease-id") String leaseId,
+ @HeaderParam("x-ms-allow-trailing-dot") Boolean allowTrailingDot,
+ @HeaderParam("x-ms-file-request-intent") ShareTokenIntent fileRequestIntent,
+ @HeaderParam("Accept") String accept, Context context);
+
@Put("/{shareName}/{fileName}")
@ExpectedResponses({ 201 })
@UnexpectedResponseExceptionType(ShareStorageExceptionInternal.class)
@@ -1513,6 +1611,544 @@ Response createHardLinkNoCustomHeadersSync(@HostParam("url") String url,
@HeaderParam("Accept") String accept, Context context);
}
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file along with {@link ResponseBase} on successful completion of
+ * {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getHardLinksWithResponseAsync(String shareName,
+ String fileId, String sharesnapshot, Integer timeout, String requestId, String leaseId) {
+ return FluxUtil
+ .withContext(context -> getHardLinksWithResponseAsync(shareName, fileId, sharesnapshot, timeout, requestId,
+ leaseId, context))
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file along with {@link ResponseBase} on successful completion of
+ * {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getHardLinksWithResponseAsync(String shareName,
+ String fileId, String sharesnapshot, Integer timeout, String requestId, String leaseId, Context context) {
+ final String comp = "hardlinks";
+ final String accept = "application/xml";
+ return service
+ .getHardLinks(this.client.getUrl(), shareName, comp, sharesnapshot, fileId, timeout,
+ this.client.getVersion(), requestId, leaseId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono getHardLinksAsync(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId, String leaseId) {
+ return getHardLinksWithResponseAsync(shareName, fileId, sharesnapshot, timeout, requestId, leaseId)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException)
+ .flatMap(res -> Mono.justOrEmpty(res.getValue()));
+ }
+
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono getHardLinksAsync(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId, String leaseId, Context context) {
+ return getHardLinksWithResponseAsync(shareName, fileId, sharesnapshot, timeout, requestId, leaseId, context)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException)
+ .flatMap(res -> Mono.justOrEmpty(res.getValue()));
+ }
+
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file along with {@link Response} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getHardLinksNoCustomHeadersWithResponseAsync(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId, String leaseId) {
+ return FluxUtil
+ .withContext(context -> getHardLinksNoCustomHeadersWithResponseAsync(shareName, fileId, sharesnapshot,
+ timeout, requestId, leaseId, context))
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file along with {@link Response} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getHardLinksNoCustomHeadersWithResponseAsync(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId, String leaseId, Context context) {
+ final String comp = "hardlinks";
+ final String accept = "application/xml";
+ return service
+ .getHardLinksNoCustomHeaders(this.client.getUrl(), shareName, comp, sharesnapshot, fileId, timeout,
+ this.client.getVersion(), requestId, leaseId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file along with {@link ResponseBase}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public ResponseBase getHardLinksWithResponse(String shareName,
+ String fileId, String sharesnapshot, Integer timeout, String requestId, String leaseId, Context context) {
+ try {
+ final String comp = "hardlinks";
+ final String accept = "application/xml";
+ return service.getHardLinksSync(this.client.getUrl(), shareName, comp, sharesnapshot, fileId, timeout,
+ this.client.getVersion(), requestId, leaseId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context);
+ } catch (ShareStorageExceptionInternal internalException) {
+ throw ModelHelper.mapToShareStorageException(internalException);
+ }
+ }
+
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public HardLinkList getHardLinks(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId, String leaseId) {
+ try {
+ return getHardLinksWithResponse(shareName, fileId, sharesnapshot, timeout, requestId, leaseId, Context.NONE)
+ .getValue();
+ } catch (ShareStorageExceptionInternal internalException) {
+ throw ModelHelper.mapToShareStorageException(internalException);
+ }
+ }
+
+ /**
+ * Returns the hard links of a file, along with all user-defined metadata, content properties, and system properties
+ * for the file. SMB only.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the file whose hard links are returned.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the list of hard links for a file along with {@link Response}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Response getHardLinksNoCustomHeadersWithResponse(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId, String leaseId, Context context) {
+ try {
+ final String comp = "hardlinks";
+ final String accept = "application/xml";
+ return service.getHardLinksNoCustomHeadersSync(this.client.getUrl(), shareName, comp, sharesnapshot, fileId,
+ timeout, this.client.getVersion(), requestId, leaseId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context);
+ } catch (ShareStorageExceptionInternal internalException) {
+ throw ModelHelper.mapToShareStorageException(internalException);
+ }
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link ResponseBase} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getPropertiesByFileIdWithResponseAsync(String shareName,
+ String fileId, String sharesnapshot, Integer timeout, String requestId, String leaseId) {
+ return FluxUtil
+ .withContext(context -> getPropertiesByFileIdWithResponseAsync(shareName, fileId, sharesnapshot, timeout,
+ requestId, leaseId, context))
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link ResponseBase} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getPropertiesByFileIdWithResponseAsync(String shareName,
+ String fileId, String sharesnapshot, Integer timeout, String requestId, String leaseId, Context context) {
+ final String accept = "application/xml";
+ return service
+ .getPropertiesByFileId(this.client.getUrl(), shareName, fileId, sharesnapshot, timeout,
+ this.client.getVersion(), requestId, leaseId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return A {@link Mono} that completes when a successful response is received.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono getPropertiesByFileIdAsync(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId, String leaseId) {
+ return getPropertiesByFileIdWithResponseAsync(shareName, fileId, sharesnapshot, timeout, requestId, leaseId)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException)
+ .flatMap(ignored -> Mono.empty());
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return A {@link Mono} that completes when a successful response is received.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono getPropertiesByFileIdAsync(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId, String leaseId, Context context) {
+ return getPropertiesByFileIdWithResponseAsync(shareName, fileId, sharesnapshot, timeout, requestId, leaseId,
+ context).onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException)
+ .flatMap(ignored -> Mono.empty());
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link Response} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getPropertiesByFileIdNoCustomHeadersWithResponseAsync(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId, String leaseId) {
+ return FluxUtil
+ .withContext(context -> getPropertiesByFileIdNoCustomHeadersWithResponseAsync(shareName, fileId,
+ sharesnapshot, timeout, requestId, leaseId, context))
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link Response} on successful completion of {@link Mono}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Mono> getPropertiesByFileIdNoCustomHeadersWithResponseAsync(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId, String leaseId, Context context) {
+ final String accept = "application/xml";
+ return service
+ .getPropertiesByFileIdNoCustomHeaders(this.client.getUrl(), shareName, fileId, sharesnapshot, timeout,
+ this.client.getVersion(), requestId, leaseId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context)
+ .onErrorMap(ShareStorageExceptionInternal.class, ModelHelper::mapToShareStorageException);
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link ResponseBase}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public ResponseBase getPropertiesByFileIdWithResponse(String shareName,
+ String fileId, String sharesnapshot, Integer timeout, String requestId, String leaseId, Context context) {
+ try {
+ final String accept = "application/xml";
+ return service.getPropertiesByFileIdSync(this.client.getUrl(), shareName, fileId, sharesnapshot, timeout,
+ this.client.getVersion(), requestId, leaseId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context);
+ } catch (ShareStorageExceptionInternal internalException) {
+ throw ModelHelper.mapToShareStorageException(internalException);
+ }
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public void getPropertiesByFileId(String shareName, String fileId, String sharesnapshot, Integer timeout,
+ String requestId, String leaseId) {
+ getPropertiesByFileIdWithResponse(shareName, fileId, sharesnapshot, timeout, requestId, leaseId, Context.NONE);
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties for the file identified by its
+ * file ID. It does not return the content of the file.
+ *
+ * @param shareName The name of the target share.
+ * @param fileId The file ID of the target file or directory.
+ * @param sharesnapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the share
+ * snapshot to query.
+ * @param timeout The timeout parameter is expressed in seconds. For more information, see <a
+ * href="https://learn.microsoft.com/rest/api/storageservices/Setting-Timeouts-for-File-Service-Operations">Setting
+ * Timeouts for File Service Operations.</a>.
+ * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
+ * analytics logs when storage analytics logging is enabled.
+ * @param leaseId If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ * @param context The context to associate with this operation.
+ * @throws IllegalArgumentException thrown if parameters fail the validation.
+ * @throws ShareStorageExceptionInternal thrown if the request is rejected by server.
+ * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
+ * @return the {@link Response}.
+ */
+ @ServiceMethod(returns = ReturnType.SINGLE)
+ public Response getPropertiesByFileIdNoCustomHeadersWithResponse(String shareName, String fileId,
+ String sharesnapshot, Integer timeout, String requestId, String leaseId, Context context) {
+ try {
+ final String accept = "application/xml";
+ return service.getPropertiesByFileIdNoCustomHeadersSync(this.client.getUrl(), shareName, fileId,
+ sharesnapshot, timeout, this.client.getVersion(), requestId, leaseId, this.client.isAllowTrailingDot(),
+ this.client.getFileRequestIntent(), accept, context);
+ } catch (ShareStorageExceptionInternal internalException) {
+ throw ModelHelper.mapToShareStorageException(internalException);
+ }
+ }
+
/**
* Creates a new file or replaces a file. Can also initialize the file with content.
*
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/ShareErrors.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/ShareErrors.java
new file mode 100644
index 0000000000000..2a7090c1dda4d
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/ShareErrors.java
@@ -0,0 +1,71 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.storage.file.share.implementation;
+
+import com.azure.core.util.CoreUtils;
+import com.azure.core.util.logging.ClientLogger;
+
+/**
+ * Shared checks for operations that require a particular resource addressing mode.
+ */
+public final class ShareErrors {
+ private static final ClientLogger LOGGER = new ClientLogger(ShareErrors.class);
+
+ private ShareErrors() {
+ }
+
+ /**
+ * Validates a file ID accepted by a client factory or builder.
+ *
+ * @param fileId The ID to validate.
+ * @throws IllegalArgumentException If the ID is null or blank.
+ */
+ public static void validateFileId(String fileId) {
+ if (fileId == null) {
+ throw LOGGER.logExceptionAsError(new IllegalArgumentException("'fileId' cannot be null."));
+ }
+ if (fileId.trim().isEmpty()) {
+ throw LOGGER.logExceptionAsError(new IllegalArgumentException("'fileId' cannot be empty."));
+ }
+ }
+
+ /**
+ * Throws if the client does not address its resource by file ID.
+ *
+ * @param fileId The client's file ID.
+ * @param operationName The operation name to report on failure.
+ * @throws IllegalStateException If the client is not file-ID-addressed.
+ */
+ public static void assertFileIdAddressed(String fileId, String operationName) {
+ if (CoreUtils.isNullOrEmpty(fileId)) {
+ throw LOGGER.logExceptionAsError(
+ new IllegalStateException(operationName + " requires a file-ID-addressed client."));
+ }
+ }
+
+ /**
+ * Validates that the client can perform a path-based operation.
+ *
+ * @param fileId The client's file ID.
+ * @param operationName The operation name to report on failure.
+ * @throws IllegalStateException If the client is file-ID-addressed.
+ */
+ public static void validatePathOperation(String fileId, String operationName) {
+ assertNotFileIdAddressed(fileId, operationName);
+ }
+
+ /**
+ * Throws if the client addresses its resource by file ID.
+ *
+ * @param fileId The client's file ID.
+ * @param operationName The operation name to report on failure.
+ * @throws IllegalStateException If the client is file-ID-addressed.
+ */
+ public static void assertNotFileIdAddressed(String fileId, String operationName) {
+ if (!CoreUtils.isNullOrEmpty(fileId)) {
+ throw LOGGER.logExceptionAsError(
+ new IllegalStateException(operationName + " is not supported for a file-ID-addressed client."));
+ }
+ }
+}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/accesshelpers/ShareDirectoryPropertiesHelper.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/accesshelpers/ShareDirectoryPropertiesHelper.java
index 7dd95ad83c29a..8ea3694fb668d 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/accesshelpers/ShareDirectoryPropertiesHelper.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/accesshelpers/ShareDirectoryPropertiesHelper.java
@@ -34,10 +34,12 @@ public interface ShareDirectoryPropertiesAccessor {
* encrypted using the specified algorithm. Otherwise, the value is set to false.
* @param smbProperties The SMB properties of the directory.
* @param posixProperties the NFS properties of the directory.
+ * @param fileName The name returned by the service.
* @return A new instance of {@link ShareDirectoryProperties}.
*/
ShareDirectoryProperties create(Map metadata, String eTag, OffsetDateTime lastModified,
- boolean isServerEncrypted, FileSmbProperties smbProperties, FilePosixProperties posixProperties);
+ boolean isServerEncrypted, FileSmbProperties smbProperties, FilePosixProperties posixProperties,
+ String fileName);
}
/**
@@ -59,11 +61,12 @@ public static void setAccessor(ShareDirectoryPropertiesAccessor accessor) {
* encrypted using the specified algorithm. Otherwise, the value is set to false.
* @param smbProperties The SMB properties of the directory.
* @param posixProperties the NFS properties of the directory.
+ * @param fileName The name returned by the service.
* @return A new instance of {@link ShareDirectoryProperties}.
*/
public static ShareDirectoryProperties create(Map metadata, String eTag,
OffsetDateTime lastModified, boolean isServerEncrypted, FileSmbProperties smbProperties,
- FilePosixProperties posixProperties) {
+ FilePosixProperties posixProperties, String fileName) {
// This looks odd but is necessary, it is possible to engage the access helper before anywhere else in the
// application accesses ShareDirectoryProperties which triggers the accessor to be configured. So, if the accessor
// is null this effectively pokes the class to set up the accessor.
@@ -72,6 +75,7 @@ public static ShareDirectoryProperties create(Map metadata, Stri
}
assert accessor != null;
- return accessor.create(metadata, eTag, lastModified, isServerEncrypted, smbProperties, posixProperties);
+ return accessor.create(metadata, eTag, lastModified, isServerEncrypted, smbProperties, posixProperties,
+ fileName);
}
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/accesshelpers/ShareFilePropertiesHelper.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/accesshelpers/ShareFilePropertiesHelper.java
index 7e6c151276cc8..31ae579a728d1 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/accesshelpers/ShareFilePropertiesHelper.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/accesshelpers/ShareFilePropertiesHelper.java
@@ -37,6 +37,7 @@ public interface ShareFilePropertiesAccessor {
* @param contentLength The number of bytes present in the response body.
* @param contentType The content type specified for the file. The default content type is
* application/octet-stream.
+ * @param contentLanguage The content language specified for the file.
* @param contentMd5 The MD5 hash of the file to check the message content integrity.
* @param contentEncoding This header returns the value that was specified for the Content-Encoding request header.
* @param cacheControl This header is returned if it was previously specified for the file.
@@ -67,15 +68,16 @@ public interface ShareFilePropertiesAccessor {
* completely encrypted using the specified algorithm. Otherwise, the value is set to false.
* @param smbProperties The SMB properties of the file.
* @param posixProperties The NFS properties of the file.
+ * @param fileName The name of the file when returned by a file-ID request.
* @return A new instance of {@link ShareFileProperties}.
*/
ShareFileProperties create(String eTag, OffsetDateTime lastModified, Map metadata,
- String fileType, Long contentLength, String contentType, byte[] contentMd5, String contentEncoding,
- String cacheControl, String contentDisposition, LeaseStatusType leaseStatusType,
+ String fileType, Long contentLength, String contentType, String contentLanguage, byte[] contentMd5,
+ String contentEncoding, String cacheControl, String contentDisposition, LeaseStatusType leaseStatusType,
LeaseStateType leaseStateType, LeaseDurationType leaseDurationType, OffsetDateTime copyCompletionTime,
String copyStatusDescription, String copyId, String copyProgress, String copySource,
CopyStatusType copyStatus, Boolean isServerEncrypted, FileSmbProperties smbProperties,
- FilePosixProperties posixProperties);
+ FilePosixProperties posixProperties, String fileName);
}
/**
@@ -97,6 +99,7 @@ public static void setAccessor(ShareFilePropertiesAccessor accessor) {
* @param contentLength The number of bytes present in the response body.
* @param contentType The content type specified for the file. The default content type is
* application/octet-stream.
+ * @param contentLanguage The content language specified for the file.
* @param contentMd5 The MD5 hash of the file to check the message content integrity.
* @param contentEncoding This header returns the value that was specified for the Content-Encoding request header.
* @param cacheControl This header is returned if it was previously specified for the file.
@@ -127,14 +130,16 @@ public static void setAccessor(ShareFilePropertiesAccessor accessor) {
* completely encrypted using the specified algorithm. Otherwise, the value is set to false.
* @param smbProperties The SMB properties of the file.
* @param posixProperties The NFS properties of the file.
+ * @param fileName The name of the file when returned by a file-ID request.
* @return A new instance of {@link ShareFileProperties}.
*/
public static ShareFileProperties create(String eTag, OffsetDateTime lastModified, Map metadata,
- String fileType, Long contentLength, String contentType, byte[] contentMd5, String contentEncoding,
- String cacheControl, String contentDisposition, LeaseStatusType leaseStatusType, LeaseStateType leaseStateType,
- LeaseDurationType leaseDurationType, OffsetDateTime copyCompletionTime, String copyStatusDescription,
- String copyId, String copyProgress, String copySource, CopyStatusType copyStatus, Boolean isServerEncrypted,
- FileSmbProperties smbProperties, FilePosixProperties posixProperties) {
+ String fileType, Long contentLength, String contentType, String contentLanguage, byte[] contentMd5,
+ String contentEncoding, String cacheControl, String contentDisposition, LeaseStatusType leaseStatusType,
+ LeaseStateType leaseStateType, LeaseDurationType leaseDurationType, OffsetDateTime copyCompletionTime,
+ String copyStatusDescription, String copyId, String copyProgress, String copySource, CopyStatusType copyStatus,
+ Boolean isServerEncrypted, FileSmbProperties smbProperties, FilePosixProperties posixProperties,
+ String fileName) {
// This looks odd but is necessary, it is possible to engage the access helper before anywhere else in the
// application accesses ShareFileProperties which triggers the accessor to be configured. So, if the accessor
// is null this effectively pokes the class to set up the accessor.
@@ -144,9 +149,9 @@ public static ShareFileProperties create(String eTag, OffsetDateTime lastModifie
}
assert accessor != null;
- return accessor.create(eTag, lastModified, metadata, fileType, contentLength, contentType, contentMd5,
- contentEncoding, cacheControl, contentDisposition, leaseStatusType, leaseStateType, leaseDurationType,
- copyCompletionTime, copyStatusDescription, copyId, copyProgress, copySource, copyStatus, isServerEncrypted,
- smbProperties, posixProperties);
+ return accessor.create(eTag, lastModified, metadata, fileType, contentLength, contentType, contentLanguage,
+ contentMd5, contentEncoding, cacheControl, contentDisposition, leaseStatusType, leaseStateType,
+ leaseDurationType, copyCompletionTime, copyStatusDescription, copyId, copyProgress, copySource, copyStatus,
+ isServerEncrypted, smbProperties, posixProperties, fileName);
}
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/DirectoriesGetPropertiesHeaders.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/DirectoriesGetPropertiesHeaders.java
index 6ac4d9f918b4c..84ed7b328e2f5 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/DirectoriesGetPropertiesHeaders.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/DirectoriesGetPropertiesHeaders.java
@@ -97,6 +97,12 @@ public final class DirectoriesGetPropertiesHeaders {
@Generated
private String xMsFileId;
+ /*
+ * The x-ms-file-name property.
+ */
+ @Generated
+ private String xMsFileName;
+
/*
* The x-ms-file-parent-id property.
*/
@@ -145,6 +151,8 @@ public final class DirectoriesGetPropertiesHeaders {
private static final HttpHeaderName X_MS_FILE_ID = HttpHeaderName.fromString("x-ms-file-id");
+ private static final HttpHeaderName X_MS_FILE_NAME = HttpHeaderName.fromString("x-ms-file-name");
+
private static final HttpHeaderName X_MS_FILE_PARENT_ID = HttpHeaderName.fromString("x-ms-file-parent-id");
private static final HttpHeaderName X_MS_MODE = HttpHeaderName.fromString("x-ms-mode");
@@ -204,6 +212,7 @@ public DirectoriesGetPropertiesHeaders(HttpHeaders rawHeaders) {
}
this.xMsFilePermissionKey = rawHeaders.getValue(X_MS_FILE_PERMISSION_KEY);
this.xMsFileId = rawHeaders.getValue(X_MS_FILE_ID);
+ this.xMsFileName = rawHeaders.getValue(X_MS_FILE_NAME);
this.xMsFileParentId = rawHeaders.getValue(X_MS_FILE_PARENT_ID);
this.xMsMode = rawHeaders.getValue(X_MS_MODE);
this.xMsOwner = rawHeaders.getValue(X_MS_OWNER);
@@ -525,6 +534,28 @@ public DirectoriesGetPropertiesHeaders setXMsFileId(String xMsFileId) {
return this;
}
+ /**
+ * Get the xMsFileName property: The x-ms-file-name property.
+ *
+ * @return the xMsFileName value.
+ */
+ @Generated
+ public String getXMsFileName() {
+ return this.xMsFileName;
+ }
+
+ /**
+ * Set the xMsFileName property: The x-ms-file-name property.
+ *
+ * @param xMsFileName the xMsFileName value to set.
+ * @return the DirectoriesGetPropertiesHeaders object itself.
+ */
+ @Generated
+ public DirectoriesGetPropertiesHeaders setXMsFileName(String xMsFileName) {
+ this.xMsFileName = xMsFileName;
+ return this;
+ }
+
/**
* Get the xMsFileParentId property: The x-ms-file-parent-id property.
*
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/FilesGetHardLinksHeaders.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/FilesGetHardLinksHeaders.java
new file mode 100644
index 0000000000000..dd9919d5906a7
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/FilesGetHardLinksHeaders.java
@@ -0,0 +1,1311 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+// Code generated by Microsoft (R) AutoRest Code Generator.
+
+package com.azure.storage.file.share.implementation.models;
+
+import com.azure.core.annotation.Fluent;
+import com.azure.core.annotation.Generated;
+import com.azure.core.http.HttpHeaderName;
+import com.azure.core.http.HttpHeaders;
+import com.azure.core.util.CoreUtils;
+import com.azure.core.util.DateTimeRfc1123;
+import com.azure.storage.file.share.models.CopyStatusType;
+import com.azure.storage.file.share.models.LeaseDurationType;
+import com.azure.storage.file.share.models.LeaseStateType;
+import com.azure.storage.file.share.models.LeaseStatusType;
+import com.azure.storage.file.share.models.NfsFileType;
+import java.time.OffsetDateTime;
+import java.util.Base64;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * The FilesGetHardLinksHeaders model.
+ */
+@Fluent
+public final class FilesGetHardLinksHeaders {
+ /*
+ * The Last-Modified property.
+ */
+ @Generated
+ private DateTimeRfc1123 lastModified;
+
+ /*
+ * The x-ms-meta- property.
+ */
+ @Generated
+ private Map xMsMeta;
+
+ /*
+ * The x-ms-type property.
+ */
+ @Generated
+ private String xMsType = "File";
+
+ /*
+ * The ETag property.
+ */
+ @Generated
+ private String eTag;
+
+ /*
+ * The x-ms-content-type property.
+ */
+ @Generated
+ private String xMsContentType;
+
+ /*
+ * The x-ms-content-length property.
+ */
+ @Generated
+ private Long xMsContentLength;
+
+ /*
+ * The x-ms-content-md5 property.
+ */
+ @Generated
+ private byte[] xMsContentMd5;
+
+ /*
+ * The x-ms-content-encoding property.
+ */
+ @Generated
+ private String xMsContentEncoding;
+
+ /*
+ * The x-ms-content-language property.
+ */
+ @Generated
+ private String xMsContentLanguage;
+
+ /*
+ * The x-ms-cache-control property.
+ */
+ @Generated
+ private String xMsCacheControl;
+
+ /*
+ * The x-ms-content-disposition property.
+ */
+ @Generated
+ private String xMsContentDisposition;
+
+ /*
+ * The x-ms-copy-completion-time property.
+ */
+ @Generated
+ private DateTimeRfc1123 xMsCopyCompletionTime;
+
+ /*
+ * The x-ms-copy-status-description property.
+ */
+ @Generated
+ private String xMsCopyStatusDescription;
+
+ /*
+ * The x-ms-copy-id property.
+ */
+ @Generated
+ private String xMsCopyId;
+
+ /*
+ * The x-ms-copy-progress property.
+ */
+ @Generated
+ private String xMsCopyProgress;
+
+ /*
+ * The x-ms-copy-source property.
+ */
+ @Generated
+ private String xMsCopySource;
+
+ /*
+ * The x-ms-copy-status property.
+ */
+ @Generated
+ private CopyStatusType xMsCopyStatus;
+
+ /*
+ * The x-ms-server-encrypted property.
+ */
+ @Generated
+ private Boolean xMsServerEncrypted;
+
+ /*
+ * The x-ms-file-attributes property.
+ */
+ @Generated
+ private String xMsFileAttributes;
+
+ /*
+ * The x-ms-file-creation-time property.
+ */
+ @Generated
+ private OffsetDateTime xMsFileCreationTime;
+
+ /*
+ * The x-ms-file-last-write-time property.
+ */
+ @Generated
+ private OffsetDateTime xMsFileLastWriteTime;
+
+ /*
+ * The x-ms-file-change-time property.
+ */
+ @Generated
+ private OffsetDateTime xMsFileChangeTime;
+
+ /*
+ * The x-ms-file-permission-key property.
+ */
+ @Generated
+ private String xMsFilePermissionKey;
+
+ /*
+ * The x-ms-file-id property.
+ */
+ @Generated
+ private String xMsFileId;
+
+ /*
+ * The x-ms-file-name property.
+ */
+ @Generated
+ private String xMsFileName;
+
+ /*
+ * The x-ms-file-parent-id property.
+ */
+ @Generated
+ private String xMsFileParentId;
+
+ /*
+ * The x-ms-lease-duration property.
+ */
+ @Generated
+ private LeaseDurationType xMsLeaseDuration;
+
+ /*
+ * The x-ms-lease-state property.
+ */
+ @Generated
+ private LeaseStateType xMsLeaseState;
+
+ /*
+ * The x-ms-lease-status property.
+ */
+ @Generated
+ private LeaseStatusType xMsLeaseStatus;
+
+ /*
+ * The x-ms-mode property.
+ */
+ @Generated
+ private String xMsMode;
+
+ /*
+ * The x-ms-owner property.
+ */
+ @Generated
+ private String xMsOwner;
+
+ /*
+ * The x-ms-group property.
+ */
+ @Generated
+ private String xMsGroup;
+
+ /*
+ * The x-ms-link-count property.
+ */
+ @Generated
+ private Integer xMsLinkCount;
+
+ /*
+ * The x-ms-file-file-type property.
+ */
+ @Generated
+ private NfsFileType xMsFileFileType;
+
+ /*
+ * The x-ms-request-id property.
+ */
+ @Generated
+ private String xMsRequestId;
+
+ /*
+ * The x-ms-version property.
+ */
+ @Generated
+ private String xMsVersion;
+
+ /*
+ * The Date property.
+ */
+ @Generated
+ private DateTimeRfc1123 date;
+
+ /*
+ * The x-ms-client-request-id property.
+ */
+ @Generated
+ private String xMsClientRequestId;
+
+ private static final HttpHeaderName X_MS_TYPE = HttpHeaderName.fromString("x-ms-type");
+
+ private static final HttpHeaderName X_MS_CONTENT_TYPE = HttpHeaderName.fromString("x-ms-content-type");
+
+ private static final HttpHeaderName X_MS_CONTENT_LENGTH = HttpHeaderName.fromString("x-ms-content-length");
+
+ private static final HttpHeaderName X_MS_CONTENT_MD5 = HttpHeaderName.fromString("x-ms-content-md5");
+
+ private static final HttpHeaderName X_MS_CONTENT_ENCODING = HttpHeaderName.fromString("x-ms-content-encoding");
+
+ private static final HttpHeaderName X_MS_CONTENT_LANGUAGE = HttpHeaderName.fromString("x-ms-content-language");
+
+ private static final HttpHeaderName X_MS_CACHE_CONTROL = HttpHeaderName.fromString("x-ms-cache-control");
+
+ private static final HttpHeaderName X_MS_CONTENT_DISPOSITION
+ = HttpHeaderName.fromString("x-ms-content-disposition");
+
+ private static final HttpHeaderName X_MS_COPY_COMPLETION_TIME
+ = HttpHeaderName.fromString("x-ms-copy-completion-time");
+
+ private static final HttpHeaderName X_MS_COPY_STATUS_DESCRIPTION
+ = HttpHeaderName.fromString("x-ms-copy-status-description");
+
+ private static final HttpHeaderName X_MS_COPY_ID = HttpHeaderName.fromString("x-ms-copy-id");
+
+ private static final HttpHeaderName X_MS_COPY_PROGRESS = HttpHeaderName.fromString("x-ms-copy-progress");
+
+ private static final HttpHeaderName X_MS_COPY_SOURCE = HttpHeaderName.fromString("x-ms-copy-source");
+
+ private static final HttpHeaderName X_MS_COPY_STATUS = HttpHeaderName.fromString("x-ms-copy-status");
+
+ private static final HttpHeaderName X_MS_SERVER_ENCRYPTED = HttpHeaderName.fromString("x-ms-server-encrypted");
+
+ private static final HttpHeaderName X_MS_FILE_ATTRIBUTES = HttpHeaderName.fromString("x-ms-file-attributes");
+
+ private static final HttpHeaderName X_MS_FILE_CREATION_TIME = HttpHeaderName.fromString("x-ms-file-creation-time");
+
+ private static final HttpHeaderName X_MS_FILE_LAST_WRITE_TIME
+ = HttpHeaderName.fromString("x-ms-file-last-write-time");
+
+ private static final HttpHeaderName X_MS_FILE_CHANGE_TIME = HttpHeaderName.fromString("x-ms-file-change-time");
+
+ private static final HttpHeaderName X_MS_FILE_PERMISSION_KEY
+ = HttpHeaderName.fromString("x-ms-file-permission-key");
+
+ private static final HttpHeaderName X_MS_FILE_ID = HttpHeaderName.fromString("x-ms-file-id");
+
+ private static final HttpHeaderName X_MS_FILE_NAME = HttpHeaderName.fromString("x-ms-file-name");
+
+ private static final HttpHeaderName X_MS_FILE_PARENT_ID = HttpHeaderName.fromString("x-ms-file-parent-id");
+
+ private static final HttpHeaderName X_MS_LEASE_DURATION = HttpHeaderName.fromString("x-ms-lease-duration");
+
+ private static final HttpHeaderName X_MS_LEASE_STATE = HttpHeaderName.fromString("x-ms-lease-state");
+
+ private static final HttpHeaderName X_MS_LEASE_STATUS = HttpHeaderName.fromString("x-ms-lease-status");
+
+ private static final HttpHeaderName X_MS_MODE = HttpHeaderName.fromString("x-ms-mode");
+
+ private static final HttpHeaderName X_MS_OWNER = HttpHeaderName.fromString("x-ms-owner");
+
+ private static final HttpHeaderName X_MS_GROUP = HttpHeaderName.fromString("x-ms-group");
+
+ private static final HttpHeaderName X_MS_LINK_COUNT = HttpHeaderName.fromString("x-ms-link-count");
+
+ private static final HttpHeaderName X_MS_FILE_FILE_TYPE = HttpHeaderName.fromString("x-ms-file-file-type");
+
+ private static final HttpHeaderName X_MS_VERSION = HttpHeaderName.fromString("x-ms-version");
+
+ // HttpHeaders containing the raw property values.
+ /**
+ * Creates an instance of FilesGetHardLinksHeaders class.
+ *
+ * @param rawHeaders The raw HttpHeaders that will be used to create the property values.
+ */
+ public FilesGetHardLinksHeaders(HttpHeaders rawHeaders) {
+ String lastModified = rawHeaders.getValue(HttpHeaderName.LAST_MODIFIED);
+ if (lastModified != null) {
+ this.lastModified = new DateTimeRfc1123(lastModified);
+ } else {
+ this.lastModified = null;
+ }
+ this.xMsType = rawHeaders.getValue(X_MS_TYPE);
+ this.eTag = rawHeaders.getValue(HttpHeaderName.ETAG);
+ this.xMsContentType = rawHeaders.getValue(X_MS_CONTENT_TYPE);
+ String xMsContentLength = rawHeaders.getValue(X_MS_CONTENT_LENGTH);
+ if (xMsContentLength != null) {
+ this.xMsContentLength = Long.parseLong(xMsContentLength);
+ } else {
+ this.xMsContentLength = null;
+ }
+ String xMsContentMd5 = rawHeaders.getValue(X_MS_CONTENT_MD5);
+ if (xMsContentMd5 != null) {
+ this.xMsContentMd5 = Base64.getDecoder().decode(xMsContentMd5);
+ } else {
+ this.xMsContentMd5 = null;
+ }
+ this.xMsContentEncoding = rawHeaders.getValue(X_MS_CONTENT_ENCODING);
+ this.xMsContentLanguage = rawHeaders.getValue(X_MS_CONTENT_LANGUAGE);
+ this.xMsCacheControl = rawHeaders.getValue(X_MS_CACHE_CONTROL);
+ this.xMsContentDisposition = rawHeaders.getValue(X_MS_CONTENT_DISPOSITION);
+ String xMsCopyCompletionTime = rawHeaders.getValue(X_MS_COPY_COMPLETION_TIME);
+ if (xMsCopyCompletionTime != null) {
+ this.xMsCopyCompletionTime = new DateTimeRfc1123(xMsCopyCompletionTime);
+ } else {
+ this.xMsCopyCompletionTime = null;
+ }
+ this.xMsCopyStatusDescription = rawHeaders.getValue(X_MS_COPY_STATUS_DESCRIPTION);
+ this.xMsCopyId = rawHeaders.getValue(X_MS_COPY_ID);
+ this.xMsCopyProgress = rawHeaders.getValue(X_MS_COPY_PROGRESS);
+ this.xMsCopySource = rawHeaders.getValue(X_MS_COPY_SOURCE);
+ String xMsCopyStatus = rawHeaders.getValue(X_MS_COPY_STATUS);
+ if (xMsCopyStatus != null) {
+ this.xMsCopyStatus = CopyStatusType.fromString(xMsCopyStatus);
+ } else {
+ this.xMsCopyStatus = null;
+ }
+ String xMsServerEncrypted = rawHeaders.getValue(X_MS_SERVER_ENCRYPTED);
+ if (xMsServerEncrypted != null) {
+ this.xMsServerEncrypted = Boolean.parseBoolean(xMsServerEncrypted);
+ } else {
+ this.xMsServerEncrypted = null;
+ }
+ this.xMsFileAttributes = rawHeaders.getValue(X_MS_FILE_ATTRIBUTES);
+ String xMsFileCreationTime = rawHeaders.getValue(X_MS_FILE_CREATION_TIME);
+ if (xMsFileCreationTime != null) {
+ this.xMsFileCreationTime = OffsetDateTime.parse(xMsFileCreationTime);
+ } else {
+ this.xMsFileCreationTime = null;
+ }
+ String xMsFileLastWriteTime = rawHeaders.getValue(X_MS_FILE_LAST_WRITE_TIME);
+ if (xMsFileLastWriteTime != null) {
+ this.xMsFileLastWriteTime = OffsetDateTime.parse(xMsFileLastWriteTime);
+ } else {
+ this.xMsFileLastWriteTime = null;
+ }
+ String xMsFileChangeTime = rawHeaders.getValue(X_MS_FILE_CHANGE_TIME);
+ if (xMsFileChangeTime != null) {
+ this.xMsFileChangeTime = OffsetDateTime.parse(xMsFileChangeTime);
+ } else {
+ this.xMsFileChangeTime = null;
+ }
+ this.xMsFilePermissionKey = rawHeaders.getValue(X_MS_FILE_PERMISSION_KEY);
+ this.xMsFileId = rawHeaders.getValue(X_MS_FILE_ID);
+ this.xMsFileName = rawHeaders.getValue(X_MS_FILE_NAME);
+ this.xMsFileParentId = rawHeaders.getValue(X_MS_FILE_PARENT_ID);
+ String xMsLeaseDuration = rawHeaders.getValue(X_MS_LEASE_DURATION);
+ if (xMsLeaseDuration != null) {
+ this.xMsLeaseDuration = LeaseDurationType.fromString(xMsLeaseDuration);
+ } else {
+ this.xMsLeaseDuration = null;
+ }
+ String xMsLeaseState = rawHeaders.getValue(X_MS_LEASE_STATE);
+ if (xMsLeaseState != null) {
+ this.xMsLeaseState = LeaseStateType.fromString(xMsLeaseState);
+ } else {
+ this.xMsLeaseState = null;
+ }
+ String xMsLeaseStatus = rawHeaders.getValue(X_MS_LEASE_STATUS);
+ if (xMsLeaseStatus != null) {
+ this.xMsLeaseStatus = LeaseStatusType.fromString(xMsLeaseStatus);
+ } else {
+ this.xMsLeaseStatus = null;
+ }
+ this.xMsMode = rawHeaders.getValue(X_MS_MODE);
+ this.xMsOwner = rawHeaders.getValue(X_MS_OWNER);
+ this.xMsGroup = rawHeaders.getValue(X_MS_GROUP);
+ String xMsLinkCount = rawHeaders.getValue(X_MS_LINK_COUNT);
+ if (xMsLinkCount != null) {
+ this.xMsLinkCount = Integer.parseInt(xMsLinkCount);
+ } else {
+ this.xMsLinkCount = null;
+ }
+ String xMsFileFileType = rawHeaders.getValue(X_MS_FILE_FILE_TYPE);
+ if (xMsFileFileType != null) {
+ this.xMsFileFileType = NfsFileType.fromString(xMsFileFileType);
+ } else {
+ this.xMsFileFileType = null;
+ }
+ this.xMsRequestId = rawHeaders.getValue(HttpHeaderName.X_MS_REQUEST_ID);
+ this.xMsVersion = rawHeaders.getValue(X_MS_VERSION);
+ String date = rawHeaders.getValue(HttpHeaderName.DATE);
+ if (date != null) {
+ this.date = new DateTimeRfc1123(date);
+ } else {
+ this.date = null;
+ }
+ this.xMsClientRequestId = rawHeaders.getValue(HttpHeaderName.X_MS_CLIENT_REQUEST_ID);
+ Map xMsMetaHeaderCollection = new LinkedHashMap<>();
+
+ rawHeaders.stream().forEach(header -> {
+ String headerName = header.getName();
+ if (headerName.startsWith("x-ms-meta-")) {
+ xMsMetaHeaderCollection.put(headerName.substring(10), header.getValue());
+ }
+ });
+ this.xMsMeta = xMsMetaHeaderCollection;
+ }
+
+ /**
+ * Get the lastModified property: The Last-Modified property.
+ *
+ * @return the lastModified value.
+ */
+ @Generated
+ public OffsetDateTime getLastModified() {
+ if (this.lastModified == null) {
+ return null;
+ }
+ return this.lastModified.getDateTime();
+ }
+
+ /**
+ * Set the lastModified property: The Last-Modified property.
+ *
+ * @param lastModified the lastModified value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setLastModified(OffsetDateTime lastModified) {
+ if (lastModified == null) {
+ this.lastModified = null;
+ } else {
+ this.lastModified = new DateTimeRfc1123(lastModified);
+ }
+ return this;
+ }
+
+ /**
+ * Get the xMsMeta property: The x-ms-meta- property.
+ *
+ * @return the xMsMeta value.
+ */
+ @Generated
+ public Map getXMsMeta() {
+ return this.xMsMeta;
+ }
+
+ /**
+ * Set the xMsMeta property: The x-ms-meta- property.
+ *
+ * @param xMsMeta the xMsMeta value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsMeta(Map xMsMeta) {
+ this.xMsMeta = xMsMeta;
+ return this;
+ }
+
+ /**
+ * Get the xMsType property: The x-ms-type property.
+ *
+ * @return the xMsType value.
+ */
+ @Generated
+ public String getXMsType() {
+ return this.xMsType;
+ }
+
+ /**
+ * Set the xMsType property: The x-ms-type property.
+ *
+ * @param xMsType the xMsType value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsType(String xMsType) {
+ this.xMsType = xMsType;
+ return this;
+ }
+
+ /**
+ * Get the eTag property: The ETag property.
+ *
+ * @return the eTag value.
+ */
+ @Generated
+ public String getETag() {
+ return this.eTag;
+ }
+
+ /**
+ * Set the eTag property: The ETag property.
+ *
+ * @param eTag the eTag value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setETag(String eTag) {
+ this.eTag = eTag;
+ return this;
+ }
+
+ /**
+ * Get the xMsContentType property: The x-ms-content-type property.
+ *
+ * @return the xMsContentType value.
+ */
+ @Generated
+ public String getXMsContentType() {
+ return this.xMsContentType;
+ }
+
+ /**
+ * Set the xMsContentType property: The x-ms-content-type property.
+ *
+ * @param xMsContentType the xMsContentType value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsContentType(String xMsContentType) {
+ this.xMsContentType = xMsContentType;
+ return this;
+ }
+
+ /**
+ * Get the xMsContentLength property: The x-ms-content-length property.
+ *
+ * @return the xMsContentLength value.
+ */
+ @Generated
+ public Long getXMsContentLength() {
+ return this.xMsContentLength;
+ }
+
+ /**
+ * Set the xMsContentLength property: The x-ms-content-length property.
+ *
+ * @param xMsContentLength the xMsContentLength value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsContentLength(Long xMsContentLength) {
+ this.xMsContentLength = xMsContentLength;
+ return this;
+ }
+
+ /**
+ * Get the xMsContentMd5 property: The x-ms-content-md5 property.
+ *
+ * @return the xMsContentMd5 value.
+ */
+ @Generated
+ public byte[] getXMsContentMd5() {
+ return CoreUtils.clone(this.xMsContentMd5);
+ }
+
+ /**
+ * Set the xMsContentMd5 property: The x-ms-content-md5 property.
+ *
+ * @param xMsContentMd5 the xMsContentMd5 value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsContentMd5(byte[] xMsContentMd5) {
+ this.xMsContentMd5 = CoreUtils.clone(xMsContentMd5);
+ return this;
+ }
+
+ /**
+ * Get the xMsContentEncoding property: The x-ms-content-encoding property.
+ *
+ * @return the xMsContentEncoding value.
+ */
+ @Generated
+ public String getXMsContentEncoding() {
+ return this.xMsContentEncoding;
+ }
+
+ /**
+ * Set the xMsContentEncoding property: The x-ms-content-encoding property.
+ *
+ * @param xMsContentEncoding the xMsContentEncoding value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsContentEncoding(String xMsContentEncoding) {
+ this.xMsContentEncoding = xMsContentEncoding;
+ return this;
+ }
+
+ /**
+ * Get the xMsContentLanguage property: The x-ms-content-language property.
+ *
+ * @return the xMsContentLanguage value.
+ */
+ @Generated
+ public String getXMsContentLanguage() {
+ return this.xMsContentLanguage;
+ }
+
+ /**
+ * Set the xMsContentLanguage property: The x-ms-content-language property.
+ *
+ * @param xMsContentLanguage the xMsContentLanguage value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsContentLanguage(String xMsContentLanguage) {
+ this.xMsContentLanguage = xMsContentLanguage;
+ return this;
+ }
+
+ /**
+ * Get the xMsCacheControl property: The x-ms-cache-control property.
+ *
+ * @return the xMsCacheControl value.
+ */
+ @Generated
+ public String getXMsCacheControl() {
+ return this.xMsCacheControl;
+ }
+
+ /**
+ * Set the xMsCacheControl property: The x-ms-cache-control property.
+ *
+ * @param xMsCacheControl the xMsCacheControl value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsCacheControl(String xMsCacheControl) {
+ this.xMsCacheControl = xMsCacheControl;
+ return this;
+ }
+
+ /**
+ * Get the xMsContentDisposition property: The x-ms-content-disposition property.
+ *
+ * @return the xMsContentDisposition value.
+ */
+ @Generated
+ public String getXMsContentDisposition() {
+ return this.xMsContentDisposition;
+ }
+
+ /**
+ * Set the xMsContentDisposition property: The x-ms-content-disposition property.
+ *
+ * @param xMsContentDisposition the xMsContentDisposition value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsContentDisposition(String xMsContentDisposition) {
+ this.xMsContentDisposition = xMsContentDisposition;
+ return this;
+ }
+
+ /**
+ * Get the xMsCopyCompletionTime property: The x-ms-copy-completion-time property.
+ *
+ * @return the xMsCopyCompletionTime value.
+ */
+ @Generated
+ public OffsetDateTime getXMsCopyCompletionTime() {
+ if (this.xMsCopyCompletionTime == null) {
+ return null;
+ }
+ return this.xMsCopyCompletionTime.getDateTime();
+ }
+
+ /**
+ * Set the xMsCopyCompletionTime property: The x-ms-copy-completion-time property.
+ *
+ * @param xMsCopyCompletionTime the xMsCopyCompletionTime value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsCopyCompletionTime(OffsetDateTime xMsCopyCompletionTime) {
+ if (xMsCopyCompletionTime == null) {
+ this.xMsCopyCompletionTime = null;
+ } else {
+ this.xMsCopyCompletionTime = new DateTimeRfc1123(xMsCopyCompletionTime);
+ }
+ return this;
+ }
+
+ /**
+ * Get the xMsCopyStatusDescription property: The x-ms-copy-status-description property.
+ *
+ * @return the xMsCopyStatusDescription value.
+ */
+ @Generated
+ public String getXMsCopyStatusDescription() {
+ return this.xMsCopyStatusDescription;
+ }
+
+ /**
+ * Set the xMsCopyStatusDescription property: The x-ms-copy-status-description property.
+ *
+ * @param xMsCopyStatusDescription the xMsCopyStatusDescription value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsCopyStatusDescription(String xMsCopyStatusDescription) {
+ this.xMsCopyStatusDescription = xMsCopyStatusDescription;
+ return this;
+ }
+
+ /**
+ * Get the xMsCopyId property: The x-ms-copy-id property.
+ *
+ * @return the xMsCopyId value.
+ */
+ @Generated
+ public String getXMsCopyId() {
+ return this.xMsCopyId;
+ }
+
+ /**
+ * Set the xMsCopyId property: The x-ms-copy-id property.
+ *
+ * @param xMsCopyId the xMsCopyId value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsCopyId(String xMsCopyId) {
+ this.xMsCopyId = xMsCopyId;
+ return this;
+ }
+
+ /**
+ * Get the xMsCopyProgress property: The x-ms-copy-progress property.
+ *
+ * @return the xMsCopyProgress value.
+ */
+ @Generated
+ public String getXMsCopyProgress() {
+ return this.xMsCopyProgress;
+ }
+
+ /**
+ * Set the xMsCopyProgress property: The x-ms-copy-progress property.
+ *
+ * @param xMsCopyProgress the xMsCopyProgress value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsCopyProgress(String xMsCopyProgress) {
+ this.xMsCopyProgress = xMsCopyProgress;
+ return this;
+ }
+
+ /**
+ * Get the xMsCopySource property: The x-ms-copy-source property.
+ *
+ * @return the xMsCopySource value.
+ */
+ @Generated
+ public String getXMsCopySource() {
+ return this.xMsCopySource;
+ }
+
+ /**
+ * Set the xMsCopySource property: The x-ms-copy-source property.
+ *
+ * @param xMsCopySource the xMsCopySource value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsCopySource(String xMsCopySource) {
+ this.xMsCopySource = xMsCopySource;
+ return this;
+ }
+
+ /**
+ * Get the xMsCopyStatus property: The x-ms-copy-status property.
+ *
+ * @return the xMsCopyStatus value.
+ */
+ @Generated
+ public CopyStatusType getXMsCopyStatus() {
+ return this.xMsCopyStatus;
+ }
+
+ /**
+ * Set the xMsCopyStatus property: The x-ms-copy-status property.
+ *
+ * @param xMsCopyStatus the xMsCopyStatus value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsCopyStatus(CopyStatusType xMsCopyStatus) {
+ this.xMsCopyStatus = xMsCopyStatus;
+ return this;
+ }
+
+ /**
+ * Get the xMsServerEncrypted property: The x-ms-server-encrypted property.
+ *
+ * @return the xMsServerEncrypted value.
+ */
+ @Generated
+ public Boolean isXMsServerEncrypted() {
+ return this.xMsServerEncrypted;
+ }
+
+ /**
+ * Set the xMsServerEncrypted property: The x-ms-server-encrypted property.
+ *
+ * @param xMsServerEncrypted the xMsServerEncrypted value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsServerEncrypted(Boolean xMsServerEncrypted) {
+ this.xMsServerEncrypted = xMsServerEncrypted;
+ return this;
+ }
+
+ /**
+ * Get the xMsFileAttributes property: The x-ms-file-attributes property.
+ *
+ * @return the xMsFileAttributes value.
+ */
+ @Generated
+ public String getXMsFileAttributes() {
+ return this.xMsFileAttributes;
+ }
+
+ /**
+ * Set the xMsFileAttributes property: The x-ms-file-attributes property.
+ *
+ * @param xMsFileAttributes the xMsFileAttributes value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFileAttributes(String xMsFileAttributes) {
+ this.xMsFileAttributes = xMsFileAttributes;
+ return this;
+ }
+
+ /**
+ * Get the xMsFileCreationTime property: The x-ms-file-creation-time property.
+ *
+ * @return the xMsFileCreationTime value.
+ */
+ @Generated
+ public OffsetDateTime getXMsFileCreationTime() {
+ return this.xMsFileCreationTime;
+ }
+
+ /**
+ * Set the xMsFileCreationTime property: The x-ms-file-creation-time property.
+ *
+ * @param xMsFileCreationTime the xMsFileCreationTime value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFileCreationTime(OffsetDateTime xMsFileCreationTime) {
+ this.xMsFileCreationTime = xMsFileCreationTime;
+ return this;
+ }
+
+ /**
+ * Get the xMsFileLastWriteTime property: The x-ms-file-last-write-time property.
+ *
+ * @return the xMsFileLastWriteTime value.
+ */
+ @Generated
+ public OffsetDateTime getXMsFileLastWriteTime() {
+ return this.xMsFileLastWriteTime;
+ }
+
+ /**
+ * Set the xMsFileLastWriteTime property: The x-ms-file-last-write-time property.
+ *
+ * @param xMsFileLastWriteTime the xMsFileLastWriteTime value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFileLastWriteTime(OffsetDateTime xMsFileLastWriteTime) {
+ this.xMsFileLastWriteTime = xMsFileLastWriteTime;
+ return this;
+ }
+
+ /**
+ * Get the xMsFileChangeTime property: The x-ms-file-change-time property.
+ *
+ * @return the xMsFileChangeTime value.
+ */
+ @Generated
+ public OffsetDateTime getXMsFileChangeTime() {
+ return this.xMsFileChangeTime;
+ }
+
+ /**
+ * Set the xMsFileChangeTime property: The x-ms-file-change-time property.
+ *
+ * @param xMsFileChangeTime the xMsFileChangeTime value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFileChangeTime(OffsetDateTime xMsFileChangeTime) {
+ this.xMsFileChangeTime = xMsFileChangeTime;
+ return this;
+ }
+
+ /**
+ * Get the xMsFilePermissionKey property: The x-ms-file-permission-key property.
+ *
+ * @return the xMsFilePermissionKey value.
+ */
+ @Generated
+ public String getXMsFilePermissionKey() {
+ return this.xMsFilePermissionKey;
+ }
+
+ /**
+ * Set the xMsFilePermissionKey property: The x-ms-file-permission-key property.
+ *
+ * @param xMsFilePermissionKey the xMsFilePermissionKey value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFilePermissionKey(String xMsFilePermissionKey) {
+ this.xMsFilePermissionKey = xMsFilePermissionKey;
+ return this;
+ }
+
+ /**
+ * Get the xMsFileId property: The x-ms-file-id property.
+ *
+ * @return the xMsFileId value.
+ */
+ @Generated
+ public String getXMsFileId() {
+ return this.xMsFileId;
+ }
+
+ /**
+ * Set the xMsFileId property: The x-ms-file-id property.
+ *
+ * @param xMsFileId the xMsFileId value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFileId(String xMsFileId) {
+ this.xMsFileId = xMsFileId;
+ return this;
+ }
+
+ /**
+ * Get the xMsFileName property: The x-ms-file-name property.
+ *
+ * @return the xMsFileName value.
+ */
+ @Generated
+ public String getXMsFileName() {
+ return this.xMsFileName;
+ }
+
+ /**
+ * Set the xMsFileName property: The x-ms-file-name property.
+ *
+ * @param xMsFileName the xMsFileName value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFileName(String xMsFileName) {
+ this.xMsFileName = xMsFileName;
+ return this;
+ }
+
+ /**
+ * Get the xMsFileParentId property: The x-ms-file-parent-id property.
+ *
+ * @return the xMsFileParentId value.
+ */
+ @Generated
+ public String getXMsFileParentId() {
+ return this.xMsFileParentId;
+ }
+
+ /**
+ * Set the xMsFileParentId property: The x-ms-file-parent-id property.
+ *
+ * @param xMsFileParentId the xMsFileParentId value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFileParentId(String xMsFileParentId) {
+ this.xMsFileParentId = xMsFileParentId;
+ return this;
+ }
+
+ /**
+ * Get the xMsLeaseDuration property: The x-ms-lease-duration property.
+ *
+ * @return the xMsLeaseDuration value.
+ */
+ @Generated
+ public LeaseDurationType getXMsLeaseDuration() {
+ return this.xMsLeaseDuration;
+ }
+
+ /**
+ * Set the xMsLeaseDuration property: The x-ms-lease-duration property.
+ *
+ * @param xMsLeaseDuration the xMsLeaseDuration value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsLeaseDuration(LeaseDurationType xMsLeaseDuration) {
+ this.xMsLeaseDuration = xMsLeaseDuration;
+ return this;
+ }
+
+ /**
+ * Get the xMsLeaseState property: The x-ms-lease-state property.
+ *
+ * @return the xMsLeaseState value.
+ */
+ @Generated
+ public LeaseStateType getXMsLeaseState() {
+ return this.xMsLeaseState;
+ }
+
+ /**
+ * Set the xMsLeaseState property: The x-ms-lease-state property.
+ *
+ * @param xMsLeaseState the xMsLeaseState value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsLeaseState(LeaseStateType xMsLeaseState) {
+ this.xMsLeaseState = xMsLeaseState;
+ return this;
+ }
+
+ /**
+ * Get the xMsLeaseStatus property: The x-ms-lease-status property.
+ *
+ * @return the xMsLeaseStatus value.
+ */
+ @Generated
+ public LeaseStatusType getXMsLeaseStatus() {
+ return this.xMsLeaseStatus;
+ }
+
+ /**
+ * Set the xMsLeaseStatus property: The x-ms-lease-status property.
+ *
+ * @param xMsLeaseStatus the xMsLeaseStatus value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsLeaseStatus(LeaseStatusType xMsLeaseStatus) {
+ this.xMsLeaseStatus = xMsLeaseStatus;
+ return this;
+ }
+
+ /**
+ * Get the xMsMode property: The x-ms-mode property.
+ *
+ * @return the xMsMode value.
+ */
+ @Generated
+ public String getXMsMode() {
+ return this.xMsMode;
+ }
+
+ /**
+ * Set the xMsMode property: The x-ms-mode property.
+ *
+ * @param xMsMode the xMsMode value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsMode(String xMsMode) {
+ this.xMsMode = xMsMode;
+ return this;
+ }
+
+ /**
+ * Get the xMsOwner property: The x-ms-owner property.
+ *
+ * @return the xMsOwner value.
+ */
+ @Generated
+ public String getXMsOwner() {
+ return this.xMsOwner;
+ }
+
+ /**
+ * Set the xMsOwner property: The x-ms-owner property.
+ *
+ * @param xMsOwner the xMsOwner value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsOwner(String xMsOwner) {
+ this.xMsOwner = xMsOwner;
+ return this;
+ }
+
+ /**
+ * Get the xMsGroup property: The x-ms-group property.
+ *
+ * @return the xMsGroup value.
+ */
+ @Generated
+ public String getXMsGroup() {
+ return this.xMsGroup;
+ }
+
+ /**
+ * Set the xMsGroup property: The x-ms-group property.
+ *
+ * @param xMsGroup the xMsGroup value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsGroup(String xMsGroup) {
+ this.xMsGroup = xMsGroup;
+ return this;
+ }
+
+ /**
+ * Get the xMsLinkCount property: The x-ms-link-count property.
+ *
+ * @return the xMsLinkCount value.
+ */
+ @Generated
+ public Integer getXMsLinkCount() {
+ return this.xMsLinkCount;
+ }
+
+ /**
+ * Set the xMsLinkCount property: The x-ms-link-count property.
+ *
+ * @param xMsLinkCount the xMsLinkCount value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsLinkCount(Integer xMsLinkCount) {
+ this.xMsLinkCount = xMsLinkCount;
+ return this;
+ }
+
+ /**
+ * Get the xMsFileFileType property: The x-ms-file-file-type property.
+ *
+ * @return the xMsFileFileType value.
+ */
+ @Generated
+ public NfsFileType getXMsFileFileType() {
+ return this.xMsFileFileType;
+ }
+
+ /**
+ * Set the xMsFileFileType property: The x-ms-file-file-type property.
+ *
+ * @param xMsFileFileType the xMsFileFileType value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsFileFileType(NfsFileType xMsFileFileType) {
+ this.xMsFileFileType = xMsFileFileType;
+ return this;
+ }
+
+ /**
+ * Get the xMsRequestId property: The x-ms-request-id property.
+ *
+ * @return the xMsRequestId value.
+ */
+ @Generated
+ public String getXMsRequestId() {
+ return this.xMsRequestId;
+ }
+
+ /**
+ * Set the xMsRequestId property: The x-ms-request-id property.
+ *
+ * @param xMsRequestId the xMsRequestId value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsRequestId(String xMsRequestId) {
+ this.xMsRequestId = xMsRequestId;
+ return this;
+ }
+
+ /**
+ * Get the xMsVersion property: The x-ms-version property.
+ *
+ * @return the xMsVersion value.
+ */
+ @Generated
+ public String getXMsVersion() {
+ return this.xMsVersion;
+ }
+
+ /**
+ * Set the xMsVersion property: The x-ms-version property.
+ *
+ * @param xMsVersion the xMsVersion value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsVersion(String xMsVersion) {
+ this.xMsVersion = xMsVersion;
+ return this;
+ }
+
+ /**
+ * Get the date property: The Date property.
+ *
+ * @return the date value.
+ */
+ @Generated
+ public OffsetDateTime getDate() {
+ if (this.date == null) {
+ return null;
+ }
+ return this.date.getDateTime();
+ }
+
+ /**
+ * Set the date property: The Date property.
+ *
+ * @param date the date value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setDate(OffsetDateTime date) {
+ if (date == null) {
+ this.date = null;
+ } else {
+ this.date = new DateTimeRfc1123(date);
+ }
+ return this;
+ }
+
+ /**
+ * Get the xMsClientRequestId property: The x-ms-client-request-id property.
+ *
+ * @return the xMsClientRequestId value.
+ */
+ @Generated
+ public String getXMsClientRequestId() {
+ return this.xMsClientRequestId;
+ }
+
+ /**
+ * Set the xMsClientRequestId property: The x-ms-client-request-id property.
+ *
+ * @param xMsClientRequestId the xMsClientRequestId value to set.
+ * @return the FilesGetHardLinksHeaders object itself.
+ */
+ @Generated
+ public FilesGetHardLinksHeaders setXMsClientRequestId(String xMsClientRequestId) {
+ this.xMsClientRequestId = xMsClientRequestId;
+ return this;
+ }
+}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/FilesGetPropertiesHeaders.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/FilesGetPropertiesHeaders.java
index 857221a951aa2..e0c298598356c 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/FilesGetPropertiesHeaders.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/FilesGetPropertiesHeaders.java
@@ -187,6 +187,12 @@ public final class FilesGetPropertiesHeaders {
@Generated
private String xMsFileId;
+ /*
+ * The x-ms-file-name property.
+ */
+ @Generated
+ private String xMsFileName;
+
/*
* The x-ms-file-parent-id property.
*/
@@ -275,6 +281,8 @@ public final class FilesGetPropertiesHeaders {
private static final HttpHeaderName X_MS_FILE_ID = HttpHeaderName.fromString("x-ms-file-id");
+ private static final HttpHeaderName X_MS_FILE_NAME = HttpHeaderName.fromString("x-ms-file-name");
+
private static final HttpHeaderName X_MS_FILE_PARENT_ID = HttpHeaderName.fromString("x-ms-file-parent-id");
private static final HttpHeaderName X_MS_LEASE_DURATION = HttpHeaderName.fromString("x-ms-lease-duration");
@@ -376,6 +384,7 @@ public FilesGetPropertiesHeaders(HttpHeaders rawHeaders) {
}
this.xMsFilePermissionKey = rawHeaders.getValue(X_MS_FILE_PERMISSION_KEY);
this.xMsFileId = rawHeaders.getValue(X_MS_FILE_ID);
+ this.xMsFileName = rawHeaders.getValue(X_MS_FILE_NAME);
this.xMsFileParentId = rawHeaders.getValue(X_MS_FILE_PARENT_ID);
String xMsLeaseDuration = rawHeaders.getValue(X_MS_LEASE_DURATION);
if (xMsLeaseDuration != null) {
@@ -1036,6 +1045,28 @@ public FilesGetPropertiesHeaders setXMsFileId(String xMsFileId) {
return this;
}
+ /**
+ * Get the xMsFileName property: The x-ms-file-name property.
+ *
+ * @return the xMsFileName value.
+ */
+ @Generated
+ public String getXMsFileName() {
+ return this.xMsFileName;
+ }
+
+ /**
+ * Set the xMsFileName property: The x-ms-file-name property.
+ *
+ * @param xMsFileName the xMsFileName value to set.
+ * @return the FilesGetPropertiesHeaders object itself.
+ */
+ @Generated
+ public FilesGetPropertiesHeaders setXMsFileName(String xMsFileName) {
+ this.xMsFileName = xMsFileName;
+ return this;
+ }
+
/**
* Get the xMsFileParentId property: The x-ms-file-parent-id property.
*
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/HardLink.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/HardLink.java
new file mode 100644
index 0000000000000..e73351509a837
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/HardLink.java
@@ -0,0 +1,144 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+// Code generated by Microsoft (R) AutoRest Code Generator.
+
+package com.azure.storage.file.share.implementation.models;
+
+import com.azure.core.annotation.Fluent;
+import com.azure.core.annotation.Generated;
+import com.azure.xml.XmlReader;
+import com.azure.xml.XmlSerializable;
+import com.azure.xml.XmlToken;
+import com.azure.xml.XmlWriter;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+
+/**
+ * A hard link to a file.
+ */
+@Fluent
+public final class HardLink implements XmlSerializable {
+ /*
+ * The name of the hard link.
+ */
+ @Generated
+ private StringEncoded fileName;
+
+ /*
+ * The fileId of the parent directory of the hard link.
+ */
+ @Generated
+ private String parentId;
+
+ /**
+ * Creates an instance of HardLink class.
+ */
+ @Generated
+ public HardLink() {
+ }
+
+ /**
+ * Get the fileName property: The name of the hard link.
+ *
+ * @return the fileName value.
+ */
+ @Generated
+ public StringEncoded getFileName() {
+ return this.fileName;
+ }
+
+ /**
+ * Set the fileName property: The name of the hard link.
+ *
+ * @param fileName the fileName value to set.
+ * @return the HardLink object itself.
+ */
+ @Generated
+ public HardLink setFileName(StringEncoded fileName) {
+ this.fileName = fileName;
+ return this;
+ }
+
+ /**
+ * Get the parentId property: The fileId of the parent directory of the hard link.
+ *
+ * @return the parentId value.
+ */
+ @Generated
+ public String getParentId() {
+ return this.parentId;
+ }
+
+ /**
+ * Set the parentId property: The fileId of the parent directory of the hard link.
+ *
+ * @param parentId the parentId value to set.
+ * @return the HardLink object itself.
+ */
+ @Generated
+ public HardLink setParentId(String parentId) {
+ this.parentId = parentId;
+ return this;
+ }
+
+ @Generated
+ @Override
+ public XmlWriter toXml(XmlWriter xmlWriter) throws XMLStreamException {
+ return toXml(xmlWriter, null);
+ }
+
+ @Generated
+ @Override
+ public XmlWriter toXml(XmlWriter xmlWriter, String rootElementName) throws XMLStreamException {
+ rootElementName = rootElementName == null || rootElementName.isEmpty() ? "HardLink" : rootElementName;
+ xmlWriter.writeStartElement(rootElementName);
+ xmlWriter.writeXml(this.fileName, "FileName");
+ xmlWriter.writeStringElement("ParentId", this.parentId);
+ return xmlWriter.writeEndElement();
+ }
+
+ /**
+ * Reads an instance of HardLink from the XmlReader.
+ *
+ * @param xmlReader The XmlReader being read.
+ * @return An instance of HardLink if the XmlReader was pointing to an instance of it, or null if it was pointing to
+ * XML null.
+ * @throws XMLStreamException If an error occurs while reading the HardLink.
+ */
+ @Generated
+ public static HardLink fromXml(XmlReader xmlReader) throws XMLStreamException {
+ return fromXml(xmlReader, null);
+ }
+
+ /**
+ * Reads an instance of HardLink from the XmlReader.
+ *
+ * @param xmlReader The XmlReader being read.
+ * @param rootElementName Optional root element name to override the default defined by the model. Used to support
+ * cases where the model can deserialize from different root element names.
+ * @return An instance of HardLink if the XmlReader was pointing to an instance of it, or null if it was pointing to
+ * XML null.
+ * @throws XMLStreamException If an error occurs while reading the HardLink.
+ */
+ @Generated
+ public static HardLink fromXml(XmlReader xmlReader, String rootElementName) throws XMLStreamException {
+ String finalRootElementName
+ = rootElementName == null || rootElementName.isEmpty() ? "HardLink" : rootElementName;
+ return xmlReader.readObject(finalRootElementName, reader -> {
+ HardLink deserializedHardLink = new HardLink();
+ while (reader.nextElement() != XmlToken.END_ELEMENT) {
+ QName elementName = reader.getElementName();
+
+ if ("FileName".equals(elementName.getLocalPart())) {
+ deserializedHardLink.fileName = StringEncoded.fromXml(reader, "FileName");
+ } else if ("ParentId".equals(elementName.getLocalPart())) {
+ deserializedHardLink.parentId = reader.getStringElement();
+ } else {
+ reader.skipElement();
+ }
+ }
+
+ return deserializedHardLink;
+ });
+ }
+}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/HardLinkList.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/HardLinkList.java
new file mode 100644
index 0000000000000..4dd75df71bb02
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/models/HardLinkList.java
@@ -0,0 +1,119 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+// Code generated by Microsoft (R) AutoRest Code Generator.
+
+package com.azure.storage.file.share.implementation.models;
+
+import com.azure.core.annotation.Fluent;
+import com.azure.core.annotation.Generated;
+import com.azure.xml.XmlReader;
+import com.azure.xml.XmlSerializable;
+import com.azure.xml.XmlToken;
+import com.azure.xml.XmlWriter;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+
+/**
+ * The list of hard links for a file.
+ */
+@Fluent
+public final class HardLinkList implements XmlSerializable {
+ /*
+ * The hard links.
+ */
+ @Generated
+ private List hardLinks = new ArrayList<>();
+
+ /**
+ * Creates an instance of HardLinkList class.
+ */
+ @Generated
+ public HardLinkList() {
+ }
+
+ /**
+ * Get the hardLinks property: The hard links.
+ *
+ * @return the hardLinks value.
+ */
+ @Generated
+ public List getHardLinks() {
+ return this.hardLinks;
+ }
+
+ /**
+ * Set the hardLinks property: The hard links.
+ *
+ * @param hardLinks the hardLinks value to set.
+ * @return the HardLinkList object itself.
+ */
+ @Generated
+ public HardLinkList setHardLinks(List hardLinks) {
+ this.hardLinks = hardLinks;
+ return this;
+ }
+
+ @Generated
+ @Override
+ public XmlWriter toXml(XmlWriter xmlWriter) throws XMLStreamException {
+ return toXml(xmlWriter, null);
+ }
+
+ @Generated
+ @Override
+ public XmlWriter toXml(XmlWriter xmlWriter, String rootElementName) throws XMLStreamException {
+ rootElementName = rootElementName == null || rootElementName.isEmpty() ? "HardLinks" : rootElementName;
+ xmlWriter.writeStartElement(rootElementName);
+ if (this.hardLinks != null) {
+ for (HardLink element : this.hardLinks) {
+ xmlWriter.writeXml(element, "HardLink");
+ }
+ }
+ return xmlWriter.writeEndElement();
+ }
+
+ /**
+ * Reads an instance of HardLinkList from the XmlReader.
+ *
+ * @param xmlReader The XmlReader being read.
+ * @return An instance of HardLinkList if the XmlReader was pointing to an instance of it, or null if it was
+ * pointing to XML null.
+ * @throws XMLStreamException If an error occurs while reading the HardLinkList.
+ */
+ @Generated
+ public static HardLinkList fromXml(XmlReader xmlReader) throws XMLStreamException {
+ return fromXml(xmlReader, null);
+ }
+
+ /**
+ * Reads an instance of HardLinkList from the XmlReader.
+ *
+ * @param xmlReader The XmlReader being read.
+ * @param rootElementName Optional root element name to override the default defined by the model. Used to support
+ * cases where the model can deserialize from different root element names.
+ * @return An instance of HardLinkList if the XmlReader was pointing to an instance of it, or null if it was
+ * pointing to XML null.
+ * @throws XMLStreamException If an error occurs while reading the HardLinkList.
+ */
+ @Generated
+ public static HardLinkList fromXml(XmlReader xmlReader, String rootElementName) throws XMLStreamException {
+ String finalRootElementName
+ = rootElementName == null || rootElementName.isEmpty() ? "HardLinks" : rootElementName;
+ return xmlReader.readObject(finalRootElementName, reader -> {
+ HardLinkList deserializedHardLinkList = new HardLinkList();
+ while (reader.nextElement() != XmlToken.END_ELEMENT) {
+ QName elementName = reader.getElementName();
+
+ if ("HardLink".equals(elementName.getLocalPart())) {
+ deserializedHardLinkList.hardLinks.add(HardLink.fromXml(reader, "HardLink"));
+ } else {
+ reader.skipElement();
+ }
+ }
+
+ return deserializedHardLinkList;
+ });
+ }
+}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/util/ModelHelper.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/util/ModelHelper.java
index c3ba69c26fe5d..ccfc938689d33 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/util/ModelHelper.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/util/ModelHelper.java
@@ -35,8 +35,11 @@
import com.azure.storage.file.share.implementation.models.FilesCreateHeaders;
import com.azure.storage.file.share.implementation.models.FilesCreateSymbolicLinkHeaders;
import com.azure.storage.file.share.implementation.models.FilesDownloadHeaders;
+import com.azure.storage.file.share.implementation.models.FilesGetHardLinksHeaders;
import com.azure.storage.file.share.implementation.models.FilesGetPropertiesHeaders;
import com.azure.storage.file.share.implementation.models.FilesGetSymbolicLinkHeaders;
+import com.azure.storage.file.share.implementation.models.HardLink;
+import com.azure.storage.file.share.implementation.models.HardLinkList;
import com.azure.storage.file.share.implementation.models.FilesSetHttpHeadersHeaders;
import com.azure.storage.file.share.implementation.models.FilesSetMetadataHeaders;
import com.azure.storage.file.share.implementation.models.FilesUploadRangeFromURLHeaders;
@@ -69,6 +72,8 @@
import com.azure.storage.file.share.models.ShareFileInfo;
import com.azure.storage.file.share.models.ShareFileItem;
import com.azure.storage.file.share.models.ShareFileItemProperties;
+import com.azure.storage.file.share.models.ShareFileLink;
+import com.azure.storage.file.share.models.ShareFileLinks;
import com.azure.storage.file.share.models.ShareFileMetadataInfo;
import com.azure.storage.file.share.models.ShareFileProperties;
import com.azure.storage.file.share.models.ShareFileRange;
@@ -421,9 +426,10 @@ public static Response createFileInfoResponse(ResponseBase(response, shareFileProperties);
}
@@ -584,16 +590,16 @@ public static Response mapGetStatisticsResponse(Response(response, shareDirectoryInfo);
}
- public static Response
- mapShareDirectoryPropertiesResponse(ResponseBase response) {
- Map metadata = response.getDeserializedHeaders().getXMsMeta();
- String eTag = response.getDeserializedHeaders().getETag();
- OffsetDateTime offsetDateTime = response.getDeserializedHeaders().getLastModified();
- boolean isServerEncrypted = response.getDeserializedHeaders().isXMsServerEncrypted();
+ public static Response mapShareDirectoryPropertiesResponse(Response response) {
+ DirectoriesGetPropertiesHeaders headers = new DirectoriesGetPropertiesHeaders(response.getHeaders());
+ Map metadata = headers.getXMsMeta();
+ String eTag = headers.getETag();
+ OffsetDateTime offsetDateTime = headers.getLastModified();
+ boolean isServerEncrypted = headers.isXMsServerEncrypted();
FileSmbProperties smbProperties = FileSmbPropertiesHelper.create(response.getHeaders());
FilePosixProperties posixProperties = FilePosixPropertiesHelper.create(response.getHeaders());
ShareDirectoryProperties shareDirectoryProperties = ShareDirectoryPropertiesHelper.create(metadata, eTag,
- offsetDateTime, isServerEncrypted, smbProperties, posixProperties);
+ offsetDateTime, isServerEncrypted, smbProperties, posixProperties, headers.getXMsFileName());
return new SimpleResponse<>(response, shareDirectoryProperties);
}
@@ -765,4 +771,26 @@ public static List toShareFileRangeItems(ShareFileRangeList
}
return ranges;
}
+
+ public static Response
+ getFileLinksResponse(ResponseBase response) {
+ FilesGetHardLinksHeaders headers = response.getDeserializedHeaders();
+ FileSmbProperties smbProperties = FileSmbPropertiesHelper.create(response.getHeaders());
+ FilePosixProperties posixProperties = FilePosixPropertiesHelper.create(response.getHeaders());
+ ShareFileProperties properties = ShareFilePropertiesHelper.create(headers.getETag(), headers.getLastModified(),
+ headers.getXMsMeta(), headers.getXMsType(), headers.getXMsContentLength(), headers.getXMsContentType(),
+ headers.getXMsContentLanguage(), headers.getXMsContentMd5(), headers.getXMsContentEncoding(),
+ headers.getXMsCacheControl(), headers.getXMsContentDisposition(), headers.getXMsLeaseStatus(),
+ headers.getXMsLeaseState(), headers.getXMsLeaseDuration(), headers.getXMsCopyCompletionTime(),
+ headers.getXMsCopyStatusDescription(), headers.getXMsCopyId(), headers.getXMsCopyProgress(),
+ headers.getXMsCopySource(), headers.getXMsCopyStatus(), headers.isXMsServerEncrypted(), smbProperties,
+ posixProperties, headers.getXMsFileName());
+ List links = new ArrayList<>();
+ for (HardLink hardLink : response.getValue().getHardLinks()) {
+ StringEncoded encodedFileName = hardLink.getFileName();
+ links.add(new ShareFileLink(hardLink.getParentId(),
+ encodedFileName == null ? null : decodeName(encodedFileName)));
+ }
+ return new SimpleResponse<>(response, new ShareFileLinks(properties, links));
+ }
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareDirectoryProperties.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareDirectoryProperties.java
index b70915b269370..bbae2cb5e3169 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareDirectoryProperties.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareDirectoryProperties.java
@@ -21,6 +21,7 @@ public final class ShareDirectoryProperties {
private final boolean isServerEncrypted;
private final FileSmbProperties smbProperties;
private final FilePosixProperties posixProperties;
+ private final String fileName;
/**
* Creates an instance of properties information about a specific Directory.
@@ -40,17 +41,20 @@ public ShareDirectoryProperties(Map metadata, String eTag, Offse
this.isServerEncrypted = isServerEncrypted;
this.smbProperties = smbProperties;
this.posixProperties = null;
+ this.fileName = null;
}
//Internal constructor to support FilePosixProperties class.
private ShareDirectoryProperties(Map metadata, String eTag, OffsetDateTime lastModified,
- boolean isServerEncrypted, FileSmbProperties smbProperties, FilePosixProperties posixProperties) {
+ boolean isServerEncrypted, FileSmbProperties smbProperties, FilePosixProperties posixProperties,
+ String fileName) {
this.metadata = metadata;
this.eTag = eTag;
this.lastModified = lastModified;
this.isServerEncrypted = isServerEncrypted;
this.smbProperties = smbProperties;
this.posixProperties = posixProperties;
+ this.fileName = fileName;
}
static {
@@ -113,4 +117,13 @@ public FileSmbProperties getSmbProperties() {
public FilePosixProperties getPosixProperties() {
return posixProperties;
}
+
+ /**
+ * Gets the directory name returned by the service, or {@code null} when it was not returned.
+ *
+ * @return The directory name.
+ */
+ public String getFileName() {
+ return fileName;
+ }
}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileLink.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileLink.java
new file mode 100644
index 0000000000000..ade041f892a12
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileLink.java
@@ -0,0 +1,44 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.storage.file.share.models;
+
+import com.azure.core.annotation.Immutable;
+
+/**
+ * Describes one path that links to a file.
+ */
+@Immutable
+public final class ShareFileLink {
+ private final String parentId;
+ private final String name;
+
+ /**
+ * Creates a file link.
+ *
+ * @param parentId The file ID of the parent directory.
+ * @param name The name of the file link.
+ */
+ public ShareFileLink(String parentId, String name) {
+ this.parentId = parentId;
+ this.name = name;
+ }
+
+ /**
+ * Gets the file ID of the parent directory.
+ *
+ * @return The parent directory ID.
+ */
+ public String getParentId() {
+ return parentId;
+ }
+
+ /**
+ * Gets the name of the file link.
+ *
+ * @return The file link name.
+ */
+ public String getName() {
+ return name;
+ }
+}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileLinks.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileLinks.java
new file mode 100644
index 0000000000000..6810198e76076
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileLinks.java
@@ -0,0 +1,50 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.storage.file.share.models;
+
+import com.azure.core.annotation.Immutable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Contains a file's properties and the paths that link to the file.
+ */
+@Immutable
+public final class ShareFileLinks {
+ private final ShareFileProperties properties;
+ private final List links;
+
+ /**
+ * Creates a file links result.
+ *
+ * @param properties The file's properties.
+ * @param links The paths that link to the file.
+ */
+ public ShareFileLinks(ShareFileProperties properties, List links) {
+ this.properties = Objects.requireNonNull(properties, "'properties' cannot be null.");
+ this.links
+ = Collections.unmodifiableList(new ArrayList<>(Objects.requireNonNull(links, "'links' cannot be null.")));
+ }
+
+ /**
+ * Gets the file's properties.
+ *
+ * @return The file's properties.
+ */
+ public ShareFileProperties getProperties() {
+ return properties;
+ }
+
+ /**
+ * Gets the paths that link to the file.
+ *
+ * @return The file links.
+ */
+ public List getLinks() {
+ return links;
+ }
+}
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileProperties.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileProperties.java
index 740d480e88b36..321d815a429be 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileProperties.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/models/ShareFileProperties.java
@@ -22,6 +22,7 @@ public final class ShareFileProperties {
private final String fileType;
private final Long contentLength;
private final String contentType;
+ private final String contentLanguage;
private final byte[] contentMd5;
private final String contentEncoding;
private final String cacheControl;
@@ -38,6 +39,7 @@ public final class ShareFileProperties {
private final Boolean isServerEncrypted;
private final FileSmbProperties smbProperties;
private final FilePosixProperties posixProperties;
+ private final String fileName;
/**
* Creates an instance of property information about a specific File.
@@ -138,6 +140,7 @@ public ShareFileProperties(String eTag, OffsetDateTime lastModified, Map metadata, String fileType,
- Long contentLength, String contentType, byte[] contentMd5, String contentEncoding, String cacheControl,
- String contentDisposition, LeaseStatusType leaseStatusType, LeaseStateType leaseStateType,
+ Long contentLength, String contentType, String contentLanguage, byte[] contentMd5, String contentEncoding,
+ String cacheControl, String contentDisposition, LeaseStatusType leaseStatusType, LeaseStateType leaseStateType,
LeaseDurationType leaseDurationType, OffsetDateTime copyCompletionTime, String copyStatusDescription,
String copyId, String copyProgress, String copySource, CopyStatusType copyStatus, Boolean isServerEncrypted,
- FileSmbProperties smbProperties, FilePosixProperties posixProperties) {
+ FileSmbProperties smbProperties, FilePosixProperties posixProperties, String fileName) {
this.eTag = eTag;
this.lastModified = lastModified;
this.metadata = metadata;
this.fileType = fileType;
this.contentLength = contentLength;
this.contentType = contentType;
+ this.contentLanguage = contentLanguage;
this.contentMd5 = CoreUtils.clone(contentMd5);
this.contentEncoding = contentEncoding;
this.cacheControl = cacheControl;
@@ -185,6 +190,7 @@ private ShareFileProperties(String eTag, OffsetDateTime lastModified, MapFile-ID-addressed clients are not supported for lease operations. A client created via
+ * {@link ShareFileClient#getFileId()} or {@link ShareFileClientBuilder#fileId(String)} must be rejected before any
+ * request is sent.
+ *
* @param fileClient ShareFileClient used to configure the builder.
* @return the updated ShareLeaseClientBuilder object
* @throws NullPointerException If {@code fileClient} is {@code null}.
+ * @throws IllegalStateException If {@code fileClient} is file-ID-addressed.
*/
public ShareLeaseClientBuilder fileClient(ShareFileClient fileClient) {
Objects.requireNonNull(fileClient);
+ ShareErrors.validatePathOperation(fileClient.getFileId(), "fileClient");
this.pipeline = fileClient.getHttpPipeline();
this.url = fileClient.getAccountUrl();
this.shareName = fileClient.getShareName();
@@ -136,12 +144,18 @@ public ShareLeaseClientBuilder fileClient(ShareFileClient fileClient) {
* Configures the builder based on the passed {@link ShareFileAsyncClient}. This will set the {@link HttpPipeline}
* and {@link URL} that are used to interact with the service.
*
+ * File-ID-addressed clients are not supported for lease operations. A client created via
+ * {@link ShareFileAsyncClient#getFileId()} or {@link ShareFileClientBuilder#fileId(String)} must be rejected before
+ * any request is sent.
+ *
* @param fileAsyncClient ShareFileAsyncClient used to configure the builder.
* @return the updated ShareLeaseClientBuilder object
* @throws NullPointerException If {@code fileAsyncClient} is {@code null}.
+ * @throws IllegalStateException If {@code fileAsyncClient} is file-ID-addressed.
*/
public ShareLeaseClientBuilder fileAsyncClient(ShareFileAsyncClient fileAsyncClient) {
Objects.requireNonNull(fileAsyncClient);
+ ShareErrors.validatePathOperation(fileAsyncClient.getFileId(), "fileAsyncClient");
this.pipeline = fileAsyncClient.getHttpPipeline();
this.url = fileAsyncClient.getAccountUrl();
this.shareName = fileAsyncClient.getShareName();
diff --git a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/BuilderHelperTests.java b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/BuilderHelperTests.java
index 607cd78fd05d3..3625365082c10 100644
--- a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/BuilderHelperTests.java
+++ b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/BuilderHelperTests.java
@@ -9,6 +9,7 @@
import com.azure.core.http.HttpHeaders;
import com.azure.core.http.HttpMethod;
import com.azure.core.http.HttpPipeline;
+import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.http.HttpRequest;
import com.azure.core.http.HttpResponse;
import com.azure.core.http.policy.FixedDelayOptions;
@@ -44,6 +45,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class BuilderHelperTests {
private static final ClientLogger LOGGER = new ClientLogger(BuilderHelperTests.class);
@@ -56,6 +58,126 @@ public class BuilderHelperTests {
private static final RetryOptions CORE_RETRY_OPTIONS
= new RetryOptions(new FixedDelayOptions(1, Duration.ofSeconds(2)));
+ @ParameterizedTest
+ @MethodSource("fileIdUrls")
+ void syncFileIdUrls(String fileId, String snapshot, String expectedUrl) {
+ ShareClient shareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME)
+ .getSnapshotClient(snapshot);
+ ShareFileClient fileClient = shareClient.getFileClientByFileId(fileId);
+ ShareDirectoryClient directoryClient = shareClient.getDirectoryClientByFileId(fileId);
+
+ assertEquals(fileId, fileClient.getFileId());
+ assertEquals(expectedUrl, fileClient.getFileUrl());
+ assertEquals(fileId, directoryClient.getFileId());
+ assertEquals(expectedUrl, directoryClient.getDirectoryUrl());
+
+ ShareFileClient rebuiltClient
+ = new ShareFileClientBuilder().endpoint(fileClient.getFileUrl()).buildFileClient();
+ assertEquals(fileId, rebuiltClient.getFileId());
+ assertEquals(expectedUrl, rebuiltClient.getFileUrl());
+ }
+
+ @ParameterizedTest
+ @MethodSource("fileIdUrls")
+ void asyncFileIdUrls(String fileId, String snapshot, String expectedUrl) {
+ ShareAsyncClient shareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .buildAsyncClient()
+ .getShareAsyncClient(FileIdTestHelper.SHARE_NAME)
+ .getSnapshotClient(snapshot);
+ ShareFileAsyncClient fileClient = shareClient.getFileClientByFileId(fileId);
+ ShareDirectoryAsyncClient directoryClient = shareClient.getDirectoryClientByFileId(fileId);
+
+ assertEquals(fileId, fileClient.getFileId());
+ assertEquals(expectedUrl, fileClient.getFileUrl());
+ assertEquals(fileId, directoryClient.getFileId());
+ assertEquals(expectedUrl, directoryClient.getDirectoryUrl());
+
+ ShareFileAsyncClient rebuiltClient
+ = new ShareFileClientBuilder().endpoint(fileClient.getFileUrl()).buildFileAsyncClient();
+ assertEquals(fileId, rebuiltClient.getFileId());
+ assertEquals(expectedUrl, rebuiltClient.getFileUrl());
+ }
+
+ @ParameterizedTest
+ @MethodSource("fileIdEndpointSetters")
+ void syncFileIdEndpointSetters(boolean connectionString, String endpointSuffix, String expectedFileId,
+ String expectedPath) {
+ ShareFileClient fileClient
+ = fileIdEndpointBuilder(connectionString, endpointSuffix, expectedFileId, expectedPath).buildFileClient();
+
+ assertEquals(expectedFileId, fileClient.getFileId());
+ assertEquals(expectedPath, fileClient.getFilePath());
+ fileClient.getProperties();
+ if (!expectedFileId.isEmpty()) {
+ assertThrows(IllegalStateException.class, fileClient::exists);
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("fileIdEndpointSetters")
+ void asyncFileIdEndpointSetters(boolean connectionString, String endpointSuffix, String expectedFileId,
+ String expectedPath) {
+ ShareFileAsyncClient fileClient
+ = fileIdEndpointBuilder(connectionString, endpointSuffix, expectedFileId, expectedPath)
+ .buildFileAsyncClient();
+
+ assertEquals(expectedFileId, fileClient.getFileId());
+ assertEquals(expectedPath, fileClient.getFilePath());
+ StepVerifier.create(fileClient.getProperties()).expectNextCount(1).verifyComplete();
+ if (!expectedFileId.isEmpty()) {
+ StepVerifier.create(fileClient.exists()).verifyError(IllegalStateException.class);
+ }
+ }
+
+ private static ShareFileClientBuilder fileIdEndpointBuilder(boolean connectionString, String endpointSuffix,
+ String expectedFileId, String expectedPath) {
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ assertEquals(HttpMethod.HEAD, request.getHttpMethod());
+ assertEquals(
+ "/" + FileIdTestHelper.SHARE_NAME
+ + (expectedFileId.isEmpty() ? "/" + expectedPath.replace("/", "%2F") : ""),
+ request.getUrl().getPath());
+ if (expectedFileId.isEmpty()) {
+ assertNull(request.getUrl().getQuery());
+ } else {
+ assertTrue(request.getUrl().getQuery().contains("fileid=" + expectedFileId));
+ }
+ return Mono.just(new MockHttpResponse(request, 200, FileIdTestHelper.fileHeaders("file.txt")));
+ }).build();
+ ShareFileClientBuilder builder = new ShareFileClientBuilder().fileId(FileIdTestHelper.FILE_ID);
+ String endpoint = FileIdTestHelper.ENDPOINT + endpointSuffix;
+ if (connectionString) {
+ builder.connectionString("FileEndpoint=" + endpoint + ";SharedAccessSignature=sv=2027-03-07&sig=test");
+ } else {
+ builder.endpoint(endpoint);
+ }
+ return builder.shareName(FileIdTestHelper.SHARE_NAME).pipeline(pipeline);
+ }
+
+ private static Stream fileIdEndpointSetters() {
+ return Stream.of(false, true)
+ .flatMap(connectionString -> Stream.of(Arguments.of(connectionString, "", FileIdTestHelper.FILE_ID, ""),
+ Arguments.of(connectionString, "/", FileIdTestHelper.FILE_ID, ""),
+ Arguments.of(connectionString, "/share", "", ""), Arguments.of(connectionString, "/share/", "", ""),
+ Arguments.of(connectionString, "/share/directory/file.txt", "", "directory/file.txt"),
+ Arguments.of(connectionString, "?fileid=replacement-id", "replacement-id", ""), Arguments
+ .of(connectionString, "/share/directory/file.txt?fileid=replacement-id", "replacement-id", "")));
+ }
+
+ // These are not realistic file IDs, but are here for defensive testing
+ private static Stream fileIdUrls() {
+ return Stream
+ .of(new String[] { FileIdTestHelper.FILE_ID, FileIdTestHelper.FILE_ID }, new String[] { "a&b", "a%26b" },
+ new String[] { "a%26b", "a%2526b" }, new String[] { "a +/=?#%", "a%20%2B%2F%3D%3F%23%25" },
+ new String[] { "caf\u00e9", "caf%C3%A9" })
+ .flatMap(pair -> Stream.of(null, "2026-09-29T12:34:56.1234567Z")
+ .map(snapshot -> Arguments.of(pair[0], snapshot,
+ FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME
+ + (snapshot == null ? "?" : "?sharesnapshot=" + snapshot + "&") + "fileid=" + pair[1])));
+ }
+
private static HttpRequest request(String url) {
return new HttpRequest(HttpMethod.HEAD, url)
.setHeaders(new HttpHeaders().set(HttpHeaderName.CONTENT_LENGTH, "0"))
diff --git a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/DirectoryApiTests.java b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/DirectoryApiTests.java
index 6f3ff54d53ee1..b268fd71bae4a 100644
--- a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/DirectoryApiTests.java
+++ b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/DirectoryApiTests.java
@@ -5,8 +5,14 @@
import com.azure.core.http.HttpHeader;
import com.azure.core.http.HttpHeaderName;
+import com.azure.core.http.HttpHeaders;
+import com.azure.core.http.HttpMethod;
+import com.azure.core.http.HttpPipeline;
+import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.http.rest.PagedResponse;
import com.azure.core.http.rest.Response;
+import com.azure.core.test.annotation.DoNotRecord;
+import com.azure.core.test.http.MockHttpResponse;
import com.azure.core.util.Context;
import com.azure.core.util.HttpClientOptions;
import com.azure.storage.blob.BlobServiceVersion;
@@ -40,12 +46,16 @@
import com.azure.storage.file.share.options.ShareListFilesAndDirectoriesOptions;
import com.azure.storage.file.share.sas.ShareFileSasPermission;
import com.azure.storage.file.share.sas.ShareServiceSasSignatureValues;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
import org.junit.jupiter.params.provider.ValueSource;
import java.io.File;
@@ -61,6 +71,7 @@
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import reactor.core.publisher.Mono;
import static com.azure.storage.common.implementation.Constants.HeaderConstants.ERROR_CODE_HEADER_NAME;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
@@ -84,7 +95,11 @@ public class DirectoryApiTests extends FileShareTestBase {
= "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-188441444-3053964)S:NO_ACCESS_CONTROL";
@BeforeEach
- public void setup() {
+ public void setup(TestInfo testInfo) {
+ if (testInfo.getTags().contains("file-id-mock")) {
+ return;
+ }
+
shareName = generateShareName();
directoryPath = generatePathName();
shareClient = shareBuilderHelper(shareName).buildClient();
@@ -105,6 +120,183 @@ public void getDirectoryUrl() {
assertEquals(expectURL, directoryURL);
}
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @ParameterizedTest
+ @ValueSource(booleans = { false, true })
+ public void directoryPropertiesByFileId(boolean snapshot) {
+ primaryDirectoryClient.createWithResponse(new ShareDirectoryCreateOptions().setMetadata(testMetadata), null,
+ null);
+ ShareDirectoryProperties expected = primaryDirectoryClient.getProperties();
+ String fileId = expected.getSmbProperties().getFileId();
+ assertNotNull(fileId);
+ ShareClient source = shareClient;
+ if (snapshot) {
+ source = shareClient.getSnapshotClient(shareClient.createSnapshot().getSnapshot());
+ primaryDirectoryClient.setMetadata(Collections.singletonMap("changed", "after-snapshot"));
+ }
+
+ ShareDirectoryClient directoryClient = source.getDirectoryClientByFileId(fileId);
+ Response response = directoryClient.getPropertiesWithResponse(null, Context.NONE);
+ ShareDirectoryProperties actual = response.getValue();
+ assertEquals(200, response.getStatusCode());
+ assertEquals(fileId, directoryClient.getFileId());
+ assertEquals(directoryPath, actual.getFileName());
+ assertEquals(expected.getMetadata(), actual.getMetadata());
+ assertEquals(expected.getETag(), actual.getETag());
+ assertEquals(expected.getLastModified(), actual.getLastModified());
+ assertEquals(expected.isServerEncrypted(), actual.isServerEncrypted());
+ assertEquals(fileId, actual.getSmbProperties().getFileId());
+ assertEquals(expected.getSmbProperties().getParentId(), actual.getSmbProperties().getParentId());
+ assertEquals(expected.getSmbProperties().getFileCreationTime(),
+ actual.getSmbProperties().getFileCreationTime());
+ assertEquals(expected.getSmbProperties().getFileLastWriteTime(),
+ actual.getSmbProperties().getFileLastWriteTime());
+ }
+
+ @LiveOnly
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void directoryPropertiesByFileIdLive() {
+ primaryDirectoryClient.create();
+ ShareDirectoryProperties expected = primaryDirectoryClient.getProperties();
+ String fileId = expected.getSmbProperties().getFileId();
+
+ ShareDirectoryProperties actual = shareClient.getDirectoryClientByFileId(fileId).getProperties();
+
+ assertEquals(directoryPath, actual.getFileName());
+ assertEquals(fileId, actual.getSmbProperties().getFileId());
+ assertEquals(expected.getSmbProperties().getParentId(), actual.getSmbProperties().getParentId());
+ }
+
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void directoryPropertiesByFileIdMapServiceErrors() {
+ ShareStorageException exception = assertThrows(ShareStorageException.class,
+ () -> shareClient.getDirectoryClientByFileId("invalid-file-id").getProperties());
+ assertEquals(400, exception.getStatusCode());
+ assertEquals(ShareErrorCode.INVALID_QUERY_PARAMETER_VALUE, exception.getErrorCode());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @ParameterizedTest
+ @ValueSource(booleans = { false, true })
+ public void directoryClientByFileIdUrl(boolean snapshot) {
+ ShareClient source = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME);
+ if (snapshot) {
+ source = source.getSnapshotClient("snapshot");
+ }
+ ShareDirectoryClient directoryClient = source.getDirectoryClientByFileId(FileIdTestHelper.FILE_ID);
+ assertEquals(FileIdTestHelper.FILE_ID, directoryClient.getFileId());
+ assertEquals("", directoryClient.getDirectoryPath());
+ assertEquals(ShareServiceVersion.V2027_03_07, directoryClient.getServiceVersion());
+ assertEquals(
+ FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME
+ + (snapshot ? "?sharesnapshot=snapshot&" : "?") + "fileid=" + FileIdTestHelper.FILE_ID,
+ directoryClient.getDirectoryUrl());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void rootDirectoryAllowsMetadataUpdates() {
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ assertEquals(HttpMethod.PUT, request.getHttpMethod());
+ assertEquals("/" + FileIdTestHelper.SHARE_NAME + "/", request.getUrl().getPath());
+ assertFalse(request.getUrl().getQuery().contains("fileid="));
+ return Mono.just(new MockHttpResponse(request, 200, FileIdTestHelper.fileHeaders("directory")
+ .set(HttpHeaderName.fromString("x-ms-request-server-encrypted"), "true")));
+ }).build();
+ ShareDirectoryClient directoryClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME)
+ .getRootDirectoryClient();
+
+ directoryClient.setMetadata(Collections.singletonMap("key", "value"));
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @ParameterizedTest
+ @NullAndEmptySource
+ @ValueSource(strings = { " ", "\t", "\n" })
+ public void directoryClientByFileIdRejectsBlankIds(String fileId) {
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ throw new AssertionError("Invalid file IDs must be rejected before sending a request.");
+ }).build();
+ ShareClient source = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME);
+ assertThrows(IllegalArgumentException.class, () -> source.getDirectoryClientByFileId(fileId));
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void directoryPropertiesWithoutFileName() {
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ HttpHeaders headers = FileIdTestHelper.fileHeaders("directory");
+ headers.remove(HttpHeaderName.fromString("x-ms-file-name"));
+ return Mono.just(new MockHttpResponse(request, 200, headers));
+ }).build();
+ ShareDirectoryClient directoryClient = new ShareFileClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .shareName(FileIdTestHelper.SHARE_NAME)
+ .resourcePath("directory")
+ .pipeline(pipeline)
+ .buildDirectoryClient();
+ assertEquals("", directoryClient.getFileId());
+ ShareDirectoryProperties properties = directoryClient.getProperties();
+ assertNull(properties.getFileName());
+ FileIdTestHelper.assertSmbProperties(properties.getSmbProperties());
+ assertNull(new ShareDirectoryProperties(Collections.emptyMap(), properties.getETag(),
+ properties.getLastModified(), false, properties.getSmbProperties()).getFileName());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @ParameterizedTest
+ @ValueSource(strings = { "", "parent/directory" })
+ public void directoryPathClientSnapshotUrls(String path) {
+ ShareClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME);
+ ShareDirectoryClient directoryClient = testShareClient.getSnapshotClient("snapshot").getDirectoryClient(path);
+
+ Assertions.assertEquals(path, directoryClient.getDirectoryPath());
+ Assertions.assertEquals(
+ FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "/" + path + "?sharesnapshot=snapshot",
+ directoryClient.getDirectoryUrl());
+ assertEquals("", directoryClient.getFileId());
+ Assertions.assertEquals(FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "/"
+ + (path.isEmpty() ? "" : path + "/") + "child?sharesnapshot=snapshot",
+ directoryClient.getSubdirectoryClient("child").getDirectoryUrl());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @ParameterizedTest
+ @ValueSource(strings = { "", "parent/directory" })
+ public void directoryClientBuilderClearsFileIdForPath(String path) {
+ ShareFileClientBuilder builder = new ShareFileClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .shareName(FileIdTestHelper.SHARE_NAME)
+ .fileId(FileIdTestHelper.FILE_ID);
+ ShareDirectoryClient directoryClient = builder.resourcePath(path).buildDirectoryClient();
+ Assertions.assertEquals(path, directoryClient.getDirectoryPath());
+ assertEquals("", directoryClient.getFileId());
+ String expectedUrl = FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "/" + path;
+ Assertions.assertEquals(expectedUrl, directoryClient.getDirectoryUrl());
+ Assertions.assertEquals(expectedUrl + (path.isEmpty() ? "" : "/") + "file.txt",
+ directoryClient.getFileClient("file.txt").getFileUrl());
+ Assertions.assertEquals(expectedUrl,
+ builder.fileId(FileIdTestHelper.FILE_ID).endpoint(expectedUrl).buildDirectoryClient().getDirectoryUrl());
+ }
+
@Test
public void getShareSnapshotUrl() {
String accountName
diff --git a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/DirectoryAsyncApiTests.java b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/DirectoryAsyncApiTests.java
index e4329f218fca0..5f519b80cada5 100644
--- a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/DirectoryAsyncApiTests.java
+++ b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/DirectoryAsyncApiTests.java
@@ -4,7 +4,14 @@
package com.azure.storage.file.share;
import com.azure.core.http.HttpHeader;
+import com.azure.core.http.HttpHeaderName;
+import com.azure.core.http.HttpHeaders;
+import com.azure.core.http.HttpMethod;
+import com.azure.core.http.HttpPipeline;
+import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.http.rest.Response;
+import com.azure.core.test.annotation.DoNotRecord;
+import com.azure.core.test.http.MockHttpResponse;
import com.azure.storage.blob.BlobServiceVersion;
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.storage.common.implementation.Constants;
@@ -30,10 +37,14 @@
import com.azure.storage.file.share.options.ShareFileRenameOptions;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.junit.jupiter.params.provider.ValueSource;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@@ -73,7 +84,11 @@ public class DirectoryAsyncApiTests extends FileShareTestBase {
= "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-188441444-3053964)S:NO_ACCESS_CONTROL";
@BeforeEach
- public void setup() {
+ public void setup(TestInfo testInfo) {
+ if (testInfo.getTags().contains("file-id-mock")) {
+ return;
+ }
+
shareName = generateShareName();
directoryPath = generatePathName();
shareClient = shareBuilderHelper(shareName).buildClient();
@@ -94,6 +109,196 @@ public void getDirectoryURL() {
assertEquals(expectURL, directoryURL);
}
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @ParameterizedTest
+ @ValueSource(booleans = { false, true })
+ public void asyncDirectoryPropertiesByFileId(boolean snapshot) {
+ primaryDirectoryAsyncClient.createWithResponse(new ShareDirectoryCreateOptions().setMetadata(testMetadata))
+ .block();
+ ShareDirectoryProperties expected = primaryDirectoryAsyncClient.getProperties().block();
+ String fileId = expected.getSmbProperties().getFileId();
+ assertNotNull(fileId);
+ ShareAsyncClient source = shareBuilderHelper(shareName).buildAsyncClient();
+ if (snapshot) {
+ source = source.getSnapshotClient(source.createSnapshot().block().getSnapshot());
+ primaryDirectoryAsyncClient.setMetadata(Collections.singletonMap("changed", "after-snapshot")).block();
+ }
+
+ ShareDirectoryAsyncClient directoryClient = source.getDirectoryClientByFileId(fileId);
+ assertEquals(fileId, directoryClient.getFileId());
+ StepVerifier.create(directoryClient.getPropertiesWithResponse()).assertNext(response -> {
+ ShareDirectoryProperties actual = response.getValue();
+ assertEquals(200, response.getStatusCode());
+ assertEquals(directoryPath, actual.getFileName());
+ assertEquals(expected.getMetadata(), actual.getMetadata());
+ assertEquals(expected.getETag(), actual.getETag());
+ assertEquals(expected.getLastModified(), actual.getLastModified());
+ assertEquals(expected.isServerEncrypted(), actual.isServerEncrypted());
+ assertEquals(fileId, actual.getSmbProperties().getFileId());
+ assertEquals(expected.getSmbProperties().getParentId(), actual.getSmbProperties().getParentId());
+ assertEquals(expected.getSmbProperties().getFileCreationTime(),
+ actual.getSmbProperties().getFileCreationTime());
+ assertEquals(expected.getSmbProperties().getFileLastWriteTime(),
+ actual.getSmbProperties().getFileLastWriteTime());
+ }).verifyComplete();
+ }
+
+ @LiveOnly
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void asyncDirectoryPropertiesByFileIdLive() {
+ StepVerifier.create(primaryDirectoryAsyncClient.create()
+ .then(primaryDirectoryAsyncClient.getProperties())
+ .flatMap(expected -> shareBuilderHelper(shareName).buildAsyncClient()
+ .getDirectoryClientByFileId(expected.getSmbProperties().getFileId())
+ .getProperties()
+ .doOnNext(actual -> {
+ assertEquals(directoryPath, actual.getFileName());
+ assertEquals(expected.getSmbProperties().getFileId(), actual.getSmbProperties().getFileId());
+ assertEquals(expected.getSmbProperties().getParentId(), actual.getSmbProperties().getParentId());
+ })))
+ .expectNextCount(1)
+ .verifyComplete();
+ }
+
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void asyncDirectoryPropertiesByFileIdMapServiceErrors() {
+ ShareAsyncClient source = shareBuilderHelper(shareName).buildAsyncClient();
+ StepVerifier.create(source.getDirectoryClientByFileId("invalid-file-id").getProperties())
+ .verifyErrorSatisfies(error -> {
+ ShareStorageException exception = assertInstanceOf(ShareStorageException.class, error);
+ assertEquals(400, exception.getStatusCode());
+ assertEquals(ShareErrorCode.INVALID_QUERY_PARAMETER_VALUE, exception.getErrorCode());
+ });
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @ParameterizedTest
+ @ValueSource(booleans = { false, true })
+ public void asyncDirectoryClientByFileIdUrl(boolean snapshot) {
+ ShareAsyncClient source = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildAsyncClient()
+ .getShareAsyncClient(FileIdTestHelper.SHARE_NAME);
+ if (snapshot) {
+ source = source.getSnapshotClient("snapshot");
+ }
+ ShareDirectoryAsyncClient original = source.getDirectoryClientByFileId(FileIdTestHelper.FILE_ID);
+ ShareDirectoryAsyncClient directoryClient = new ShareDirectoryAsyncClient(original);
+ assertEquals(original.getDirectoryUrl(), directoryClient.getDirectoryUrl());
+ assertEquals(FileIdTestHelper.FILE_ID, directoryClient.getFileId());
+ assertEquals("", directoryClient.getDirectoryPath());
+ assertEquals(ShareServiceVersion.V2027_03_07, directoryClient.getServiceVersion());
+ assertEquals(
+ FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME
+ + (snapshot ? "?sharesnapshot=snapshot&" : "?") + "fileid=" + FileIdTestHelper.FILE_ID,
+ directoryClient.getDirectoryUrl());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void asyncRootDirectoryAllowsMetadataUpdates() {
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ assertEquals(HttpMethod.PUT, request.getHttpMethod());
+ assertEquals("/" + FileIdTestHelper.SHARE_NAME + "/", request.getUrl().getPath());
+ assertFalse(request.getUrl().getQuery().contains("fileid="));
+ return Mono.just(new MockHttpResponse(request, 200, FileIdTestHelper.fileHeaders("directory")
+ .set(HttpHeaderName.fromString("x-ms-request-server-encrypted"), "true")));
+ }).build();
+ ShareDirectoryAsyncClient directoryClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .buildAsyncClient()
+ .getShareAsyncClient(FileIdTestHelper.SHARE_NAME)
+ .getRootDirectoryClient();
+
+ StepVerifier.create(directoryClient.setMetadata(Collections.singletonMap("key", "value")))
+ .expectNextCount(1)
+ .verifyComplete();
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @ParameterizedTest
+ @NullAndEmptySource
+ @ValueSource(strings = { " ", "\t", "\n" })
+ public void asyncDirectoryClientByFileIdRejectsBlankIds(String fileId) {
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ throw new AssertionError("Invalid file IDs must be rejected before sending a request.");
+ }).build();
+ ShareAsyncClient source = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .buildAsyncClient()
+ .getShareAsyncClient(FileIdTestHelper.SHARE_NAME);
+ Assertions.assertThrows(IllegalArgumentException.class, () -> source.getDirectoryClientByFileId(fileId));
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void asyncDirectoryPropertiesWithoutFileName() {
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ HttpHeaders headers = FileIdTestHelper.fileHeaders("directory");
+ headers.remove(HttpHeaderName.fromString("x-ms-file-name"));
+ return Mono.just(new MockHttpResponse(request, 200, headers));
+ }).build();
+ ShareDirectoryAsyncClient directoryClient = new ShareFileClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .shareName(FileIdTestHelper.SHARE_NAME)
+ .resourcePath("directory")
+ .pipeline(pipeline)
+ .buildDirectoryAsyncClient();
+ assertEquals("", directoryClient.getFileId());
+ StepVerifier.create(directoryClient.getProperties()).assertNext(properties -> {
+ assertNull(properties.getFileName());
+ FileIdTestHelper.assertSmbProperties(properties.getSmbProperties());
+ }).verifyComplete();
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @ParameterizedTest
+ @ValueSource(strings = { "", "parent/directory" })
+ public void asyncDirectoryPathClientSnapshotUrls(String path) {
+ ShareAsyncClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildAsyncClient()
+ .getShareAsyncClient(FileIdTestHelper.SHARE_NAME);
+ ShareDirectoryAsyncClient directoryClient
+ = testShareClient.getSnapshotClient("snapshot").getDirectoryClient(path);
+ Assertions.assertEquals(path, directoryClient.getDirectoryPath());
+ Assertions.assertEquals(
+ FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "/" + path + "?sharesnapshot=snapshot",
+ directoryClient.getDirectoryUrl());
+ assertEquals("", directoryClient.getFileId());
+ Assertions.assertEquals(FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "/"
+ + (path.isEmpty() ? "" : path + "/") + "child?sharesnapshot=snapshot",
+ directoryClient.getSubdirectoryClient("child").getDirectoryUrl());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @ParameterizedTest
+ @ValueSource(strings = { "", "parent/directory" })
+ public void asyncDirectoryClientBuilderClearsFileIdForPath(String path) {
+ ShareFileClientBuilder builder = new ShareFileClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .shareName(FileIdTestHelper.SHARE_NAME)
+ .fileId(FileIdTestHelper.FILE_ID);
+ ShareDirectoryAsyncClient directoryClient = builder.resourcePath(path).buildDirectoryAsyncClient();
+ Assertions.assertEquals(path, directoryClient.getDirectoryPath());
+ assertEquals("", directoryClient.getFileId());
+ String expectedUrl = FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "/" + path;
+ Assertions.assertEquals(expectedUrl, directoryClient.getDirectoryUrl());
+ Assertions.assertEquals(expectedUrl + (path.isEmpty() ? "" : "/") + "file.txt",
+ directoryClient.getFileClient("file.txt").getFileUrl());
+ Assertions.assertEquals(expectedUrl,
+ builder.fileId(FileIdTestHelper.FILE_ID)
+ .endpoint(expectedUrl)
+ .buildDirectoryAsyncClient()
+ .getDirectoryUrl());
+ }
+
@Test
public void getSubDirectoryClient() {
ShareDirectoryAsyncClient subDirectoryClient
diff --git a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileApiTests.java b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileApiTests.java
index f2d1e78db613c..11e85476ea030 100644
--- a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileApiTests.java
+++ b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileApiTests.java
@@ -6,8 +6,14 @@
import com.azure.core.exception.UnexpectedLengthException;
import com.azure.core.http.HttpHeader;
import com.azure.core.http.HttpHeaderName;
+import com.azure.core.http.HttpHeaders;
+import com.azure.core.http.HttpMethod;
+import com.azure.core.http.HttpPipeline;
+import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.http.rest.PagedResponse;
import com.azure.core.http.rest.Response;
+import com.azure.core.test.annotation.DoNotRecord;
+import com.azure.core.test.http.MockHttpResponse;
import com.azure.core.test.TestMode;
import com.azure.core.util.BinaryData;
import com.azure.core.util.Context;
@@ -51,6 +57,7 @@
import com.azure.storage.file.share.models.ShareFileHandleAccessRights;
import com.azure.storage.file.share.models.ShareFileHttpHeaders;
import com.azure.storage.file.share.models.ShareFileInfo;
+import com.azure.storage.file.share.models.ShareFileLinks;
import com.azure.storage.file.share.models.ShareFileItem;
import com.azure.storage.file.share.models.ShareFileMetadataInfo;
import com.azure.storage.file.share.models.ShareFilePermission;
@@ -85,7 +92,9 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -121,6 +130,8 @@
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import java.util.concurrent.atomic.AtomicReference;
+import reactor.core.publisher.Mono;
import static com.azure.storage.common.implementation.Constants.HeaderConstants.ERROR_CODE_HEADER_NAME;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
@@ -137,10 +148,13 @@
// It is still necessary to test deprecated APIs.
@SuppressWarnings("deprecation")
class FileApiTests extends FileShareTestBase {
+ private static final String FILE_ID_TEST_CONTENT = "file-id properties";
+
private ShareFileClient primaryFileClient;
private ShareClient shareClient;
private String shareName;
private String filePath;
+ private String fileId;
private static Map testMetadata;
private static ShareFileHttpHeaders httpHeaders;
private FileSmbProperties smbProperties;
@@ -148,7 +162,11 @@ class FileApiTests extends FileShareTestBase {
= "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-188441444-3053964)S:NO_ACCESS_CONTROL";
@BeforeEach
- public void setup() {
+ public void setup(TestInfo testInfo) {
+ if (testInfo.getTags().contains("file-id-mock")) {
+ return;
+ }
+
shareName = generateShareName();
filePath = generatePathName();
shareClient = shareBuilderHelper(shareName).buildClient();
@@ -157,6 +175,14 @@ public void setup() {
testMetadata = Collections.singletonMap("testmetadata", "value");
httpHeaders = new ShareFileHttpHeaders().setContentLanguage("en").setContentType("application/octet-stream");
smbProperties = new FileSmbProperties().setNtfsFileAttributes(EnumSet.of(NtfsFileAttributes.NORMAL));
+
+ if (testInfo.getTags().contains("file-id-integration")) {
+ byte[] content = FILE_ID_TEST_CONTENT.getBytes(StandardCharsets.UTF_8);
+ primaryFileClient.create(content.length);
+ primaryFileClient.upload(new ByteArrayInputStream(content), content.length);
+ fileId = primaryFileClient.getProperties().getSmbProperties().getFileId();
+ assertNotNull(fileId);
+ }
}
@Test
@@ -170,6 +196,162 @@ public void getFileURL() {
assertEquals(expectURL, fileURL);
}
+ @Tag("file-id-integration")
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void filePropertiesById() {
+ ShareFileClient factoryClient = shareClient.getFileClientByFileId(fileId);
+ ShareFileClient builderClient = instrument(new ShareFileClientBuilder())
+ .connectionString(ENVIRONMENT.getPrimaryAccount().getConnectionString())
+ .shareName(shareName)
+ .fileId(fileId)
+ .buildFileClient();
+
+ for (ShareFileClient fileIdClient : Arrays.asList(factoryClient, builderClient)) {
+ ShareFileProperties properties = fileIdClient.getProperties();
+ assertEquals(filePath, properties.getFileName());
+ assertEquals(FILE_ID_TEST_CONTENT.length(), properties.getContentLength());
+ assertEquals(fileId, properties.getSmbProperties().getFileId());
+ }
+ }
+
+ @Tag("file-id-integration")
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void fileLinksById() {
+ ShareFileLinks links = shareClient.getFileClientByFileId(fileId).getFileLinks();
+
+ assertEquals(FILE_ID_TEST_CONTENT.length(), links.getProperties().getContentLength());
+ assertEquals(fileId, links.getProperties().getSmbProperties().getFileId());
+ assertEquals(1, links.getLinks().size());
+ assertEquals(filePath, links.getLinks().get(0).getName());
+ assertEquals(links.getProperties().getSmbProperties().getParentId(), links.getLinks().get(0).getParentId());
+ }
+
+ @Tag("file-id-integration")
+ @LiveOnly
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void filePropertiesByIdLive() {
+ ShareFileProperties properties = shareClient.getFileClientByFileId(fileId).getProperties();
+
+ assertEquals(filePath, properties.getFileName());
+ assertEquals(FILE_ID_TEST_CONTENT.length(), properties.getContentLength());
+ assertEquals(fileId, properties.getSmbProperties().getFileId());
+ }
+
+ @Tag("file-id-integration")
+ @LiveOnly
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void fileLinksByIdLive() {
+ ShareFileLinks links = shareClient.getFileClientByFileId(fileId).getFileLinks();
+
+ assertEquals(fileId, links.getProperties().getSmbProperties().getFileId());
+ assertEquals(1, links.getLinks().size());
+ assertEquals(filePath, links.getLinks().get(0).getName());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void fileLinksMapPropertiesAndDecodeLinkNames() {
+ AtomicReference requestUrl = new AtomicReference<>();
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ Assertions.assertEquals(HttpMethod.GET, request.getHttpMethod());
+ requestUrl.set(request.getUrl().toString());
+ String body = "file%20name.txt "
+ + "parent-id " + " ";
+ HttpHeaders headers
+ = FileIdTestHelper.fileHeaders("file.txt").set(HttpHeaderName.CONTENT_TYPE, "application/xml");
+ return Mono.just(new MockHttpResponse(request, 200, headers, body.getBytes(StandardCharsets.UTF_8)));
+ }).build();
+
+ ShareClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME);
+ ShareFileLinks links = testShareClient.getFileClientByFileId(FileIdTestHelper.FILE_ID).getFileLinks();
+
+ Assertions.assertEquals("file.txt", links.getProperties().getFileName());
+ Assertions.assertEquals("en", links.getProperties().getContentLanguage());
+ Assertions.assertEquals("gzip", links.getProperties().getContentEncoding());
+ FileIdTestHelper.assertSmbProperties(links.getProperties().getSmbProperties());
+ Assertions.assertEquals(1, links.getLinks().size());
+ Assertions.assertEquals("file name.txt", links.getLinks().get(0).getName());
+ Assertions.assertEquals("parent-id", links.getLinks().get(0).getParentId());
+ Assertions.assertTrue(requestUrl.get().contains("comp=hardlinks"));
+ Assertions.assertTrue(requestUrl.get().contains("fileid=" + FileIdTestHelper.FILE_ID));
+ }
+
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void propertiesByIdMapServiceErrors() {
+ ShareStorageException exception = assertThrows(ShareStorageException.class,
+ () -> shareClient.getFileClientByFileId("invalid-file-id").getProperties());
+ assertEquals(400, exception.getStatusCode());
+ assertEquals(ShareErrorCode.INVALID_QUERY_PARAMETER_VALUE, exception.getErrorCode());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void fileClientFileIdValidation() {
+ AtomicReference requestSent = new AtomicReference<>(false);
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ requestSent.set(true);
+ return Mono.just(new MockHttpResponse(request, 200));
+ }).build();
+
+ ShareClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME);
+ IllegalStateException linksException = Assertions.assertThrows(IllegalStateException.class,
+ () -> testShareClient.getFileClient("path/file").getFileLinks());
+ Assertions.assertEquals("getFileLinks requires a file-ID-addressed client.", linksException.getMessage());
+ Assertions.assertThrows(IllegalArgumentException.class, () -> testShareClient.getFileClientByFileId(" "));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> testShareClient.getFileClientByFileId(null));
+ Assertions.assertFalse(requestSent.get());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void fileClientBuilderParsesFileIdFromEndpointQuery() {
+ ShareFileClient fileClient = new ShareFileClientBuilder()
+ .endpoint(
+ FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "?fileid=" + FileIdTestHelper.FILE_ID)
+ .buildFileClient();
+
+ Assertions.assertEquals(FileIdTestHelper.FILE_ID, fileClient.getFileId());
+ Assertions.assertEquals("", fileClient.getFilePath());
+ Assertions.assertEquals(
+ FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "?fileid=" + FileIdTestHelper.FILE_ID,
+ fileClient.getFileUrl());
+
+ ShareFileClient configuredFileIdClient = new ShareFileClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .shareName(FileIdTestHelper.SHARE_NAME)
+ .fileId(FileIdTestHelper.FILE_ID)
+ .buildFileClient();
+ Assertions.assertEquals(FileIdTestHelper.FILE_ID, configuredFileIdClient.getFileId());
+ Assertions.assertEquals("", configuredFileIdClient.getFilePath());
+
+ ShareFileClient pathClient = new ShareFileClientBuilder()
+ .endpoint(FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "/file.txt")
+ .buildFileClient();
+ Assertions.assertEquals("", pathClient.getFileId());
+ Assertions.assertEquals("file.txt", pathClient.getFilePath());
+ Assertions.assertThrows(IllegalArgumentException.class, () -> new ShareFileClientBuilder().fileId(" "));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> new ShareFileClientBuilder().fileId(null));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> new ShareFileClientBuilder()
+ .endpoint(FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "?fileid="));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> new ShareFileClientBuilder()
+ .endpoint(FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "?fileid=%20"));
+ }
+
@Test
public void getShareSnapshotURL() {
String accountName
diff --git a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileAsyncApiTests.java b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileAsyncApiTests.java
index 99d9120e0dd92..11c6b93f8648e 100644
--- a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileAsyncApiTests.java
+++ b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileAsyncApiTests.java
@@ -6,8 +6,14 @@
import com.azure.core.exception.UnexpectedLengthException;
import com.azure.core.http.HttpHeader;
import com.azure.core.http.HttpHeaderName;
+import com.azure.core.http.HttpHeaders;
+import com.azure.core.http.HttpMethod;
+import com.azure.core.http.HttpPipeline;
+import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.http.rest.Response;
+import com.azure.core.test.annotation.DoNotRecord;
import com.azure.core.test.TestMode;
+import com.azure.core.test.http.MockHttpResponse;
import com.azure.core.util.BinaryData;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.FluxUtil;
@@ -38,6 +44,7 @@
import com.azure.storage.file.share.models.ShareFileDownloadHeaders;
import com.azure.storage.file.share.models.ShareFileHttpHeaders;
import com.azure.storage.file.share.models.ShareFileInfo;
+import com.azure.storage.file.share.models.ShareFileLinks;
import com.azure.storage.file.share.models.ShareFilePermission;
import com.azure.storage.file.share.models.ShareFileProperties;
import com.azure.storage.file.share.models.ShareFileRange;
@@ -65,7 +72,9 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -102,6 +111,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -117,10 +127,13 @@
@SuppressWarnings("deprecation")
public class FileAsyncApiTests extends FileShareTestBase {
+ private static final String FILE_ID_TEST_CONTENT = "file-id properties";
+
private ShareFileAsyncClient primaryFileAsyncClient;
private ShareAsyncClient shareAsyncClient;
private String shareName;
private String filePath;
+ private String fileId;
private static Map testMetadata;
private static ShareFileHttpHeaders httpHeaders;
private FileSmbProperties smbProperties;
@@ -128,7 +141,11 @@ public class FileAsyncApiTests extends FileShareTestBase {
= "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-188441444-3053964)S:NO_ACCESS_CONTROL";
@BeforeEach
- public void setup() {
+ public void setup(TestInfo testInfo) {
+ if (testInfo.getTags().contains("file-id-mock")) {
+ return;
+ }
+
shareName = generateShareName();
filePath = generatePathName();
shareAsyncClient = shareBuilderHelper(shareName).buildAsyncClient();
@@ -137,6 +154,15 @@ public void setup() {
testMetadata = Collections.singletonMap("testmetadata", "value");
httpHeaders = new ShareFileHttpHeaders().setContentLanguage("en").setContentType("application/octet-stream");
smbProperties = new FileSmbProperties().setNtfsFileAttributes(EnumSet.of(NtfsFileAttributes.NORMAL));
+
+ if (testInfo.getTags().contains("file-id-integration")) {
+ byte[] content = FILE_ID_TEST_CONTENT.getBytes(StandardCharsets.UTF_8);
+ primaryFileAsyncClient.create(content.length).block();
+ primaryFileAsyncClient.upload(Flux.just(ByteBuffer.wrap(content)), content.length).block();
+ ShareFileProperties properties = Objects.requireNonNull(primaryFileAsyncClient.getProperties().block());
+ fileId = Objects.requireNonNull(properties.getSmbProperties()).getFileId();
+ Assertions.assertNotNull(fileId);
+ }
}
@Test
@@ -149,6 +175,125 @@ public void getFileURL() {
assertEquals(expectURL, fileURL);
}
+ @Tag("file-id-integration")
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void asyncFilePropertiesById() {
+ ShareFileAsyncClient factoryClient = shareAsyncClient.getFileClientByFileId(fileId);
+ ShareFileAsyncClient builderClient = instrument(new ShareFileClientBuilder())
+ .connectionString(ENVIRONMENT.getPrimaryAccount().getConnectionString())
+ .shareName(shareName)
+ .fileId(fileId)
+ .buildFileAsyncClient();
+
+ for (ShareFileAsyncClient fileIdClient : Arrays.asList(factoryClient, builderClient)) {
+ ShareFileProperties properties = fileIdClient.getProperties().block();
+ Assertions.assertEquals(filePath, properties.getFileName());
+ Assertions.assertEquals(FILE_ID_TEST_CONTENT.length(), properties.getContentLength());
+ Assertions.assertEquals(fileId, properties.getSmbProperties().getFileId());
+ }
+ }
+
+ @Tag("file-id-integration")
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void asyncFileLinksById() {
+ ShareFileLinks links = shareAsyncClient.getFileClientByFileId(fileId).getFileLinks().block();
+
+ assertEquals(FILE_ID_TEST_CONTENT.length(), links.getProperties().getContentLength());
+ assertEquals(fileId, links.getProperties().getSmbProperties().getFileId());
+ assertEquals(1, links.getLinks().size());
+ assertEquals(filePath, links.getLinks().get(0).getName());
+ assertEquals(links.getProperties().getSmbProperties().getParentId(), links.getLinks().get(0).getParentId());
+ }
+
+ @Tag("file-id-integration")
+ @LiveOnly
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void asyncFilePropertiesByIdLive() {
+ StepVerifier.create(shareAsyncClient.getFileClientByFileId(fileId).getProperties()).assertNext(properties -> {
+ assertEquals(filePath, properties.getFileName());
+ assertEquals(FILE_ID_TEST_CONTENT.length(), properties.getContentLength());
+ assertEquals(fileId, properties.getSmbProperties().getFileId());
+ }).verifyComplete();
+ }
+
+ @Tag("file-id-integration")
+ @LiveOnly
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void asyncFileLinksByIdLive() {
+ StepVerifier.create(shareAsyncClient.getFileClientByFileId(fileId).getFileLinks()).assertNext(links -> {
+ assertEquals(fileId, links.getProperties().getSmbProperties().getFileId());
+ assertEquals(1, links.getLinks().size());
+ assertEquals(filePath, links.getLinks().get(0).getName());
+ }).verifyComplete();
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void asyncFileLinksMapPropertiesAndDecodeLinkNames() {
+ AtomicReference requestUrl = new AtomicReference<>();
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ Assertions.assertEquals(HttpMethod.GET, request.getHttpMethod());
+ requestUrl.set(request.getUrl().toString());
+ String body = "file%20name.txt "
+ + "parent-id " + " ";
+ HttpHeaders headers
+ = FileIdTestHelper.fileHeaders("file.txt").set(HttpHeaderName.CONTENT_TYPE, "application/xml");
+ return Mono.just(new MockHttpResponse(request, 200, headers, body.getBytes(StandardCharsets.UTF_8)));
+ }).build();
+
+ ShareAsyncClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildAsyncClient()
+ .getShareAsyncClient(FileIdTestHelper.SHARE_NAME);
+ ShareFileLinks links = testShareClient.getFileClientByFileId(FileIdTestHelper.FILE_ID).getFileLinks().block();
+
+ Assertions.assertEquals("file.txt", links.getProperties().getFileName());
+ Assertions.assertEquals("en", links.getProperties().getContentLanguage());
+ Assertions.assertEquals("gzip", links.getProperties().getContentEncoding());
+ FileIdTestHelper.assertSmbProperties(links.getProperties().getSmbProperties());
+ Assertions.assertEquals(1, links.getLinks().size());
+ Assertions.assertEquals("file name.txt", links.getLinks().get(0).getName());
+ Assertions.assertEquals("parent-id", links.getLinks().get(0).getParentId());
+ Assertions.assertTrue(requestUrl.get().contains("comp=hardlinks"));
+ Assertions.assertTrue(requestUrl.get().contains("fileid=" + FileIdTestHelper.FILE_ID));
+ }
+
+ @RequiredServiceVersion(clazz = ShareServiceVersion.class, min = "2027-03-07")
+ @Test
+ public void asyncPropertiesByIdMapServiceErrors() {
+ ShareStorageException exception = Assertions.assertThrows(ShareStorageException.class,
+ () -> shareAsyncClient.getFileClientByFileId("invalid-file-id").getProperties().block());
+ assertEquals(400, exception.getStatusCode());
+ assertEquals(ShareErrorCode.INVALID_QUERY_PARAMETER_VALUE, exception.getErrorCode());
+ }
+
+ @DoNotRecord
+ @Tag("file-id-mock")
+ @Test
+ public void asyncFileLinksRequireFileId() {
+ AtomicReference requestSent = new AtomicReference<>(false);
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ requestSent.set(true);
+ return Mono.just(new MockHttpResponse(request, 200));
+ }).build();
+
+ ShareAsyncClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildAsyncClient()
+ .getShareAsyncClient(FileIdTestHelper.SHARE_NAME);
+ IllegalStateException linksException = Assertions.assertThrows(IllegalStateException.class,
+ () -> testShareClient.getFileClient("path/file").getFileLinks().block());
+ Assertions.assertEquals("getFileLinks requires a file-ID-addressed client.", linksException.getMessage());
+ Assertions.assertFalse(requestSent.get());
+ }
+
@Test
public void createFile() {
StepVerifier.create(primaryFileAsyncClient.createWithResponse(1024, null, null, null, null))
diff --git a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileIdTestHelper.java b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileIdTestHelper.java
new file mode 100644
index 0000000000000..b9dc78e682994
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileIdTestHelper.java
@@ -0,0 +1,51 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.storage.file.share;
+
+import com.azure.core.http.HttpHeaderName;
+import com.azure.core.http.HttpHeaders;
+
+import java.time.OffsetDateTime;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+final class FileIdTestHelper {
+ static final String ENDPOINT = "https://account.file.core.windows.net";
+ static final String SHARE_NAME = "share";
+ static final String FILE_ID = "12384898975283830";
+ private static final String FILE_TIME = "2026-09-29T12:34:56.1234567Z";
+
+ private FileIdTestHelper() {
+ }
+
+ static HttpHeaders fileHeaders(String fileName) {
+ return new HttpHeaders().set(HttpHeaderName.ETAG, "\"0x8DEAF1479E1C087\"")
+ .set(HttpHeaderName.LAST_MODIFIED, "Wed, 21 Oct 2015 07:28:00 GMT")
+ .set(HttpHeaderName.CONTENT_TYPE, "application/octet-stream")
+ .set(HttpHeaderName.CONTENT_LENGTH, "1024")
+ .set(HttpHeaderName.CONTENT_LANGUAGE, "en")
+ .set(HttpHeaderName.CONTENT_ENCODING, "gzip")
+ .set(HttpHeaderName.fromString("x-ms-meta-key"), "value")
+ .set(HttpHeaderName.fromString("x-ms-file-creation-time"), FILE_TIME)
+ .set(HttpHeaderName.fromString("x-ms-file-last-write-time"), FILE_TIME)
+ .set(HttpHeaderName.fromString("x-ms-file-change-time"), FILE_TIME)
+ .set(HttpHeaderName.fromString("x-ms-file-id"), FILE_ID)
+ .set(HttpHeaderName.fromString("x-ms-file-parent-id"), "parent-id")
+ .set(HttpHeaderName.fromString("x-ms-file-name"), fileName)
+ .set(HttpHeaderName.fromString("x-ms-type"), "file")
+ .set(HttpHeaderName.fromString("x-ms-server-encrypted"), "false")
+ .set(HttpHeaderName.fromString("x-ms-content-type"), "application/octet-stream")
+ .set(HttpHeaderName.fromString("x-ms-content-length"), "1024")
+ .set(HttpHeaderName.fromString("x-ms-content-language"), "en")
+ .set(HttpHeaderName.fromString("x-ms-content-encoding"), "gzip");
+ }
+
+ static void assertSmbProperties(FileSmbProperties properties) {
+ assertEquals(FILE_ID, properties.getFileId());
+ assertEquals("parent-id", properties.getParentId());
+ assertEquals(OffsetDateTime.parse(FILE_TIME), properties.getFileCreationTime());
+ assertEquals(OffsetDateTime.parse(FILE_TIME), properties.getFileLastWriteTime());
+ assertEquals(OffsetDateTime.parse(FILE_TIME), properties.getFileChangeTime());
+ }
+}
diff --git a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileIdUnsupportedOperationsTests.java b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileIdUnsupportedOperationsTests.java
new file mode 100644
index 0000000000000..8341cc51b0c5c
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileIdUnsupportedOperationsTests.java
@@ -0,0 +1,511 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.storage.file.share;
+
+import com.azure.core.http.HttpPipeline;
+import com.azure.core.http.HttpPipelineBuilder;
+import com.azure.core.test.annotation.DoNotRecord;
+import com.azure.core.test.http.MockHttpResponse;
+import com.azure.core.util.Context;
+import com.azure.storage.common.ParallelTransferOptions;
+import com.azure.storage.file.share.models.ShareFileRange;
+import com.azure.storage.file.share.models.ShareFileUploadOptions;
+import com.azure.storage.file.share.models.ShareFileUploadRangeOptions;
+import com.azure.storage.file.share.options.ShareFileCopyOptions;
+import com.azure.storage.file.share.options.ShareFileCreateHardLinkOptions;
+import com.azure.storage.file.share.options.ShareFileCreateOptions;
+import com.azure.storage.file.share.specialized.ShareLeaseClientBuilder;
+import com.azure.storage.file.share.options.ShareFileCreateSymbolicLinkOptions;
+import com.azure.storage.file.share.options.ShareFileDownloadOptions;
+import com.azure.storage.file.share.options.ShareFileListRangesDiffOptions;
+import com.azure.storage.file.share.options.ShareFileListRangesOptions;
+import com.azure.storage.file.share.options.ShareFileRenameOptions;
+import com.azure.storage.file.share.options.ShareFileSetPropertiesOptions;
+import com.azure.storage.file.share.options.ShareFileUploadRangeFromUrlOptions;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+// Temporary file-ID restrictions; remove the corresponding assertions as operations become supported.
+@SuppressWarnings("deprecation")
+class FileIdUnsupportedOperationsTests {
+ @DoNotRecord
+ @Test
+ public void fileIdClientsRejectPathOperations() {
+ AtomicReference requestSent = new AtomicReference<>(false);
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ requestSent.set(true);
+ return Mono.just(new MockHttpResponse(request, 200));
+ }).build();
+
+ ShareClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME);
+ ShareFileClient fileClient = testShareClient.getFileClientByFileId(FileIdTestHelper.FILE_ID);
+
+ Assertions.assertThrows(IllegalStateException.class, fileClient::exists);
+ IllegalStateException createException
+ = Assertions.assertThrows(IllegalStateException.class, () -> fileClient.create(1024));
+ Assertions.assertEquals("create is not supported for a file-ID-addressed client.",
+ createException.getMessage());
+ Assertions.assertThrows(IllegalStateException.class, fileClient::delete);
+ Assertions.assertThrows(IllegalStateException.class, () -> fileClient.setMetadata(null));
+ Assertions.assertThrows(IllegalStateException.class, () -> fileClient.rename("destination"));
+ Assertions.assertThrows(IllegalStateException.class, fileClient::getFileOutputStream);
+ Assertions.assertThrows(IllegalStateException.class, () -> fileClient.generateSas(null));
+ assertThrows(IllegalStateException.class, () -> fileClient.existsWithResponse(null, Context.NONE));
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.createWithResponse(new ShareFileCreateOptions(1024), null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.deleteWithResponse(null, null, Context.NONE));
+ assertThrows(IllegalStateException.class, fileClient::deleteIfExists);
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.deleteIfExistsWithResponse(null, null, Context.NONE));
+ String sourceUrl = FileIdTestHelper.ENDPOINT + "/" + FileIdTestHelper.SHARE_NAME + "/source";
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.beginCopy(sourceUrl, Collections.emptyMap(), null).poll());
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.beginCopy(sourceUrl, new ShareFileCopyOptions(), null).poll());
+ assertThrows(IllegalStateException.class, () -> fileClient.abortCopy("copy-id"));
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.abortCopyWithResponse("copy-id", null, null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.setProperties(1024, null, null, null));
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.setPropertiesWithResponse(new ShareFileSetPropertiesOptions(1024), null, Context.NONE));
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.setMetadataWithResponse(null, null, null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.uploadRangeFromUrl(1, 0, 0, sourceUrl));
+ assertThrows(IllegalStateException.class, () -> fileClient
+ .uploadRangeFromUrlWithResponse(new ShareFileUploadRangeFromUrlOptions(1, sourceUrl), null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.clearRange(1));
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.clearRangeWithResponse(1, 0, null, null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.listRanges().iterator().hasNext());
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.listRanges(new ShareFileRange(0, 0L), null, null, Context.NONE).iterator().hasNext());
+ assertThrows(IllegalStateException.class, () -> fileClient.listRangesDiff("snapshot"));
+ assertThrows(IllegalStateException.class, () -> fileClient
+ .listRangesDiffWithResponse(new ShareFileListRangesDiffOptions("snapshot"), null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.listAllRanges().iterator().hasNext());
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.listAllRanges(new ShareFileListRangesOptions(), null, Context.NONE).iterator().hasNext());
+ assertThrows(IllegalStateException.class, () -> fileClient.listAllRangesDiff("snapshot").iterator().hasNext());
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.listAllRangesDiff(new ShareFileListRangesDiffOptions("snapshot"), null, Context.NONE)
+ .iterator()
+ .hasNext());
+ assertThrows(IllegalStateException.class, () -> fileClient.listHandles().iterator().hasNext());
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.listHandles(1, null, Context.NONE).iterator().hasNext());
+ assertThrows(IllegalStateException.class, () -> fileClient.forceCloseHandle("handle"));
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.forceCloseHandleWithResponse("handle", null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.forceCloseAllHandles(null, Context.NONE));
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.renameWithResponse(new ShareFileRenameOptions("destination"), null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.createHardLink("target"));
+ assertThrows(IllegalStateException.class, () -> fileClient
+ .createHardLinkWithResponse(new ShareFileCreateHardLinkOptions("target"), null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.createSymbolicLink("target"));
+ assertThrows(IllegalStateException.class, () -> fileClient
+ .createSymbolicLinkWithResponse(new ShareFileCreateSymbolicLinkOptions("target"), null, Context.NONE));
+ assertThrows(IllegalStateException.class, fileClient::getSymbolicLink);
+ assertThrows(IllegalStateException.class, () -> fileClient.getSymbolicLinkWithResponse(null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.generateSas(null, null, Context.NONE));
+ assertThrows(IllegalStateException.class, () -> fileClient.generateUserDelegationSas(null, null));
+ assertThrows(IllegalStateException.class,
+ () -> fileClient.generateUserDelegationSas(null, null, null, Context.NONE));
+ assertThrows(IllegalStateException.class, fileClient::openInputStream);
+ assertThrows(IllegalStateException.class, () -> fileClient.openInputStream(new ShareFileRange(0, 0L)));
+ assertThrows(IllegalStateException.class, () -> fileClient.getFileOutputStream(0));
+ assertThrows(IllegalStateException.class, () -> fileClient.getFileSeekableByteChannelRead(null));
+ assertThrows(IllegalStateException.class, () -> fileClient.getFileSeekableByteChannelWrite(null));
+ Assertions.assertFalse(requestSent.get());
+ }
+
+ @DoNotRecord
+ @Test
+ public void fileIdLeaseBuildersRejectPathOperations() {
+ AtomicReference requestSent = new AtomicReference<>(false);
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ requestSent.set(true);
+ return Mono.just(new MockHttpResponse(request, 200));
+ }).build();
+
+ ShareClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildClient()
+ .getShareClient(FileIdTestHelper.SHARE_NAME);
+ ShareFileClient fileClient = testShareClient.getFileClientByFileId(FileIdTestHelper.FILE_ID);
+
+ IllegalStateException buildException
+ = assertThrows(IllegalStateException.class, () -> new ShareLeaseClientBuilder().fileClient(fileClient));
+ assertEquals("fileClient is not supported for a file-ID-addressed client.", buildException.getMessage());
+ assertFalse(requestSent.get());
+ }
+
+ @DoNotRecord
+ @Test
+ public void asyncFileIdLeaseBuildersRejectPathOperations() {
+ AtomicReference requestSent = new AtomicReference<>(false);
+ HttpPipeline pipeline = new HttpPipelineBuilder().httpClient(request -> {
+ requestSent.set(true);
+ return Mono.just(new MockHttpResponse(request, 200));
+ }).build();
+
+ ShareAsyncClient testShareClient = new ShareServiceClientBuilder().endpoint(FileIdTestHelper.ENDPOINT)
+ .pipeline(pipeline)
+ .serviceVersion(ShareServiceVersion.V2027_03_07)
+ .buildAsyncClient()
+ .getShareAsyncClient(FileIdTestHelper.SHARE_NAME);
+ ShareFileAsyncClient fileClient = testShareClient.getFileClientByFileId(FileIdTestHelper.FILE_ID);
+
+ IllegalStateException buildException = assertThrows(IllegalStateException.class,
+ () -> new ShareLeaseClientBuilder().fileAsyncClient(fileClient));
+ assertEquals("fileAsyncClient is not supported for a file-ID-addressed client.", buildException.getMessage());
+ assertFalse(requestSent.get());
+ }
+
+ @DoNotRecord
+ @Test
+ public void asyncFileIdClientsRejectPathOperations() {
+ AtomicReference