Skip to content
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
1 change: 1 addition & 0 deletions eng/.docsettings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ known_content_issues:
- ['sdk/core/Microsoft.Azure.Core.NewtonsoftJson/README.md', '#15423']
- ['sdk/core/Microsoft.Azure.Core.Spatial/README.md', '#15423']
- ['sdk/core/Microsoft.Azure.Core.Spatial.NewtonsoftJson/README.md', '#15423']
- ['sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/README.md', '#15423']

# .net climbs upwards. placing these to prevent assigning readmes to the wrong project
package_indexing_exclusion_list:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Release History

## 5.0.0-beta.1 (Unreleased)

- The initial release of Microsoft.Azure.WebJobs.Extensions.ServiceBus 5.0.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IsClientLibrary>true</IsClientLibrary>
</PropertyGroup>

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.props))\Directory.Build.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30804.86
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.ServiceBus", "src\Microsoft.Azure.WebJobs.Extensions.ServiceBus.csproj", "{2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.ServiceBus.Tests", "tests\Microsoft.Azure.WebJobs.Extensions.ServiceBus.Tests.csproj", "{564B3907-57C9-456A-9C7B-C6D876B24479}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}.Release|Any CPU.Build.0 = Release|Any CPU
{564B3907-57C9-456A-9C7B-C6D876B24479}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{564B3907-57C9-456A-9C7B-C6D876B24479}.Debug|Any CPU.Build.0 = Debug|Any CPU
{564B3907-57C9-456A-9C7B-C6D876B24479}.Release|Any CPU.ActiveCfg = Release|Any CPU
{564B3907-57C9-456A-9C7B-C6D876B24479}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {371BFA14-0980-4A43-A18A-CA1C1A9CB784}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Azure WebJobs Service Bus client library for .NET

This extension provides functionality for accessing Azure Service Bus from an Azure Function.

## Getting started

### Install the package

### Prerequisites


### Authenticate the Client

#### Managed identity authentication


## Key concepts


## Examples


## Troubleshooting


## Next steps


## Contributing

See our [CONTRIBUTING.md][contrib] for details on building,
testing, and contributing to this library.

This project welcomes contributions and suggestions. Most contributions require
you to agree to a Contributor License Agreement (CLA) declaring that you have
the right to, and actually do, grant us the rights to use your contribution. For
details, visit [cla.microsoft.com][cla].

This project has adopted the [Microsoft Open Source Code of Conduct][coc].
For more information see the [Code of Conduct FAQ][coc_faq]
or contact [opencode@microsoft.com][coc_contact] with any
additional questions or comments.

![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-net%2Fsdk%2Fservicebus%2FMicrosoft.Azure.WebJobs.Extensions.ServiceBus%2FREADME.png)

<!-- LINKS -->
[source]: https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src
[package]: https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.ServiceBus/
[docs]: https://docs.microsoft.com/dotnet/api/Microsoft.Azure.WebJobs.Extensions.ServiceBus
[nuget]: https://www.nuget.org/

[contrib]: https://github.com/Azure/azure-sdk-for-net/tree/master/CONTRIBUTING.md
[cla]: https://cla.microsoft.com
[coc]: https://opensource.microsoft.com/codeofconduct/
[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/
[coc_contact]: mailto:opencode@microsoft.com
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.WebJobs.Host.Bindings;
using Microsoft.Azure.WebJobs.Host.Converters;

namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
{
internal class AsyncCollectorArgumentBindingProvider : IQueueArgumentBindingProvider
{
public IArgumentBinding<ServiceBusEntity> TryCreate(ParameterInfo parameter)
{
Type parameterType = parameter.ParameterType;

if (!parameterType.IsGenericType)
{
return null;
}

Type genericTypeDefinition = parameterType.GetGenericTypeDefinition();

if (genericTypeDefinition != typeof(IAsyncCollector<>))
{
return null;
}

Type itemType = parameterType.GetGenericArguments()[0];
return CreateBinding(itemType);
}

private static IArgumentBinding<ServiceBusEntity> CreateBinding(Type itemType)
{
MethodInfo method = typeof(AsyncCollectorArgumentBindingProvider).GetMethod("CreateBindingGeneric",
BindingFlags.NonPublic | BindingFlags.Static);
Debug.Assert(method != null);
MethodInfo genericMethod = method.MakeGenericMethod(itemType);
Debug.Assert(genericMethod != null);
Func<IArgumentBinding<ServiceBusEntity>> lambda =
(Func<IArgumentBinding<ServiceBusEntity>>)Delegate.CreateDelegate(
typeof(Func<IArgumentBinding<ServiceBusEntity>>), genericMethod);
return lambda.Invoke();
}

private static IArgumentBinding<ServiceBusEntity> CreateBindingGeneric<TItem>()
{
return new AsyncCollectorArgumentBinding<TItem>(MessageConverterFactory.Create<TItem>());
}

private class AsyncCollectorArgumentBinding<TItem> : IArgumentBinding<ServiceBusEntity>
{
private readonly IConverter<TItem, Message> _converter;

public AsyncCollectorArgumentBinding(IConverter<TItem, Message> converter)
{
_converter = converter;
}

public Type ValueType
{
get { return typeof(IAsyncCollector<TItem>); }
}

public Task<IValueProvider> BindAsync(ServiceBusEntity value, ValueBindingContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

IAsyncCollector<TItem> collector = new MessageSenderAsyncCollector<TItem>(value, _converter,
context.FunctionInstanceId);
IValueProvider provider = new CollectorValueProvider(value, collector, typeof(IAsyncCollector<TItem>));

return Task.FromResult(provider);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.Azure.WebJobs.Host.Bindings;
using Microsoft.Azure.WebJobs.Host.Bindings.Path;

namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
{
/// <summary>
/// Utility class with factory method to create an instance of a strategy class implementing <see cref="IBindableServiceBusPath"/> interface.
/// </summary>
internal static class BindableServiceBusPath
{
/// <summary>
/// A factory method detecting parameters in supplied queue or topic name pattern and creating
/// an instance of relevant strategy class implementing <see cref="IBindableServiceBusPath"/>.
/// </summary>
/// <param name="queueOrTopicNamePattern">Service Bus queue or topic name pattern containing optional binding parameters.</param>
/// <returns>An object implementing <see cref="IBindableServiceBusPath"/></returns>
public static IBindableServiceBusPath Create(string queueOrTopicNamePattern)
{
if (queueOrTopicNamePattern == null)
{
throw new ArgumentNullException(nameof(queueOrTopicNamePattern));
}

BindingTemplate template = BindingTemplate.FromString(queueOrTopicNamePattern);

if (template.ParameterNames.Any())
{
return new ParameterizedServiceBusPath(template);
}

return new BoundServiceBusPath(queueOrTopicNamePattern);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
{
/// <summary>
/// Bindable queue or topic path strategy implementation for "degenerate" bindable patterns,
/// i.e. containing no parameters.
/// </summary>
internal class BoundServiceBusPath : IBindableServiceBusPath
{
private readonly string _queueOrTopicNamePattern;

public BoundServiceBusPath(string queueOrTopicNamePattern)
{
_queueOrTopicNamePattern = queueOrTopicNamePattern;
}

public string QueueOrTopicNamePattern
{
get { return _queueOrTopicNamePattern; }
}

public bool IsBound
{
get { return true; }
}

public IEnumerable<string> ParameterNames
{
get { return Enumerable.Empty<string>(); }
}

public string Bind(IReadOnlyDictionary<string, object> bindingData)
{
return QueueOrTopicNamePattern;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Host.Bindings;

namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
{
internal class ByteArrayArgumentBindingProvider : IQueueArgumentBindingProvider
{
public IArgumentBinding<ServiceBusEntity> TryCreate(ParameterInfo parameter)
{
if (!parameter.IsOut || parameter.ParameterType != typeof(byte[]).MakeByRefType())
{
return null;
}

return new ByteArrayArgumentBinding();
}

private class ByteArrayArgumentBinding : IArgumentBinding<ServiceBusEntity>
{
public Type ValueType
{
get { return typeof(byte[]); }
}

/// <remarks>
/// The out byte array parameter is processed as follows:
/// <list type="bullet">
/// <item>
/// <description>
/// If the value is <see langword="null"/>, no message will be sent.
/// </description>
/// </item>
/// <item>
/// <description>
/// If the value is an empty byte array, a message with empty content will be sent.
/// </description>
/// </item>
/// <item>
/// <description>
/// If the value is a non-empty byte array, a message with that content will be sent.
/// </description>
/// </item>
/// </list>
/// </remarks>
public Task<IValueProvider> BindAsync(ServiceBusEntity value, ValueBindingContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

IValueProvider provider = new NonNullConverterValueBinder<byte[]>(value,
new ByteArrayToBrokeredMessageConverter(), context.FunctionInstanceId);

return Task.FromResult(provider);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Azure.ServiceBus;

namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
{
internal class ByteArrayToBrokeredMessageConverter : IConverter<byte[], Message>
{
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
public Message Convert(byte[] input)
{
if (input == null)
{
throw new InvalidOperationException("A brokered message cannot contain a null byte array instance.");
}

return new Message(input)
{
ContentType = ContentTypes.ApplicationOctetStream
};
}
}
}
Loading