Строки подключения к хранилищу BLOB-объектов Azure в нескольких средах конфликтуют - PullRequest
0 голосов
/ 15 октября 2019

Позвольте мне начать с того, что мне трудно сформулировать запрос, чтобы найти ответы на этот вопрос. Я даже не уверен, как описать это вкратце для правильного названия ... Во всяком случае, я искал SO и различные места в Интернете, чтобы получить ответ, но придумываю пончики. Итак ...

У меня есть API (.NET, C #), который работает в трех ветвях среды: dev, qa, prod. У меня есть три службы приложений Azure для поддержки этих трех сред: appServDev, appServQa, appServPod. У меня также есть хранилище BLOB-объектов Azure для каждой среды: blobDev, blobQa, blobProd;каждый с контейнером для хранения больших двоичных объектов для хранения данных, необходимых для передачи конечному пользователю. Кроме того, в производственном хранилище BLOB-объектов имеется контейнер BLOB-объектов, предназначенный для совместного использования определенного набора файлов во всех трех программных средах, назовем его mySharedStorage. Этот контейнер не существует в blobDev или blobQa

Таким образом, структура контейнера BLOB-объектов выглядит примерно так:

blobDev
  -myDevStorage

blobQa
  -myQaStorage

blobProd
  -myProdStorage
  -mySharedStorage

Где контейнер BLOB-объекта my[environment]Storage реплицировал данные пово всех средах, а Dev и Qa просто имеют меньшее подмножество данных продукта. Мы должны сделать это, чтобы отделить данные от продукта для тестирования. mySharedStorage содержит нечувствительные к среде данные, которые нужны всем трем (просто используется для загрузки файла .pdf пользователю).

В Registry.cs и Web.Config я настроил строки подключения для доступа к соответствующему хранилищу в зависимости от среды. В Web.Config у меня есть следующие строки, в которых значение будет преобразовываться в зависимости от среды:

  <add key="MyAzureConnectionString" value="" />
  <add key="MyAzureSharedConnectionString" value="" />

MyAzureSharedConnectionString заканчивается получением правильной строки соединения для blobProd > mySharedStorage, тогда как MyAzureConnectionString получает строкудля соответствующей строки подключения к среде (например, QA получает blobQA > myQaStorage строку подключения);

Однако я не могу получить среды Dev и QA для доступа к файлам в mySharedStorage. Кажется, что, когда я перехожу через код, MyAzureConnectionString переопределяет среду для MyAzureSharedConnectionString. В основном в Dev и QA программа ищет mySharedStorage контейнер в неправильной среде, где он не существует. В Prod, однако, это все работает просто отлично .. потому что оно существует там!

Чтобы проверить все это, я жестко закодировал две строки подключения, где общее хранилище - это всегда правильное производственное общее хранилище, а другое я меняю между тремя средами. Dev и QA терпят неудачу, а Prod всегда работает.

Что мне нужно сделать, чтобы Dev и QA указывали на правильное общее хранилище?

РЕДАКТИРОВАТЬ: Дополнительная информация по запросу. Все это использует BlobStorageUtility со следующим конструктором:

public BlobStorageUtility(
  string blobContainerName,
  string storageConnectionString,
  bool isPublic = true)
{
  this._storageConnectionString = storageConnectionString;
  this.SetBlobContainer(blobContainerName, isPublic);
}

И в файле Registry.cs:

For<IBlobStorageUtility>().Use<BlobStorageUtility>()
    .Named("prodBlobStorageUtility")
    .Ctor<string>("blobContainerName").Is(settings["ProdBlobContainerName"])
    .Ctor<string>("storageConnectionString").Is(settings["AzureStorageConnectionString"])
    .Ctor<bool>("isPublic").Is(true);

For<IBlobStorageUtility>().Use<BlobStorageUtility>()
    .Named("sharedBlobStorageUtility")
    .Ctor<string>("blobContainerName").Is(settings["SharedBlobContainerName"])
    .Ctor<string>("storageConnectionString").Is(settings["AzureSharedStorageConnectionString"])
    .Ctor<bool>("isPublic").Is(true);

, а также int Web.Config для получения значений дляреестр ...

    <add key="ProdBlobContainerName" value="prodWebSite" />
    <add key="SharedBlobContainerName" value="sharedSite-files" />

рабочий код, к которому принимается файл

public class SharedFileService : ISharedFileService
{
    private readonly IBlobStorageUtility _blobStorageUtility;
    private readonly IFileDetailService _fileDetailService

    public MsdsService(IFileDetailService fileDetailService, IBlobStorageUtility blobStorageUtility)
    {
        _blobStorageUtility = blobStorageUtility;
        _fileDetailService = fileDetailService;
    }

    ...

    public FileDto GetFile (int? fileId, string fileName)
    {
        var filename = _fileDetailService.GetfileInfo(fileId, fileName).FileName;
        var contentType = GetContentType(filename); //gets the type of file, in this case a pdf

        // This next line is where I can see the blobStorageUtility is pointed to the wrong environment, not shared
        _blobStorageUtility.SetBlobContainer(ConfigurationManager.AppSettings["SharedBlobContainerName"]);
        // so then this line fails with a null reference... 
        var blobReference = _blobStorageUtility.GetBlockBlobReference($"{filename}");

        if (blobReference.Exists())
        {
            blobReference.FetchAttributes();

            var byteArr = new byte[blobReference.Properties.Length];
            blobReference.DownloadToByteArray(byteArr, 0);

            return new FileDto() { File = byteArr, ContentType = contentType };
        }
        else
        {
            return null;
        }
    }
}

РЕДАКТИРОВАТЬ: В качестве обходного пути для этой проблемы мы просто дублировали общее хранилище во всех трех средахтолько с небольшим подмножеством данных для тестирования. Это не идеально и противоречит цели общего хранилища. Однако это решает задачу. Я все еще хотел бы найти решение, в котором мы можем получить доступ к хранилищу Prod Shared из любой среды, одновременно поддерживая подключение к хранилищу Dev и QA.

...