Skip to content

Commit

Permalink
Merge pull request #153 from SeanFeldman/develop
Browse files Browse the repository at this point in the history
Release 6.0.0
  • Loading branch information
SeanFeldman authored Nov 12, 2019
2 parents 5a8ae31 + 2145568 commit af1a862
Show file tree
Hide file tree
Showing 25 changed files with 135 additions and 117 deletions.
File renamed without changes.
58 changes: 45 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<!--
This file was generate by MarkdownSnippets.
GENERATED FILE - DO NOT EDIT
This file was generated by [MarkdownSnippets](https://github.com/SimonCropp/MarkdownSnippets).
Source File: /README.source.md
To change this file edit the source file and then re-run the generation using either the dotnet global tool (https://github.com/SimonCropp/MarkdownSnippets#markdownsnippetstool) or using the api (https://github.com/SimonCropp/MarkdownSnippets#running-as-a-unit-test).
To change this file edit the source file and then run MarkdownSnippets.
-->

![Icon](https://github.com/SeanFeldman/ServiceBus.AttachmentPlugin/blob/master/images/project-icon.png)

### This is a plugin for [Microsoft.Azure.ServiceBus client](https://github.com/Azure/azure-service-bus-dotnet/)
Expand All @@ -23,24 +25,45 @@ To Install from the Nuget Package Manager Console

PM> Install-Package ServiceBus.AttachmentPlugin

<!-- toc -->
## Contents

* [Examples](#examples)
* [Convert body into attachment, no matter how big it is](#convert-body-into-attachment-no-matter-how-big-it-is)
* [Sending a message without exposing the storage account to receivers](#sending-a-message-without-exposing-the-storage-account-to-receivers)
* [Configure blob container name](#configure-blob-container-name)
* [Configure message property to identify attachment blob](#configure-message-property-to-identify-attachment-blob)
* [Configure message property for SAS uri to attachment blob](#configure-message-property-for-sas-uri-to-attachment-blob)
* [Configure criteria for message max size identification](#configure-criteria-for-message-max-size-identification)
* [Configuring connection string provider](#configuring-connection-string-provider)
* [Configuring plugin using StorageCredentials (Service or Container SAS)](#configuring-plugin-using-storagecredentials-service-or-container-sas)
* [Using attachments with Azure Functions](#using-attachments-with-azure-functions)
* [Cleanup](#cleanup)
* [Who's trusting this plugin in production](#whos-trusting-this-plugin-in-production)
* [Icon](#icon)
<!-- endtoc -->


## Examples

### Convert body into attachment, no matter how big it is

Configuration and registration

<!-- snippet: ConfigurationAndRegistration -->
<a id='snippet-configurationandregistration'/></a>
```cs
var sender = new MessageSender(connectionString, queueName);
var config = new AzureStorageAttachmentConfiguration(storageConnectionString);
sender.RegisterAzureStorageAttachmentPlugin(config);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L14-L20)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L14-L20) / [anchor](#snippet-configurationandregistration)</sup>
<!-- endsnippet -->

Sending

<!-- snippet: AttachmentSending -->
<a id='snippet-attachmentsending'/></a>
```cs
var payload = new MyMessage
{
Expand All @@ -50,26 +73,28 @@ var serialized = JsonConvert.SerializeObject(payload);
var payloadAsBytes = Encoding.UTF8.GetBytes(serialized);
var message = new Message(payloadAsBytes);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L26-L36)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L26-L36) / [anchor](#snippet-attachmentsending)</sup>
<!-- endsnippet -->

Receiving

<!-- snippet: AttachmentReceiving -->
<a id='snippet-attachmentreceiving'/></a>
```cs
var receiver = new MessageReceiver(connectionString, entityPath, ReceiveMode.ReceiveAndDelete);
receiver.RegisterAzureStorageAttachmentPlugin(config);
var message = await receiver.ReceiveAsync().ConfigureAwait(false);
// message will contain the original payload
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L42-L49)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L42-L49) / [anchor](#snippet-attachmentreceiving)</sup>
<!-- endsnippet -->

### Sending a message without exposing the storage account to receivers

Configuration and registration with blob SAS URI

<!-- snippet: ConfigurationAndRegistrationSas -->
<a id='snippet-configurationandregistrationsas'/></a>
```cs
var sender = new MessageSender(connectionString, queueName);
var config = new AzureStorageAttachmentConfiguration(storageConnectionString)
Expand All @@ -78,12 +103,13 @@ var config = new AzureStorageAttachmentConfiguration(storageConnectionString)
messagePropertyToIdentifySasUri: "mySasUriProperty");
sender.RegisterAzureStorageAttachmentPlugin(config);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L54-L63)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L54-L63) / [anchor](#snippet-configurationandregistrationsas)</sup>
<!-- endsnippet -->

Sending

<!-- snippet: AttachmentSendingSas -->
<a id='snippet-attachmentsendingsas'/></a>
```cs
var payload = new MyMessage
{
Expand All @@ -93,19 +119,20 @@ var serialized = JsonConvert.SerializeObject(payload);
var payloadAsBytes = Encoding.UTF8.GetBytes(serialized);
var message = new Message(payloadAsBytes);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L69-L79)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L69-L79) / [anchor](#snippet-attachmentsendingsas)</sup>
<!-- endsnippet -->

Receiving only mode (w/o Storage account credentials)

<!-- snippet: AttachmentReceivingSas -->
<a id='snippet-attachmentreceivingsas'/></a>
```cs
// Override message property used to identify SAS URI
// .RegisterAzureStorageAttachmentPluginForReceivingOnly() is using "$attachment.sas.uri" by default
messageReceiver.RegisterAzureStorageAttachmentPluginForReceivingOnly("mySasUriProperty");
var message = await messageReceiver.ReceiveAsync().ConfigureAwait(false);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L85-L92)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L85-L92) / [anchor](#snippet-attachmentreceivingsas)</sup>
<!-- endsnippet -->

### Configure blob container name
Expand Down Expand Up @@ -137,12 +164,13 @@ new AzureStorageAttachmentConfiguration(storageConnectionString).WithSasUri(mess
Default is to convert any body to attachment.

<!-- snippet: Configure_criteria_for_message_max_size_identification -->
<a id='snippet-configure_criteria_for_message_max_size_identification'/></a>
```cs
// messages with body > 200KB should be converted to use attachments
new AzureStorageAttachmentConfiguration(storageConnectionString,
messageMaxSizeReachedCriteria: message => message.Body.Length > 200 * 1024);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L97-L103)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L97-L103) / [anchor](#snippet-configure_criteria_for_message_max_size_identification)</sup>
<!-- endsnippet -->

### Configuring connection string provider
Expand All @@ -151,21 +179,23 @@ When Storage connection string needs to be retrieved rather than passed in as a
The plugin comes with a `PlainTextConnectionStringProvider` and can be used in the following way.

<!-- snippet: Configuring_connection_string_provider -->
<a id='snippet-configuring_connection_string_provider'/></a>
```cs
var provider = new PlainTextConnectionStringProvider(connectionString);
var config = new AzureStorageAttachmentConfiguration(provider);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L109-L114)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L109-L114) / [anchor](#snippet-configuring_connection_string_provider)</sup>
<!-- endsnippet -->

### Configuring plugin using StorageCredentials (Service or Container SAS)

<!-- snippet: Configuring_plugin_using_StorageCredentials -->
<a id='snippet-configuring_plugin_using_storagecredentials'/></a>
```cs
var credentials = new StorageCredentials( /*Shared key OR Service SAS OR Container SAS*/);
var config = new AzureStorageAttachmentConfiguration(credentials, blobEndpoint);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L120-L125)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L120-L125) / [anchor](#snippet-configuring_plugin_using_storagecredentials)</sup>
<!-- endsnippet -->

See [`StorageCredentials`](https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.auth.storagecredentials) for more details.
Expand All @@ -179,16 +209,18 @@ To use the extensions, your Function must return (send) or take as parameter (re
Upload attachment to Azure Storage blob

<!-- snippet: Upload_attachment_without_registering_plugin -->
<a id='snippet-upload_attachment_without_registering_plugin'/></a>
```cs
//To make it possible to use SAS URI when downloading, use WithBlobSasUri() when creating configuration object
await message.UploadAzureStorageAttachment(config);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L130-L135)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L130-L135) / [anchor](#snippet-upload_attachment_without_registering_plugin)</sup>
<!-- endsnippet -->

Download attachment from Azure Storage blob

<!-- snippet: Download_attachment_without_registering_plugin -->
<a id='snippet-download_attachment_without_registering_plugin'/></a>
```cs
//Using SAS URI with default message property ($attachment.sas.uri)
await message.DownloadAzureStorageAttachment();
Expand All @@ -199,7 +231,7 @@ await message.DownloadAzureStorageAttachment("$custom-attachment.sas.uri");
//Using configuration object
await message.DownloadAzureStorageAttachment(config);
```
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L139-L150)</sup>
<sup>[snippet source](/src/ServiceBus.AttachmentPlugin.Tests/Snippets.cs#L139-L150) / [anchor](#snippet-download_attachment_without_registering_plugin)</sup>
<!-- endsnippet -->

#### Additional providers
Expand Down
2 changes: 2 additions & 0 deletions README.source.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ To Install from the Nuget Package Manager Console

PM> Install-Package ServiceBus.AttachmentPlugin

toc

## Examples

### Convert body into attachment, no matter how big it is
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ skip_commits:
- images/*
matrix:
fast_finish: true
image: Previous Visual Studio 2017 #Visual Studio 2017 #use workaround image until https://github.com/appveyor/ci/issues/1404 is resolved
image: Visual Studio 2019
environment:
matrix:
# First build
- DotNetRunTime: net461
# Second build
- DotNetRunTime: netcoreapp2.1
- DotNetRunTime: netcoreapp3.0

# ensure Azure Storage emulator 5.9 is installed
install:
Expand Down
3 changes: 2 additions & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>
7 changes: 5 additions & 2 deletions src/ServiceBus.AttachmentPlugin.Tests/ApiApprovals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ public class ApiApprovals
public void AzureStorageAttachmentPlugin()
{
var publicApi = ApiGenerator.GeneratePublicApi(typeof(AzureStorageAttachment).Assembly,
whitelistedNamespacePrefixes: new[] { "Microsoft.Azure.ServiceBus." },
excludeAttributes: new[] { "System.Runtime.Versioning.TargetFrameworkAttribute" });
new ApiGeneratorOptions
{
WhitelistedNamespacePrefixes = new[] {"Microsoft.Azure.ServiceBus."},
ExcludeAttributes = new[] {"System.Runtime.Versioning.TargetFrameworkAttribute"}
});

Approver.Verify(publicApi);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute(@"ServiceBus.AttachmentPlugin.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5a2fefe7a1f74bb526125b1630af3f5e30b3961640926ea3b20cdb9a803487af798b02fd52a8d265c3fe7174027dd3f738f0e24213cb26b21189ada2d85d74a3cd2c944c7e57c76c5cba3aa45928fc3c300f9744cfaab92c24ac98d15ec2fe05c0500121be04644881448dd06f15f5cd5a4db3dbb8e9d78e63436045bbe8db5")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"ServiceBus.AttachmentPlugin.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5a2fefe7a1f74bb526125b1630af3f5e30b3961640926ea3b20cdb9a803487af798b02fd52a8d265c3fe7174027dd3f738f0e24213cb26b21189ada2d85d74a3cd2c944c7e57c76c5cba3aa45928fc3c300f9744cfaab92c24ac98d15ec2fe05c0500121be04644881448dd06f15f5cd5a4db3dbb8e9d78e63436045bbe8db5")]
namespace Microsoft.Azure.ServiceBus
{
public class AzureStorageAttachmentConfiguration
{
public AzureStorageAttachmentConfiguration(string connectionString, string containerName = "attachments", string messagePropertyToIdentifyAttachmentBlob = "$attachment.blob", System.Func<Microsoft.Azure.ServiceBus.Message, bool> messageMaxSizeReachedCriteria = null) { }
public AzureStorageAttachmentConfiguration(Microsoft.WindowsAzure.Storage.Auth.StorageCredentials storageCredentials, string blobEndpoint, string containerName = "attachments", string messagePropertyToIdentifyAttachmentBlob = "$attachment.blob", System.Func<Microsoft.Azure.ServiceBus.Message, bool> messageMaxSizeReachedCriteria = null) { }
public AzureStorageAttachmentConfiguration(Microsoft.Azure.ServiceBus.IProvideStorageConnectionString connectionStringProvider, string containerName = "attachments", string messagePropertyToIdentifyAttachmentBlob = "$attachment.blob", System.Func<Microsoft.Azure.ServiceBus.Message, bool> messageMaxSizeReachedCriteria = null) { }
public AzureStorageAttachmentConfiguration(string connectionString, string containerName = "attachments", string messagePropertyToIdentifyAttachmentBlob = "$attachment.blob", System.Func<Microsoft.Azure.ServiceBus.Message, bool>? messageMaxSizeReachedCriteria = null) { }
public AzureStorageAttachmentConfiguration(Microsoft.Azure.Storage.Auth.StorageCredentials storageCredentials, string blobEndpoint, string containerName = "attachments", string messagePropertyToIdentifyAttachmentBlob = "$attachment.blob", System.Func<Microsoft.Azure.ServiceBus.Message, bool>? messageMaxSizeReachedCriteria = null) { }
public AzureStorageAttachmentConfiguration(Microsoft.Azure.ServiceBus.IProvideStorageConnectionString connectionStringProvider, string containerName = "attachments", string messagePropertyToIdentifyAttachmentBlob = "$attachment.blob", System.Func<Microsoft.Azure.ServiceBus.Message, bool>? messageMaxSizeReachedCriteria = null) { }
}
public class static AzureStorageAttachmentConfigurationExtensions
public static class AzureStorageAttachmentConfigurationExtensions
{
public static Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration WithBlobSasUri(this Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration azureStorageAttachmentConfiguration, string messagePropertyToIdentifySasUri = "$attachment.sas.uri", System.Nullable<System.TimeSpan> sasTokenValidationTime = null) { }
[System.ObsoleteAttribute("Will be removed in version 6. Use replacement API \'.WithBlobSasUri()\' instead.", true)]
public static Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration WithSasUri(this Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration azureStorageAttachmentConfiguration, string messagePropertyToIdentifySasUri = "$attachment.sas.uri", System.Nullable<System.TimeSpan> sasTokenValidationTime = null) { }
public static Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration WithBlobSasUri(this Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration azureStorageAttachmentConfiguration, string messagePropertyToIdentifySasUri = "$attachment.sas.uri", System.TimeSpan? sasTokenValidationTime = default) { }
}
public class static AzureStorageAttachmentExtensions
public static class AzureStorageAttachmentExtensions
{
public static Microsoft.Azure.ServiceBus.Core.ServiceBusPlugin RegisterAzureStorageAttachmentPlugin(this Microsoft.Azure.ServiceBus.ClientEntity client, Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration configuration) { }
public static Microsoft.Azure.ServiceBus.Core.ServiceBusPlugin RegisterAzureStorageAttachmentPlugin(this Microsoft.Azure.ServiceBus.IClientEntity client, Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration configuration) { }
public static Microsoft.Azure.ServiceBus.Core.ServiceBusPlugin RegisterAzureStorageAttachmentPluginForReceivingOnly(this Microsoft.Azure.ServiceBus.ClientEntity client, string messagePropertyToIdentifySasUri = "$attachment.sas.uri") { }
public static Microsoft.Azure.ServiceBus.Core.ServiceBusPlugin RegisterAzureStorageAttachmentPluginForReceivingOnly(this Microsoft.Azure.ServiceBus.IClientEntity client, string messagePropertyToIdentifySasUri = "$attachment.sas.uri") { }
}
public interface IProvideStorageConnectionString
{
System.Threading.Tasks.Task<string> GetConnectionString();
}
public class static MessageExtensions
public static class MessageExtensions
{
public static System.Threading.Tasks.Task<Microsoft.Azure.ServiceBus.Message> DownloadAzureStorageAttachment(this Microsoft.Azure.ServiceBus.Message message, Microsoft.Azure.ServiceBus.AzureStorageAttachmentConfiguration configuration) { }
public static System.Threading.Tasks.Task<Microsoft.Azure.ServiceBus.Message> DownloadAzureStorageAttachment(this Microsoft.Azure.ServiceBus.Message message, string messagePropertyToIdentifySasUri = "$attachment.sas.uri") { }
Expand Down
12 changes: 6 additions & 6 deletions src/ServiceBus.AttachmentPlugin.Tests/ApprovalFiles/Approver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ static string TestDirectory
{
get
{
var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly()!.CodeBase!);
var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
var dirPath = Path.GetDirectoryName(codeBasePath);
return Path.Combine(dirPath, "..", "..", "..", "ApprovalFiles");
return Path.Combine(dirPath!, "..", "..", "..", "ApprovalFiles");
}
}

Expand All @@ -44,13 +44,13 @@ static Approver()
/// <param name="value">The string to verify.</param>
/// <param name="scrubber">A delegate that modifies the received string before comparing it to the approval file.</param>
/// <param name="scenario">A value that will be added to the name of the approval file.</param>
public static void Verify(string value, Func<string, string> scrubber = null, string scenario = null)
public static void Verify(string value, Func<string, string>? scrubber = default, string? scenario = default)
{
var st = new StackTrace();
var sf = st.GetFrame(1);
var currentMethodName = sf.GetMethod();
var currentMethodName = sf!.GetMethod();

var className = currentMethodName.DeclaringType.Name;
var className = currentMethodName!.DeclaringType!.Name;
var methodName = currentMethodName.Name;
var scenarioName = string.IsNullOrEmpty(scenario) ? "" : scenario + ".";

Expand Down Expand Up @@ -79,7 +79,7 @@ public static void Verify(string value, Func<string, string> scrubber = null, st
/// <param name="value">The object to verify.</param>
/// <param name="scrubber">A delegate that modifies the received object, after it has been serialized, before comparing it to the approval file.</param>
/// <param name="scenario">A value that will be added to the name of the approval file.</param>
public static void Verify(object value, Func<string, string> scrubber = null, string scenario = null)
public static void Verify(object value, Func<string, string>? scrubber = default, string? scenario = default)
{
var json = JsonConvert.SerializeObject(value, jsonSerializerSettings);

Expand Down
Loading

0 comments on commit af1a862

Please sign in to comment.