Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes issue with non-prod like Azurite urls #201

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
bin/
obj/
.vs/

.DS_Store
**/wwwroot/dist/
!**/**/wwwroot/dist/azurewebexplorer.css
**/Properties/launchSettings.json
Expand All @@ -12,5 +12,4 @@ obj/
__azurite*.json
private*.data

.DS_Store
azurestorageexplorer.sln
23 changes: 22 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,28 @@
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
//"AZURE_STORAGE_CONNECTIONSTRING": "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://localhost:10000/devstoreaccount1;QueueEndpoint=http://localhost:10001/devstoreaccount1;TableEndpoint=http://localhost:10002/devstoreaccount1;"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": "Blazor WEB (Azurite)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-and-azurite",
"program": "${workspaceFolder}/src/web/bin/Debug/net8.0/web.dll",
"args": [],
"cwd": "${workspaceFolder}/src/web",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"AZURE_STORAGE_CONNECTIONSTRING": "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://localhost:10000/devstoreaccount1;QueueEndpoint=http://localhost:10001/devstoreaccount1;TableEndpoint=http://localhost:10002/devstoreaccount1;",
"AZURITE": "true"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
Expand Down
9 changes: 9 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
],
"problemMatcher": "$msCompile"
},
{
"label": "azurite",
"command": "./azurite.sh"
},
{
"label": "build-and-azurite",
"dependsOrder": "sequence",
"dependsOn": ["build", "azurite"]
},
{
"label": "publish",
"command": "dotnet",
Expand Down
18 changes: 18 additions & 0 deletions azurite.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

CONTAINER_NAME="azurite"
IMAGE_NAME="mcr.microsoft.com/azure-storage/azurite"

Check if the container is already running
if [ "$(docker ps -q -f name=${CONTAINER_NAME})" ]; then
echo "Container ${CONTAINER_NAME} is already running."
else
# Check if the container exists but is stopped
if [ "$(docker ps -aq -f status=exited -f name=${CONTAINER_NAME})" ]; then
echo "Starting existing container ${CONTAINER_NAME}."
docker start ${CONTAINER_NAME}
else
echo "Running a new container named ${CONTAINER_NAME}."
docker run -d -p 10000:10000 -p 10001:10001 -p 10002:10002 --name ${CONTAINER_NAME} ${IMAGE_NAME}
fi
fi
3 changes: 2 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
cd "${0%/*}" || exit 1
#!/bin/bash

dotnet build ./src/web/web.csproj
3 changes: 2 additions & 1 deletion docker-build.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
cd "${0%/*}" || exit 1
#!/bin/bash

docker build --tag azurestorageexplorer:local ./src
3 changes: 1 addition & 2 deletions docker-compose/azurestorageexplorer.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3.8'

services:
azurite:
image: mcr.microsoft.com/azure-storage/azurite
Expand All @@ -14,5 +12,6 @@ services:
- "8080:8080"
environment:
- AZURE_STORAGE_CONNECTIONSTRING=DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://azurite:10000/devstoreaccount1;QueueEndpoint=http://azurite:10001/devstoreaccount1;TableEndpoint=http://azurite:10002/devstoreaccount1;
- AZURITE=true
depends_on:
- azurite
2 changes: 1 addition & 1 deletion docker-run.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cd "${0%/*}" || exit 1
#!/bin/bash

echo App will run on http://localhost:8080

Expand Down
40 changes: 40 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
default:
@just --list

# Build the solution
build:
dotnet build ./src/web/web.csproj

# Publish and launches in localhost:5000
publish:
#!/bin/bash
dotnet publish --configuration Release -o ./bin ./src/web/web.csproj

OK=$?
if [ $OK -eq 0 ]; then
echo Azure Storage Explorer will be running in http://localhost:5000/
cd bin
dotnet web.dll
cd ..
fi

# Run unit tests
test:
dotnet test ./tests/StorageLibTests/StorageLibTests.csproj

# Build Docker image as azurestorageexplorer:local
db:
docker build --tag azurestorageexplorer:local ./src

# Launches the local docker image at http://localhost:8080
dr:
echo App will run on http://localhost:8080
docker run --rm -p 8080:8080 --name azurestorageexplorer azurestorageexplorer:local

compose:
docker-compose -f ./docker-compose/azurestorageexplorer.yaml up

uncompose:
docker-compose -f ./docker-compose/azurestorageexplorer.yaml down


2 changes: 1 addition & 1 deletion publish.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cd "${0%/*}" || exit 1
#!/bin/bash

dotnet publish --configuration Release -o ./bin ./src/web/web.csproj

Expand Down
2 changes: 1 addition & 1 deletion src/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 as builder
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder

WORKDIR /src
COPY ./ /src
Expand Down
8 changes: 4 additions & 4 deletions src/StorageLibrary/AzureContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace StorageLibrary
{
internal class AzureContainer : StorageObject, IContainer
{
public AzureContainer(string account, string key, string endpoint, string connectionString)
: base(account, key, endpoint, connectionString) { }
public AzureContainer(StorageFactoryConfig config)
: base(config) { }

public async Task<List<CloudBlobContainerWrapper>> ListContainersAsync()
{
Expand Down Expand Up @@ -45,11 +45,11 @@ public async Task<List<BlobItemWrapper>> ListBlobsAsync(string containerName, st
{
BlobClient blobClient = container.GetBlobClient(blobItem.Blob.Name);

wrapper = new BlobItemWrapper(blobClient.Uri.AbsoluteUri, blobItem.Blob.Properties.ContentLength);
wrapper = new BlobItemWrapper(blobClient.Uri.AbsoluteUri, blobItem.Blob.Properties.ContentLength.HasValue ? blobItem.Blob.Properties.ContentLength.Value : 0, IsAzurite);
}
else if (blobItem.IsPrefix)
{
wrapper = new BlobItemWrapper($"{container.Uri}/{blobItem.Prefix}", 0);
wrapper = new BlobItemWrapper($"{container.Uri}/{blobItem.Prefix}", 0, IsAzurite);
}

if (wrapper != null && !results.Contains(wrapper))
Expand Down
4 changes: 2 additions & 2 deletions src/StorageLibrary/AzureFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ namespace StorageLibrary
{
internal class AzureFile : StorageObject, IFile
{
public AzureFile(string account, string key, string endpoint, string connectionString)
: base(account, key, endpoint, connectionString) { }
public AzureFile(StorageFactoryConfig config)
: base(config) { }

public async Task<List<FileShareWrapper>> ListFileSharesAsync()
{
Expand Down
5 changes: 3 additions & 2 deletions src/StorageLibrary/AzureQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace StorageLibrary
{
internal class AzureQueue : StorageObject, IQueue
{
public AzureQueue(string account, string key, string endpoint, string connectionString)
: base(account, key, endpoint, connectionString) { }
public AzureQueue(StorageFactoryConfig config)
: base(config) { }

public async Task<List<QueueWrapper>> ListQueuesAsync()
{
QueueServiceClient client = new QueueServiceClient(ConnectionString);
Expand Down
4 changes: 2 additions & 2 deletions src/StorageLibrary/AzureTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ namespace StorageLibrary
{
internal class AzureTable : StorageObject, ITable
{
public AzureTable(string account, string key, string endpoint, string connectionString)
: base(account, key, endpoint, connectionString) { }
public AzureTable(StorageFactoryConfig config)
: base(config) { }

public async Task<List<TableWrapper>> ListTablesAsync()
{
Expand Down
30 changes: 13 additions & 17 deletions src/StorageLibrary/Common/BlobItemWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,18 @@ namespace StorageLibrary.Common
public class BlobItemWrapper : IEquatable<BlobItemWrapper>, IComparable<BlobItemWrapper>
{
Uri m_internalUri;
public string Name { get => HttpUtility.UrlDecode(m_internalUri.Segments[m_internalUri.Segments.Length - 1]); }
public string Path
{
get
{
int containerPos = m_internalUri.LocalPath.IndexOf(Container) + Container.Length;

return m_internalUri.LocalPath.Substring(containerPos, (m_internalUri.LocalPath.Length) - (containerPos) - Name.Length);
}
}

public string Container { get => IsAzurite ? m_internalUri.Segments[2] : m_internalUri.Segments[1]; }
bool m_isAzurite = false;
public string Name { get; private set; }
public string Path { get; private set; }
public string Container { get; private set; }
public string FullName { get => $"{Path}{Name}"; }
public bool IsFile { get => !m_internalUri.Segments[m_internalUri.Segments.Length - 1].EndsWith("/"); }
public bool IsFile { get; private set; }
public string Url
{
get { return m_internalUri.OriginalString; }
private set { m_internalUri = new Uri(value); }
}

public bool IsAzurite { get => m_internalUri.IsLoopback; }

public long Size { get; private set; }

public decimal SizeInKBs { get => (decimal)Size / 1024; }
Expand All @@ -36,10 +26,16 @@ public string Url

public BlobItemWrapper(string url) : this(url, 0) { }

public BlobItemWrapper(string url, long? size)
public BlobItemWrapper(string url, long size, bool fromAzurite = false)
{
Url = url;
Size = size.HasValue ? size.Value : 0;
Size = size;
m_isAzurite = fromAzurite;
IsFile = !m_internalUri.Segments[m_internalUri.Segments.Length - 1].EndsWith(System.IO.Path.AltDirectorySeparatorChar);
Container = m_isAzurite ? m_internalUri.Segments[2] : m_internalUri.Segments[1];
Name = HttpUtility.UrlDecode(m_internalUri.Segments[m_internalUri.Segments.Length - 1]);
int containerPos = m_internalUri.LocalPath.IndexOf(Container) + Container.Length;
Path = m_internalUri.LocalPath.Substring(containerPos, (m_internalUri.LocalPath.Length) - (containerPos) - Name.Length);
}

public int CompareTo(BlobItemWrapper other)
Expand Down
2 changes: 1 addition & 1 deletion src/StorageLibrary/Mocks/MockContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ await Task.Run(() =>
if (MockUtils.FolderStructure[containerName].Contains(blobName))
throw new InvalidOperationException($"Blob '{blobName}' already exists in Container '{containerName}'");

BlobItemWrapper blob = new BlobItemWrapper($"{MockUtils.FAKE_URL}/{containerName}/{blobName}");
BlobItemWrapper blob = StorageFactory.GetBlobItemWrapper($"{MockUtils.FAKE_URL}/{containerName}/{blobName}");
if (!MockUtils.FolderStructure[containerName].Contains(blob.Path))
MockUtils.FolderStructure[containerName].Add(blob.Path);

Expand Down
35 changes: 29 additions & 6 deletions src/StorageLibrary/StorageFactory.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,49 @@

using StorageLibrary.Common;
using StorageLibrary.Interfaces;
using StorageLibrary.Mocks;

namespace StorageLibrary
{
public class StorageFactory
{
static StorageFactory Instance;

public IQueue Queues { get; private set; }
public IContainer Containers { get; set; }
public ITable Tables { get; set; }
public IFile Files { get; set; }

StorageFactoryConfig m_currentConfig;

public StorageFactory()
: this(string.Empty, string.Empty, string.Empty, string.Empty, true)
: this(new StorageFactoryConfig { Mock = true })
{ }

public StorageFactory(string account, string key, string endpoint, string connectionString, bool mock = false)
public StorageFactory(StorageFactoryConfig config)
{
Queues = mock ? new MockQueue() : new AzureQueue(account, key, endpoint, connectionString);
Containers = mock ? new MockContainer() : new AzureContainer(account, key, endpoint, connectionString);
Tables = mock ? new MockTable() : new AzureTable(account, key, endpoint, connectionString);
Files = mock ? new MockFile() : new AzureFile(account, key, endpoint, connectionString);
m_currentConfig = config;
Queues = config.Mock ? new MockQueue() : new AzureQueue(config);
Containers = config.Mock ? new MockContainer() : new AzureContainer(config);
Tables = config.Mock ? new MockTable() : new AzureTable(config);
Files = config.Mock ? new MockFile() : new AzureFile(config);

Instance = this;
}

public static BlobItemWrapper GetBlobItemWrapper(string url, long size = 0)
{
return new BlobItemWrapper(url, size, Instance.m_currentConfig.IsAzurite);
}
}

public class StorageFactoryConfig
{
public string Account { get; set; }
public string Key { get; set; }
public string Endpoint { get; set; } = "core.windows.net";
public string ConnectionString { get; set; }
public bool IsAzurite { get; set; }
public bool Mock { get; set; }
}
}
9 changes: 8 additions & 1 deletion src/StorageLibrary/StorageObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ internal class StorageObject
public string Endpoint { get; private set; } = "core.windows.net";
public string ConnectionString { get; private set; }

public bool IsAzurite { get; private set; }

const string CONNSTRING_TEMPLATE = "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}";
public StorageObject(string account, string key, string endpoint, string connectionString)

public StorageObject(StorageFactoryConfig config)
: this(config.Account, config.Key, config.Endpoint, config.ConnectionString, config.IsAzurite){ }

public StorageObject(string account, string key, string endpoint, string connectionString, bool azurite)
{
IsAzurite = azurite;
if (!string.IsNullOrEmpty(connectionString))
{
ConnectionString = connectionString;
Expand Down
2 changes: 1 addition & 1 deletion src/web/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<AzureStorageWebExplorerVersion>2.17.0</AzureStorageWebExplorerVersion>
<AzureStorageWebExplorerVersion>2.17.1</AzureStorageWebExplorerVersion>
</PropertyGroup>
</Project>
Loading
Loading