Created
July 23, 2018 12:55
-
-
Save benhysell/a7cb2b95b83a50b89382b5cbdf6c3e23 to your computer and use it in GitHub Desktop.
Azure Storage Simulator using Azurite and Docker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using Docker.DotNet; | |
using Docker.DotNet.Models; | |
using Microsoft.WindowsAzure.Storage; | |
using Microsoft.WindowsAzure.Storage.Blob; | |
namespace Web.Utilities | |
{ | |
/// <summary> | |
/// Azure Storage Simulator using Azurite, https://github.com/Azure/Azurite | |
/// </summary> | |
public class AzureStorageSimulator | |
{ | |
private static string _containerPortBlob = "10000"; | |
private static string _containerPortQueue = "10001"; | |
private static string _containerPortTable = "10002"; | |
private static string _dockerImageName = "arafato/azurite"; | |
private static Uri _localHost = new Uri("http://localhost:2375"); | |
/// <summary> | |
/// Start a container | |
/// </summary> | |
/// <param name="dockerContainerName"></param> | |
/// <param name="storagePathLocalFileSystem"></param> | |
/// <param name="hostPortBlob"></param> | |
/// <param name="hostPortQueue"></param> | |
/// <param name="hostPortTable"></param> | |
/// <param name="storageAccountConnectionString"></param> | |
/// <param name="storageBlobContainerName"></param> | |
/// <returns></returns> | |
public static async Task<string> StartContainerAsync(string dockerContainerName, string storagePathLocalFileSystem, string hostPortBlob, string hostPortQueue, string hostPortTable, string storageAccountConnectionString, string storageBlobContainerName) | |
{ | |
//create directory for local storage | |
if (!Directory.Exists(storagePathLocalFileSystem)) | |
{ | |
Directory.CreateDirectory(storagePathLocalFileSystem); | |
} | |
var _dockerClient = new DockerClientConfiguration(_localHost).CreateClient(); | |
var containerId = string.Empty; | |
var containers = await FindContainerAsync(dockerContainerName, _dockerClient); | |
if (!containers.Any()) | |
{ | |
//create the container | |
var container = await _dockerClient.Containers.CreateContainerAsync( | |
new CreateContainerParameters | |
{ | |
Name = dockerContainerName, | |
Image = _dockerImageName, | |
Volumes = new Dictionary<string, EmptyStruct> | |
{ | |
{ | |
storagePathLocalFileSystem, new EmptyStruct() | |
} | |
}, | |
ExposedPorts = new Dictionary<string, EmptyStruct> | |
{ | |
{ | |
_containerPortBlob, new EmptyStruct() | |
}, | |
{ | |
_containerPortTable, new EmptyStruct() | |
}, | |
{ | |
_containerPortQueue, new EmptyStruct() | |
} | |
}, | |
HostConfig = new HostConfig | |
{ | |
//bind local storage to internal storage | |
Binds = new List<string>() { $"{storagePathLocalFileSystem}:/opt/azurite/folder" }, | |
PortBindings = new Dictionary<string, IList<PortBinding>> | |
{ | |
{ | |
_containerPortBlob, new List<PortBinding> | |
{ | |
new PortBinding | |
{ | |
HostPort = hostPortBlob | |
} | |
} | |
}, | |
{ | |
_containerPortTable, new List<PortBinding> | |
{ | |
new PortBinding | |
{ | |
HostPort = hostPortTable | |
} | |
} | |
}, | |
{ | |
_containerPortQueue, new List<PortBinding> | |
{ | |
new PortBinding | |
{ | |
HostPort = hostPortQueue | |
} | |
} | |
} | |
} | |
} | |
}); | |
await _dockerClient.Containers.StartContainerAsync(container.ID, new ContainerStartParameters()); | |
containerId = container.ID; | |
//add storage container | |
CloudBlobContainer cloudBlobContainer = null; | |
if (CloudStorageAccount.TryParse(storageAccountConnectionString, out var storageAccount)) | |
{ | |
// Create the CloudBlobClient that represents the Blob storage endpoint for the storage account. | |
var cloudBlobClient = storageAccount.CreateCloudBlobClient(); | |
cloudBlobContainer = cloudBlobClient.GetContainerReference(storageBlobContainerName); | |
if (!await cloudBlobContainer.CreateIfNotExistsAsync()) | |
{ | |
throw new Exception($"Could not create blob container {storageBlobContainerName}"); | |
} | |
} | |
else | |
{ | |
throw new Exception($"Could not create blob container, could not parse connection string {storageBlobContainerName}"); | |
} | |
} | |
else | |
{ | |
if ("running" != containers[0].State) | |
{ | |
await _dockerClient.Containers.StartContainerAsync(containers[0].ID, new ContainerStartParameters()); | |
} | |
containerId = containers[0].ID; | |
} | |
return containerId; | |
} | |
/// <summary> | |
/// Stop container | |
/// </summary> | |
/// <param name="dockerContainerName"></param> | |
/// <returns></returns> | |
public static async Task StopContainerAsync(string dockerContainerName) | |
{ | |
var _dockerClient = new DockerClientConfiguration(_localHost).CreateClient(); | |
var containers = await FindContainerAsync(dockerContainerName, _dockerClient); | |
if (containers.Any()) | |
{ | |
if ("running" == containers[0].State) | |
{ | |
await _dockerClient.Containers.StopContainerAsync(containers[0].ID, new ContainerStopParameters()); | |
} | |
} | |
} | |
/// <summary> | |
/// Deletes a container and local resources | |
/// </summary> | |
/// <param name="dockerContainerName"></param> | |
/// <param name="storagePathLocalFileSystem"></param> | |
/// <returns></returns> | |
public static async Task<string> DeleteContainerAsync(string dockerContainerName, string storagePathLocalFileSystem) | |
{ | |
var _dockerClient = new DockerClientConfiguration(_localHost).CreateClient(); | |
var containerId = string.Empty; | |
var containers = await FindContainerAsync(dockerContainerName, _dockerClient); | |
if (containers.Any()) | |
{ | |
await _dockerClient.Containers.RemoveContainerAsync(containers[0].ID, new ContainerRemoveParameters() { Force = true }); | |
//create directory for local storage | |
if (Directory.Exists(storagePathLocalFileSystem)) | |
{ | |
Directory.Delete(storagePathLocalFileSystem, true); | |
} | |
} | |
return containerId; | |
} | |
/// <summary> | |
/// Find container based on name | |
/// </summary> | |
/// <param name="dockerContainerName"></param> | |
/// <param name="_dockerClient"></param> | |
/// <returns></returns> | |
private static async Task<IList<ContainerListResponse>> FindContainerAsync(string dockerContainerName, DockerClient _dockerClient) | |
{ | |
return await _dockerClient.Containers.ListContainersAsync( | |
new ContainersListParameters() | |
{ | |
All = true, | |
Filters = new Dictionary<string, IDictionary<string, bool>> | |
{ | |
{ | |
"name", new Dictionary<string, bool> | |
{ | |
{ dockerContainerName, true } | |
} | |
} | |
} as IDictionary<string, IDictionary<string, bool>> | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment