Commit 101f4b3a authored by Kelly Domico's avatar Kelly Domico
Browse files

Add dependency logging to BlobStore

parent b8e158df
......@@ -24,6 +24,10 @@ import com.azure.storage.blob.sas.BlobContainerSasPermission;
import com.azure.storage.blob.sas.BlobSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
import com.azure.storage.blob.specialized.BlockBlobClient;
import org.apache.http.HttpStatus;
import org.opengroup.osdu.azure.logging.CoreLoggerFactory;
import org.opengroup.osdu.azure.logging.DependencyPayload;
import org.opengroup.osdu.azure.logging.ICoreLogger;
import org.opengroup.osdu.core.common.logging.ILogger;
import org.opengroup.osdu.core.common.model.http.AppException;
......@@ -80,15 +84,18 @@ import java.util.Collections;
public class BlobStore {
private IBlobServiceClientFactory blobServiceClientFactory;
private ILogger logger;
private ICoreLogger coreLogger;
/**
* Constructor to create BlobStore.
* @param factory Factory that provides blob client.
*
* @param factory Factory that provides blob client.
* @param loggerInstance logger instance to be used for logging.
*/
public BlobStore(final IBlobServiceClientFactory factory, final ILogger loggerInstance) {
this.blobServiceClientFactory = factory;
this.logger = loggerInstance;
this.coreLogger = CoreLoggerFactory.getInstance().getLogger(BlobStore.class);
}
private static final String LOG_PREFIX = "azure-core-lib";
......@@ -105,19 +112,28 @@ public class BlobStore {
final String containerName) {
BlobContainerClient blobContainerClient = getBlobContainerClient(dataPartitionId, containerName);
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient(filePath).getBlockBlobClient();
final long start = System.currentTimeMillis();
int statusCode = HttpStatus.SC_OK;
try (ByteArrayOutputStream downloadStream = new ByteArrayOutputStream()) {
blockBlobClient.download(downloadStream);
logger.info(LOG_PREFIX, String.format("Done reading from %s", filePath), Collections.<String, String>emptyMap());
return downloadStream.toString(StandardCharsets.UTF_8.name());
} catch (BlobStorageException ex) {
statusCode = ex.getStatusCode();
if (ex.getErrorCode().equals(BlobErrorCode.BLOB_NOT_FOUND)) {
throw handleBlobStoreException(404, "Specified blob was not found", ex);
}
throw handleBlobStoreException(500, "Failed to read specified blob", ex);
} catch (UnsupportedEncodingException ex) {
statusCode = HttpStatus.SC_BAD_REQUEST;
throw handleBlobStoreException(400, String.format("Encoding was not correct for item with name=%s", filePath), ex);
} catch (IOException ex) {
statusCode = HttpStatus.SC_INTERNAL_SERVER_ERROR;
throw handleBlobStoreException(500, String.format("Malformed document for item with name=%s", filePath), ex);
} finally {
final long timeTaken = System.currentTimeMillis() - start;
final String dependencyData = String.format("%s:%s/%s", dataPartitionId, containerName, filePath);
logDependency("READ_FROM_STORAGE_CONTAINER", dependencyData, dependencyData, timeTaken, String.valueOf(statusCode), statusCode == HttpStatus.SC_OK);
}
}
......@@ -133,14 +149,22 @@ public class BlobStore {
final String containerName) {
BlobContainerClient blobContainerClient = getBlobContainerClient(dataPartitionId, containerName);
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient(filePath).getBlockBlobClient();
final long start = System.currentTimeMillis();
int statusCode = HttpStatus.SC_OK;
try {
blockBlobClient.delete();
logger.info(LOG_PREFIX, String.format("Done deleting blob at %s", filePath), Collections.<String, String>emptyMap());
return true;
} catch (BlobStorageException ex) {
statusCode = ex.getStatusCode();
if (ex.getErrorCode().equals(BlobErrorCode.BLOB_NOT_FOUND)) {
throw handleBlobStoreException(404, "Specified blob was not found", ex);
}
throw handleBlobStoreException(500, "Failed to delete blob", ex);
} finally {
final long timeTaken = System.currentTimeMillis() - start;
final String dependencyData = String.format("%s:%s/%s", dataPartitionId, containerName, filePath);
logDependency("DELETE_FROM_STORAGE_CONTAINER", dependencyData, dependencyData, timeTaken, String.valueOf(statusCode), statusCode == HttpStatus.SC_OK);
}
}
......@@ -159,12 +183,22 @@ public class BlobStore {
int bytesSize = bytes.length;
BlobContainerClient blobContainerClient = getBlobContainerClient(dataPartitionId, containerName);
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient(filePath).getBlockBlobClient();
final long start = System.currentTimeMillis();
int statusCode = HttpStatus.SC_OK;
try (ByteArrayInputStream dataStream = new ByteArrayInputStream(bytes)) {
blockBlobClient.upload(dataStream, bytesSize, true);
logger.info(LOG_PREFIX, String.format("Done uploading file content to %s", filePath), Collections.<String, String>emptyMap());
} catch (BlobStorageException ex) {
statusCode = ex.getStatusCode();
throw handleBlobStoreException(500, "Failed to upload file content.", ex);
} catch (IOException ex) {
statusCode = HttpStatus.SC_INTERNAL_SERVER_ERROR;
throw handleBlobStoreException(500, String.format("Malformed document for item with name=%s", filePath), ex);
} finally {
final long timeTaken = System.currentTimeMillis() - start;
final String dependencyData = String.format("%s:%s/%s", dataPartitionId, containerName, filePath);
logDependency("WRITE_TO_STORAGE_CONTAINER", dependencyData, dependencyData, timeTaken, String.valueOf(statusCode), statusCode == HttpStatus.SC_OK);
}
}
......@@ -198,10 +232,11 @@ public class BlobStore {
/**
* Generates pre-signed url to a blob container.
*
* @param dataPartitionId data partition id
* @param containerName Name of the storage container
* @param expiryTime Time after which the token expires
* @param permissions permissions for the given container
* @param containerName Name of the storage container
* @param expiryTime Time after which the token expires
* @param permissions permissions for the given container
* @return Generates pre-signed url for a given container
*/
public String generatePreSignedURL(final String dataPartitionId, final String containerName, final OffsetDateTime expiryTime, final BlobContainerSasPermission permissions) {
......@@ -211,6 +246,7 @@ public class BlobStore {
/**
* Method is used to copy a file specified at Source URL to the provided destination.
*
* @param dataPartitionId Data partition id
* @param filePath Path of file (blob) to which the file has to be copied
* @param containerName Name of the storage container
......@@ -218,18 +254,18 @@ public class BlobStore {
* @return Blob Copy Final Result.
*/
public BlobCopyInfo copyFile(final String dataPartitionId, final String filePath, final String containerName,
final String sourceUrl) {
final String sourceUrl) {
BlobContainerClient blobContainerClient = getBlobContainerClient(dataPartitionId, containerName);
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient(filePath).getBlockBlobClient();
SyncPoller<BlobCopyInfo, Void> result = blockBlobClient.beginCopy(sourceUrl, Duration.ofSeconds(1));
return result.waitForCompletion().getValue();
}
/**
*
* @param blockBlobClient Blob client
* @param expiryTime Time after which SAS Token expires
* @param permissions Permissions for the given blob
* @param expiryTime Time after which SAS Token expires
* @param permissions Permissions for the given blob
* @return Generates SAS Token.
*/
private String generateSASToken(final BlockBlobClient blockBlobClient, final OffsetDateTime expiryTime, final BlobSasPermission permissions) {
......@@ -238,8 +274,8 @@ public class BlobStore {
}
/**
* @param client Container client
* @param expiryTime Time after which SAS Token expires
* @param client Container client
* @param expiryTime Time after which SAS Token expires
* @param permissions Permissions for the given container
* @return Generates SAS Token.
*/
......@@ -276,4 +312,22 @@ public class BlobStore {
logger.warning(LOG_PREFIX, errorMessage, Collections.<String, String>emptyMap());
return new AppException(status, errorMessage, ex.getMessage(), ex);
}
/**
* Log dependency.
*
* @param name the name of the command initiated with this dependency call
* @param data the command initiated by this dependency call
* @param target the target of this dependency call
* @param timeTakenInMs the request duration in milliseconds
* @param resultCode the result code of the call
* @param success indication of successful or unsuccessful call
*/
private void logDependency(final String name, final String data, final String target, final long timeTakenInMs, final String resultCode, final boolean success) {
DependencyPayload payload = new DependencyPayload(name, data, Duration.ofMillis(timeTakenInMs), resultCode, success);
payload.setType("BlobStore");
payload.setTarget(target);
coreLogger.logDependency(payload);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment