FileStorageResource.java
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.spring.autoconfigure.storage.resource;
import com.azure.storage.file.share.ShareClient;
import com.azure.storage.file.share.ShareFileClient;
import com.azure.storage.file.share.ShareServiceClient;
import com.azure.storage.file.share.models.ShareStorageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.WritableResource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.net.URL;
/**
* Implements {@link WritableResource} for reading and writing objects in Azure
* StorageAccount file. An instance of this class represents a handle to a file.
*
* @author Warren Zhu
*/
public class FileStorageResource extends AzureStorageResource {
private static final Logger LOG = LoggerFactory.getLogger(FileStorageResource.class);
private static final String MSG_FAIL_GET = "Failed to get file or container";
private static final String MSG_FAIL_OPEN_OUTPUT = "Failed to open output stream of file";
private static final String MSG_FAIL_CHECK_EXIST = "Failed to check existence of file or container";
private static final String MSG_FAIL_OPEN_INPUT = "Failed to open input stream of file";
private final ShareServiceClient shareServiceClient;
private final ShareClient shareClient;
private final ShareFileClient shareFileClient;
private final String location;
private final boolean autoCreateFiles;
public FileStorageResource(ShareServiceClient shareServiceClient, String location) {
this(shareServiceClient, location, false);
}
FileStorageResource(ShareServiceClient shareServiceClient, String location, boolean autoCreateFiles) {
assertIsAzureStorageLocation(location);
this.autoCreateFiles = autoCreateFiles;
this.location = location;
this.shareServiceClient = shareServiceClient;
this.shareClient = shareServiceClient.getShareClient(getContainerName(location));
this.shareFileClient = shareClient.getFileClient(getFilename(location));
}
@Override
public OutputStream getOutputStream() throws IOException {
try {
if (!exists()) {
if (autoCreateFiles) {
create();
} else {
throw new FileNotFoundException("The file was not found: " + this.location);
}
}
return this.shareFileClient.getFileOutputStream();
} catch (ShareStorageException e) {
LOG.error(MSG_FAIL_OPEN_OUTPUT, e);
throw new IOException(MSG_FAIL_OPEN_OUTPUT, e);
}
}
@Override
public boolean exists() {
return this.shareClient.exists() && shareFileClient.exists();
}
@Override
public URL getURL() throws IOException {
return new URL(this.shareFileClient.getFileUrl());
}
@Override
public File getFile() {
throw new UnsupportedOperationException(getDescription() + " cannot be resolved to absolute file path");
}
@Override
public long contentLength() {
return this.shareFileClient.getProperties().getContentLength();
}
@Override
public long lastModified() {
return this.shareFileClient.getProperties().getLastModified().toEpochSecond() * 1000;
}
@Override
public Resource createRelative(String relativePath) {
String newLocation = this.location + "/" + relativePath;
return new FileStorageResource(this.shareServiceClient, newLocation, autoCreateFiles);
}
@Override
public String getFilename() {
final String[] split = this.shareFileClient.getFilePath().split("/");
return split[split.length - 1];
}
@Override
public String getDescription() {
return String.format("Azure storage account file resource [container='%s', file='%s']",
this.shareFileClient.getShareName(), this.getFilename());
}
@Override
public InputStream getInputStream() throws IOException {
try {
assertExisted();
return this.shareFileClient.openInputStream();
} catch (ShareStorageException e) {
LOG.error("Failed to open input stream of cloud file", e);
throw new IOException("Failed to open input stream of cloud file");
}
}
@Override
StorageType getStorageType() {
return StorageType.FILE;
}
private void assertExisted() throws FileNotFoundException {
if (!exists()) {
throw new FileNotFoundException("File or container not existed.");
}
}
private void create() throws ShareStorageException {
if (!shareClient.exists()) {
this.shareClient.create();
}
if (!shareFileClient.exists()) {
//TODO: create method must provide file length, but we don't know actual
this.shareFileClient.create(1024);
}
}
}