Skip to content

Commit

Permalink
Merge pull request #131 from perfectsense/feature/optimize-filebackend
Browse files Browse the repository at this point in the history
Optimization 5 & 6 - Add exists(String file) and copy(String source, String dest) methods to FileBackend
  • Loading branch information
JC authored Aug 11, 2020
2 parents 0534403 + 8c645db commit 75f228a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 43 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ configurations {
def azureSdkVersion = '1.31.0'

dependencies {
api 'gyro:gyro-core:0.99.4'
api 'gyro:gyro-core:0.99.5' + (releaseBuild ? '' : '-SNAPSHOT')

implementation 'com.psddev:dari-util:3.3.607-xe0f27a'
implementation 'com.google.guava:guava:23.0'
Expand Down
101 changes: 59 additions & 42 deletions src/main/java/gyro/azure/CloudBlobContainerFileBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@

package gyro.azure;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

Expand All @@ -32,14 +31,16 @@
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import com.microsoft.azure.storage.blob.CopyStatus;
import com.microsoft.azure.storage.blob.ListBlobItem;
import com.psddev.dari.util.ObjectUtils;
import com.psddev.dari.util.StringUtils;
import gyro.azure.storage.StorageAccountResource;
import gyro.core.FileBackend;
import gyro.core.GyroCore;
import gyro.core.GyroException;
import gyro.core.Type;
import gyro.core.auth.Credentials;
import gyro.core.auth.CredentialsSettings;

@Type("cloud-blob-container")
Expand Down Expand Up @@ -97,66 +98,78 @@ public void setCredentials(String credentials) {

@Override
public Stream<String> list() throws Exception {
return StreamSupport.stream(container().listBlobs(getPrefix(), true).spliterator(), false)
.map(ListBlobItem::getUri)
.map(URI::getPath)
.filter(f -> f.endsWith(".gyro"))
.map(this::removeContainerAndPrefix);
if (this.equals(GyroCore.getStateBackend(getName()))) {
return StreamSupport.stream(container().listBlobs(getPrefix(), true).spliterator(), false)
.map(ListBlobItem::getUri)
.map(URI::getPath)
.filter(f -> f.endsWith(".gyro"))
.map(this::removeContainerAndPrefix);
}

return Stream.empty();
}

@Override
public InputStream openInput(String file) throws Exception {
return container().getBlockBlobReference(prefixed(file)).openInputStream();
return getBlockBlobReference(file).openInputStream();
}

@Override
public OutputStream openOutput(String file) throws Exception {
return new ByteArrayOutputStream() {

public void close() {
try {
container()
.getBlockBlobReference(prefixed(file))
.uploadFromByteArray(toByteArray(), 0, toByteArray().length);
} catch (StorageException | URISyntaxException | IOException e) {
throw new GyroException(e.getMessage());
}
}
};
return getBlockBlobReference(file).openOutputStream();
}

@Override
public void delete(String file) throws Exception {
// Delete the file only if it exists.
try {
container().getBlockBlobReference(prefixed(file)).delete();
} catch (StorageException e) {
if (e.getHttpStatusCode() != 404) {
throw e;
}
}
getBlockBlobReference(file).deleteIfExists();
}

private Azure client() {
Credentials credentials = getRootScope().getSettings(CredentialsSettings.class)
.getCredentialsByName()
.get("azure::" + getCredentials());
@Override
public boolean exists(String file) throws Exception {
return getBlockBlobReference(file).exists();
}

return AzureResource.createClient((AzureCredentials) credentials);
@Override
public void copy(String source, String destination) throws Exception {
CloudBlockBlob target = getBlockBlobReference(destination);
target.startCopy(getBlockBlobReference(source));

long wait = 0L;

while (true) {
target.downloadAttributes();
CopyStatus copyStatus = target.getCopyState().getStatus();

if (copyStatus != CopyStatus.PENDING) {
if (copyStatus != CopyStatus.SUCCESS) {
throw new GyroException(
String.format("Copying %s to %s failed: %s", source, destination, copyStatus));
}
break;
}
wait += 1000L;
Thread.sleep(wait);
}
}

private CloudBlobContainer container() {
StorageAccountResource storage = getRootScope().findResourceById(
StorageAccountResource.class,
getStorageAccount());

StorageAccount storageAccount = client().storageAccounts()
.getByResourceGroup(getResourceGroup(), getStorageAccount());
String account = getStorageAccount();
StorageAccount storageAccount = Optional.ofNullable(getRootScope())
.map(e -> e.getSettings(CredentialsSettings.class))
.map(CredentialsSettings::getCredentialsByName)
.map(e -> e.get("azure::" + getCredentials()))
.filter(AzureCredentials.class::isInstance)
.map(AzureCredentials.class::cast)
.map(AzureResource::createClient)
.map(Azure::storageAccounts)
.map(e -> e.getByResourceGroup(getResourceGroup(), account))
.orElseThrow(() -> new GyroException("No storage account available!"));
StorageAccountResource storage = getRootScope().findResourceById(StorageAccountResource.class, account);
storage.copyFrom(storageAccount);

try {
CloudStorageAccount account = CloudStorageAccount.parse(storage.getConnection());
CloudBlobClient blobClient = account.createCloudBlobClient();
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.parse(storage.getConnection());
CloudBlobClient blobClient = cloudStorageAccount.createCloudBlobClient();

return blobClient.getContainerReference(getCloudBlobContainer());
} catch (StorageException | URISyntaxException | InvalidKeyException ex) {
Expand All @@ -183,4 +196,8 @@ private String removeContainerAndPrefix(String file) {

return file;
}

private CloudBlockBlob getBlockBlobReference(String file) throws Exception {
return container().getBlockBlobReference(prefixed(file));
}
}

0 comments on commit 75f228a

Please sign in to comment.