Hej Wam. Trzeba trochę odkurzyć projekt, a z racji, że w chwili pisania tego artykułu wylądowałem na ławce, postanowiłem się podszkolić z wiedzy, która przyda się każdemu. Mi się przydała do mojego projektu.
Nie jest też to droga usługa, przynajmniej na potrzebę usług takich jak galeria na stronie.
W tej części nie tylko opowiem Wam na temat założenia Storage Account, ale także jak obsłużyć “Bloby”.
Przy okazji, to już 2 lata od regularnego pisania w ramach DSP. Dzisiaj nie dałbym radę pisać 2x tygodniowo wpisów jak wtedy.
Azure Storage
Zacznę od tego, że usługa Azure Storage, to zestaw przestrzeni dla plików (Blob i File Storage). Mała baza danych Table Storage, a także kolejki czyli Queue (długo nie wiedziałem jak to wymówić bez łamania języka) Storage.
Warto jeszcze dodać, że usługi te świetnie współgrają z usługami serverless od Azure.
Tworzenie usługi
Do rozpoczęcia pracy z BlobStorage potrzebujemy założyć Azure Storage. Jeśli nie posiadasz subskrypcji Azure, na visualstudio.net po założeniu konta i przejściu do my benefits/moje korzyści można dostać za darmo roczną.Wystarczy do sandboxowania, a nawet prostej strony.
Po zalogowaniu na portal Azure klikamy na Create a Resource a potem Storage Accounts i stwórzcie swoją usługę.
Następnie po wejściu na usługę przechodzimy do Access Key i kopiujemy Connection strings z Key1, np. do naszego appsettings, zmiennych systemowych czy key vault.
No to zaczynamy kod
Czekaliście na to 🙂
Zróbmy to bardziej elegancko, bo dobre nawyki są docenione przez przyszłych lub obecnych pracodawców i kolegów z teamu.
Zacznijmy od interfejsu do naszego repo.
Interfejs i przygotowanie
public interface IBlobStorage
{
Task<BlobItem> Create(BlobItem item);
Task<Result> Update(BlobItem item);
Task<Result> Remove(string name, string folder);
Task<BlobItem> Get(string name, string folder);
Task<IEnumerable<BlobItem>> GetList(string folder);
}
Oraz Data Modelu, na którym oprzemy nasze działania
public class BlobItem
{
public string Container { get; set; }
public Uri Uri { get; set; }
public Uri StorageUri { get; set; }
public Stream Stream { get; set; }
public string Name { get; set; }
}
Zanim zaczniemy, należy pobrać z nugeta paczkę Microsoft.WindowsAzure.Storage.Blob
W konstruktorze tworzymy instancję Blob Client i Blob Accounts
private readonly CloudBlobClient BlobClient;
public BlobStorage(IConfiguration configuration)
{
var storageAccount = CloudStorageAccount.Parse(configuration[“BlobStorage”]);
BlobClient = storageAccount.CreateCloudBlobClient();
}
A następnie obiekt, który tworzy i zarządza naszą kolekcją, czyli kontener:
private CloudBlobContainer GetContainer(string folder)
{
var container = BlobClient.GetContainerReference(folder);
container.CreateIfNotExistsAsync().Wait();
return container;
}
Nazwa folderu, czy kontera określa naszą ścieżkę oraz pozwoli zrobić porządek w plikach oraz zarządzaniu uprawnieniami do nich. Ważne, by ustawić np. w panelu dostępność:
- Private : tylko z poziomu kodu mamy dostęp.
- Container: Użytkownik może widzieć wszystkie pliki w kolekcji
- Blob: Użytkownik może widzieć plik, gdy wejdzie na bezpośredni link do niego
Przy okazji kreator do tworzenia BlobItem
private static BlobItem GenerateBlob(CloudBlockBlob blob)
{
return new BlobItem
{
Container = blob.Container.Name,
StorageUri = blob.StorageUri.PrimaryUri,
Uri = blob.Uri,
Name = blob.Name
};
}
Tworzenie CRUD
To teraz przejdźmy do stworzenia standardowych CRUD Metod dla naszego serwisu:
Create
public async Task<BlobItem> Create(BlobItem item)
{
var container = GetContainer(item.Container);
var blob = container.GetBlockBlobReference(item.Name);
await blob.UploadFromStreamAsync(item.Stream);
item.Uri = blob.Uri.AbsoluteUri;
return item;
}
Get
public async Task<IEnumerable<BlobItem>> GetList(string folder)
{
var container = GetContainer(folder);
var blob = await container.ListBlobsSegmentedAsync(null);
return blob.Results.Select(p =>new BlobItem
{
StorageUri = p.StorageUri.PrimaryUri,
Uri = p.Uri,
Container = p.Container.Name
});
}
public async Task<BlobItem> Get(string name, string folder)
{
var container = GetContainer(folder);
var blob = container.GetBlockBlobReference(name);
return GenerateBlob(blob);
}
Jeśli potrzeba, z BlockBlobReference możemy też pobrać Streama z danymi, które potem możemy zapisać do pliku czy pamięci. Na potrzeby swojej strony, potrzebowałem tylko url do pliku.
Update
public async Task<Result> Update(BlobItem item)
{
try
{
var container = GetContainer(item.Container);
var blob = container.GetBlockBlobReference(item.Name);
await blob.UploadFromStreamAsync(item.Stream);
return Result.Success;
}
catch (Exception)
{
return Result.Failed;
}
}
Podobnie jak create, tylko uploadujemy plik do istniejącego juz bloba.
Delete
A teraz czyścimy
public async Task<Result> Remove(string name, string folder)
{
try
{
var container = GetContainer(folder);
var blob = container.GetBlockBlobReference(name);
await blob.DeleteAsync();
return Result.Success;
}
catch (Exception)
{
return Result.Failed;
}
}
Czyli szukamy naszego bloba i prosty delete 🙂
Podsumowanie
To by było tyle na ten wpis. Nauczyliście się tworzyć serwis w azure oraz obsługiwać go.
Zapraszam do regularnego czytania oraz opinii.
P.s Kod dostępny na GitHub – aluspl/AzureSamples: Azure samples, for upskill and blog i na GitHub – aluspl/LifeLike: CMS System based on net core and microservices