blob: 0fb3f024f1ebc029a23d7d745db980f0c6b145d3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.airavata.mft.transport.azure;
import com.azure.core.http.rest.PagedIterable;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.blob.models.BlobContainerItem;
import com.azure.storage.blob.models.BlobItem;
import com.azure.storage.blob.models.BlobItemProperties;
import com.azure.storage.blob.models.BlobProperties;
import org.apache.airavata.mft.agent.stub.*;
import org.apache.airavata.mft.core.api.MetadataCollector;
import org.apache.airavata.mft.credential.stubs.azure.AzureSecret;
import org.apache.airavata.mft.resource.stubs.azure.storage.AzureStorage;
public class AzureMetadataCollector implements MetadataCollector {
boolean initialized = false;
private AzureStorage azureStorage;
private AzureSecret azureSecret;
@Override
public void init(StorageWrapper storage, SecretWrapper secret) {
this.azureStorage = storage.getAzure();
this.azureSecret = secret.getAzure();
this.initialized = true;
}
private void checkInitialized() {
if (!initialized) {
throw new IllegalStateException("Azure Metadata Collector is not initialized");
}
}
@Override
public ResourceMetadata getResourceMetadata(String resourcePath, boolean recursiveSearch) throws Exception {
checkInitialized();
// Azure does not have a concept called hierarchical containers. So we assume that there are no containers inside
// the given container
ResourceMetadata.Builder metadataBuilder = ResourceMetadata.newBuilder();
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(azureSecret.getConnectionString()).buildClient();
if (resourcePath.isEmpty() && azureStorage.getContainer().isEmpty()) { // List containers
PagedIterable<BlobContainerItem> blobContainerItems = blobServiceClient.listBlobContainers();
DirectoryMetadata.Builder parentDir = DirectoryMetadata.newBuilder();
parentDir.setResourcePath("");
parentDir.setFriendlyName("");
blobContainerItems.forEach(containerItem -> {
DirectoryMetadata.Builder containerDir = DirectoryMetadata.newBuilder();
containerDir.setFriendlyName(containerItem.getName());
containerDir.setResourcePath(containerItem.getName());
containerDir.setCreatedTime(containerItem.getProperties().getLastModified().toEpochSecond());
containerDir.setUpdateTime(containerItem.getProperties().getLastModified().toEpochSecond());
parentDir.addDirectories(containerDir);
});
metadataBuilder.setDirectory(parentDir);
return metadataBuilder.build();
}
BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient(azureStorage.getContainer());
if (resourcePath.isEmpty()) { // List inside the container
PagedIterable<BlobItem> blobItems = blobContainerClient.listBlobs();
DirectoryMetadata.Builder directoryBuilder = DirectoryMetadata.newBuilder();
blobItems.forEach(blobItem -> {
FileMetadata.Builder fileBuilder = FileMetadata.newBuilder();
BlobItemProperties properties = blobItem.getProperties();
fileBuilder.setResourceSize(properties.getContentLength());
fileBuilder.setCreatedTime(properties.getCreationTime().toEpochSecond());
fileBuilder.setUpdateTime(properties.getCreationTime().toEpochSecond());
fileBuilder.setFriendlyName(blobItem.getName());
fileBuilder.setResourcePath(blobItem.getName());
byte[] contentMd5 = properties.getContentMd5();
StringBuilder md5sb = new StringBuilder();
for (byte aByte : contentMd5) {
md5sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
}
fileBuilder.setMd5Sum(md5sb.toString());
directoryBuilder.addFiles(fileBuilder);
});
metadataBuilder.setDirectory(directoryBuilder);
} else { // If resource is a file
if (!isAvailable(resourcePath)) {
metadataBuilder.setError(MetadataFetchError.NOT_FOUND);
return metadataBuilder.build();
}
BlobClient blobClient = blobContainerClient.getBlobClient(resourcePath);
FileMetadata.Builder fileBuilder = FileMetadata.newBuilder();
BlobProperties properties = blobClient.getProperties();
fileBuilder.setResourceSize(properties.getBlobSize());
fileBuilder.setCreatedTime(properties.getCreationTime().toEpochSecond());
fileBuilder.setUpdateTime(properties.getCreationTime().toEpochSecond());
fileBuilder.setFriendlyName(blobClient.getBlobName());
fileBuilder.setResourcePath(resourcePath);
byte[] contentMd5 = properties.getContentMd5();
StringBuilder md5sb = new StringBuilder();
for (byte aByte : contentMd5) {
md5sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
}
fileBuilder.setMd5Sum(md5sb.toString());
metadataBuilder.setFile(fileBuilder);
}
return metadataBuilder.build();
}
@Override
public Boolean isAvailable(String resourcePath) throws Exception {
checkInitialized();
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(azureSecret.getConnectionString()).buildClient();
BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(azureStorage.getContainer());
boolean containerExists = containerClient.exists();
if (!containerExists) {
return false;
}
if (resourcePath.isEmpty()) {
return true;
}
return containerClient.getBlobClient(resourcePath).exists();
}
}