Get the AccessTier of Blobs - azure-storage

I'm trying to get the AccessTier of blobs. I use the following code snippet:
var blobContainerClient = _blobServiceClient.GetBlobContainerClient("container-name");
await foreach (var blobItem in blobContainerClient.GetBlobsAsync(BlobTraits.All, BlobStates.All))
{
Console.WriteLine(blobItem.Properties.AccessTier)
}
The issue I'm running into is that AccessTier is always null.
I've also tried to get properties explicitly, like:
var properties = blobContainerClient.GetBlobClient(blobItem.Name).GetProperties().Value.AccessTier;
But still it's null. Is there a way to get AccessTier using Azure .NET SDK?

I noticed that the issue is my storage account's type is V1 and in V1 tiers are not supported.

Related

Using ImageFlow Server with multiple Azure Containers

I am currently evaluating ImageFlow Server (https://github.com/imazen/imageflow-dotnet-server) to determine if it will meet the needs of a project that I am working on. Working through the documentation, I was able to get the ImageFlow Server connected to Azure Storage using the following:
public void ConfigureServices(IServiceCollection services)
{
services.AddImageflowAzureBlobService(
new AzureBlobServiceOptions("[MY CONNECTION STRING TO AZURE STORAGE]",
new BlobClientOptions())
.MapPrefix("/azure", "[CONTAINER No. 1]"));
}
This works without issue and I can see images as expected. Current requirements for the project requires that each user will have a unique container though, which makes the implementation above impossible.
Is there a way to pass the container name along with the file name when making a request? Something like: '/azure/CONTAINER/image.jpg?w=250'
We have an example provider to do exactly that here: https://github.com/imazen/imageflow-dotnet-server/blob/main/examples/Imageflow.Server.Example/CustomBlobService.cs
// Custom blob services can do whatever you need. See CustomBlobService.cs in src/Imageflow.Service.Example
services.AddImageflowCustomBlobService(new CustomBlobServiceOptions()
{
Prefix = "/custom_blobs/",
IgnorePrefixCase = true,
ConnectionString = "UseDevelopmentStorage=true;",
// Only allow 'my_container' to be accessed. /custom_blobs/my_container/key.jpg would be an example path.
ContainerKeyFilterFunction = (container, key) =>
container == "my_container" ? Tuple.Create(container, key) : null
});

StackExchange.Redis Connect to multiple db

I am using stackexchange redis client, I want to connect to multiple db not only one How can I handle it ?
https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/Basics.md
You have to pass the DB number in the getDatabase() Method
ConnectionMultiplexer redis = ConnectionMultiplexer.connect("local host");
IDatabase db = redis.GetDatabase(databaseNumber);
if you are using it in .Net Core, I have created a wrapper class which you can use like this:
var redisConnectionString = "{Your Redis Cache Connection String}";
var rest = new Restme(redisConnectionString);
//get cache data (support Generic cast)
var cacheResult = rest.Get("home:testKey");
var cacheResult2 = rest.Get<bool>("home:testKey2");
var cacheResult3 = rest.Get<ObjectType>("home:testKey3");
//set cache data
rest.Post("home:testKey","value");
rest.Post<bool>("home:testKey2",true);
it's actually a simple wrapper of StackExchange.Redis, so if you want to conect to multiple databases, just simply instantiate multiple Restme() objects as separate variables, each contains different Redis db connection.
The source code is in github: https://github.com/oelite/RESTme

How can I get references to BlockBlob objects from CloudBlobDirectory.ListBlobs?

I am using the Microsoft Azure .NET client libraries to interact with Azure cloud storage. I need to be able to access additional information about each blob in its metadata collection. I am currently using CloudBlobDirectory.ListBlobs() method to get a list of blobs in a particular directory of a directory structure I've devised in the blob names. The ListBlobs() method returns a list of IListBlobItem objects. They only have a couple of properties: Url and references to parent directory and parent container. I need to get to the metadata of the actual blob objects.
I envisioned there would be a way to either cast the IListBlobItem to a BlockBlob object or use the IListBlockItem to get a reference to the BlockBlob, but can't seem to find a way to do that.
My question is: Is there a way to get a BlockBlob object from this method, or do I have to use a different way of getting the actual BlockBlob objects? If different, then can you suggest a way to achieve this, while also being able to filter by the "directory" scheme?
OK... I found a way to do this, and while it seems a little clunky and indirect, it does achieve the main thing I thought should be doable, which is to cast the IListBlobItem directly to a CloudBlockBlob object.
What I am doing is getting the list from the Directory object's ListBlobs() method and then looping over each item in the list and casting the item to a CloudBlockBlob object and then calling the FetchAttributes() method to retrieve the properties (including the metadata). Then add a new "info" object to a new list of info objects. Here's the code I'm using:
CloudBlobDirectory dir = container.GetDirectoryReference(dirPath);
var blobs = dir.ListBlobs(true);
foreach (IListBlobItem item in blobs)
{
CloudBlockBlob blob = (CloudBlockBlob)item;
blob.FetchAttributes();
files.Add(new ImageInfo
{
FileUrl = item.Uri.ToString(),
FileName = item.Uri.PathAndQuery.Replace(restaurantId.ToString().PadLeft(3, '0') + "/", ""),
ImageName = blob.Metadata["Name"]
});
}
The whole "Blob" concept seems needlessly complex and doesn't seem to achieve what I'd have thought would have been one of the main features of the Blob wrapper. That is, a way to expand search capabilities by allowing a query over name, directory, container and metadata. I'd have thought you could construct a linq query that would read somewhat like: "return a list of all blobs in the 'images' container, that are in the 'natural/landscapes/' directory path that have a metadata key of 'category' with the value of 'sunset'". There doesn't seem to be a way to do that and that seems to be a missed opportunity to me. Oh, well.
If I'm wrong and way off base here, please let me know.
This approach has been developed for Java, but I hope it can somehow be modified to fit any other supported language. Despite the functionality you ask has not been explicitly developed yet, I think I found a different (hopefully less clunky) way to access CloudBlockBlob data from a ListBlobItem element.
The following code can be used to delete, for example, every blob inside a specific directory.
String blobUri;
CloudBlobClient blobClient = /* Obtain your blob client */
try{
CloudBlobContainer container = /* Obtain your blob container */
for (ListBlobItem blobItem : container.listBlobs(blobPrefix)) {
if (blobItem instanceof CloudBlob) {
blob = (CloudBlob) blobItem;
if (blob.exists()){
System.out.println("Deleting blob " + blob.getName());
blob.delete();
}
}
}
}catch (URISyntaxException | StorageException ex){
Logger.getLogger(BlobOperations.class.getName()).log(Level.SEVERE, null, ex);
}
The previous answers are good. I just wanted to point out 2 things:
1) Nowadays ASYNC programming is recommended to do and supported by Azure SDK as well. So try to use it:
CloudBlobDirectory dir = container.GetDirectoryReference(dirPath);
var blobs = dir.ListBlobs(true);
foreach (IListBlobItem item in blobs)
{
CloudBlockBlob blob = (CloudBlockBlob)item;
await blob.FetchAttributesAsync(); //Use async calls...
}
2) Fetching Metadata in a separate call is not efficient. The code makes 2 HTTP request per blob object. ListBlobs() method supports getting Metadata with as well in one call by setting BlobListingDetails parameter:
CloudBlobDirectory dir = container.GetDirectoryReference(dirPath);
var blobs = dir.ListBlobs(useFlatBlobListing: true, blobListingDetails: BlobListingDetails.Metadata);
I recommend to use second code it it is possible. Since it is the most efficient way to fetch Metadata.

Fetching Publishing Pages from Pages Library in SharePoint 2010 ECMAScript OM

i want to fetch all the pages in a specific Publishing Web using JavaScript and Client Object Model, it keeps giving
The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.
Here's the code,
var selectedDoc;
var ctx = new SP.ClientContext.get_current();
var site = ctx.get_site();
//('created ctx');
//loading the Library
var pagesLib = site.openWeb('/Ar/News').get_lists().getByTitle('Pages');
if (missionType == 'All') {
var query = new SP.CamlQuery();
query.set_viewXml("<View><RowLimit>10</RowLimit></View>");
selectedDoc = pagesLib.getItems(query);
ctx.load(selectedDoc,'Include(Title)');
ctx.executeQueryAsync(getAllNewsWithQuerySuccess(this,this.onListLoadSuccess), getAllNewsWithQueryFailure(this,this.onQueryFailed));
You might be missing a load call. Try this right after you assign pagesLib:
ctx.load(pagesLib);
I'm guessing the error is due to pagesLib not having been populated before you execute the CAML query against it.
You might be missing a load call. Try this right after you assign pagesLib:
ctx.load(pagesLib);
I'm guessing the error is due to pagesLib not having been populated before you execute the CAML query against it.

Querying into alternate workspaces with Rally C# API

I'm making a bunch of Rally API calls using the C# Rally Rest API Wrapper, with great success... except when I'm trying to query into a non-default workspace. For example, take this code:
public Project GetProject(string objectID)
{
Request request = new Request("Project");
// request.Workspace = "2354109555"; //"CTO:SST";
request.Query = new Query("ObjectID", Query.Operator.Equals, objectID);
QueryResult q = _restApi.Query(request);
foreach (var result in q.Results)
{
return CreateProjectFromResult(result);
}
return null;
}
If objectID is in the default workspace, the project is found. If it is not, it is not found. I've tried setting the Workspace property to the workspace object id, the workspace name, not setting it.. to no avail. I've also gone into Rally, switched my default workspace, and verified the switch in which projects are successfully obtained.
I've also triple checked the objectIDs for the projects and workspaces.
I'm officially stumped. Does anyone have the magic answer or something else I can try?
Much appreciated,
Orlando
I think you're 99 pct of the way there. When you specify a workspace attribute on your Request object, it needs to be in the form of a ref, i.e.:
request.Workspace = "/workspace/2354109555"; //"CTO:SST";
Your code should pull from that Workspace once you make that modification.