Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

Commit 752bf4a

Browse files
authored
Chore - move build variables to variable template (#32)
* Chore - move build variables to variable template * pr-fix: update with temp messaging update * pr-fix: update with moved extensions * pr-fix: add MyGet sources to key vault proj * pr-fix: add MyGet sources to key vault proj * pr-fix: update with implementation type * pr-fix: update with temp mesage pump package * pr-fix: update with temp mesage pump package * pr-sug: use NuGet preview messaging package * pr-sug: use NuGet preview messaging package
1 parent f0a0ede commit 752bf4a

File tree

12 files changed

+170
-201
lines changed

12 files changed

+170
-201
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*.user
99
*.userosscache
1010
*.sln.docstates
11+
*.local.json
1112

1213
# User-specific files (MonoDevelop/Xamarin Studio)
1314
*.userprefs

build/ci-build.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@ variables:
2626
- group: 'Arcus Security - Integration Testing'
2727
- group: 'Arcus - GitHub Package Registry'
2828
- group: 'Build Configuration'
29-
# Always use fixed version for .NET Core SDK
30-
- name: 'DotNet.Sdk.Version'
31-
value: '3.0.101'
32-
- name: 'Project'
33-
value: 'Arcus.BackgroundJobs'
29+
- template: ./variables/build.yml
3430
# 'Package.Version.ManualTrigger' is added as queue-time variable on build in Azure DevOps
3531

3632
stages:

build/nuget-release.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ variables:
1515
- group: 'Arcus Security - Integration Testing'
1616
- group: 'Build Configuration'
1717
- group: 'Arcus Background Jobs - .NET'
18-
- name: 'Project'
19-
value: 'Arcus.BackgroundJobs'
18+
- template: ./variables/build.yml
2019
- name: 'GitHub.Repository'
2120
value: 'arcus-azure/arcus.backgroundjobs'
2221
# 'Package.Version' is added as queue-time variable on build in Azure DevOps

build/variables/build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
variables:
2+
DotNet.Sdk.Version: '3.0.101'
3+
Project: 'Arcus.BackgroundJobs'

src/Arcus.BackgroundJobs.CloudEvents/Arcus.BackgroundJobs.CloudEvents.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
</PropertyGroup>
1818

1919
<ItemGroup>
20-
<PackageReference Include="Arcus.EventGrid" Version="3.0.0-preview-1" />
21-
<PackageReference Include="Arcus.Messaging.Pumps.ServiceBus" Version="0.1.0-preview-2" />
22-
<PackageReference Include="Microsoft.Azure.EventGrid" Version="3.2.0" />
20+
<PackageReference Include="Arcus.EventGrid" Version="3.0.0" />
21+
<PackageReference Include="Arcus.Messaging.Pumps.ServiceBus" Version="0.1.0-preview-3" />
2322
</ItemGroup>
23+
2424
</Project>
Lines changed: 30 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,65 @@
11
using System;
2-
using System.Threading;
3-
using System.Threading.Tasks;
4-
using Arcus.Messaging.Abstractions;
52
using Arcus.Messaging.Pumps.ServiceBus;
3+
using Arcus.Messaging.Pumps.ServiceBus.Configuration;
64
using CloudNative.CloudEvents;
7-
using GuardNet;
8-
using Microsoft.Azure.ServiceBus;
9-
using Microsoft.Azure.ServiceBus.Management;
105
using Microsoft.Extensions.Configuration;
11-
using Microsoft.Extensions.DependencyInjection;
126
using Microsoft.Extensions.Logging;
13-
using Microsoft.Extensions.Options;
147

158
namespace Arcus.BackgroundJobs.CloudEvents
169
{
1710
/// <summary>
1811
/// Representing a Azure Service Bus Topic message pump that will create and delete a Service Bus Topic subscription during the lifetime of the pump.
1912
/// </summary>
20-
public abstract class CloudEventBackgroundJob : AzureServiceBusMessagePump<CloudNative.CloudEvents.CloudEvent>
13+
public class CloudEventBackgroundJob : AzureServiceBusMessagePump
2114
{
2215
private static readonly JsonEventFormatter JsonEventFormatter = new JsonEventFormatter();
2316

2417
/// <summary>
2518
/// Initializes a new instance of the <see cref="CloudEventBackgroundJob"/> class.
2619
/// </summary>
20+
/// <param name="settings">The settings to influence the behavior of the message pump.</param>
2721
/// <param name="configuration">The configuration of the application.</param>
2822
/// <param name="serviceProvider">The collection of services that are configured.</param>
29-
/// <param name="options">The options to further configure this job.</param>
3023
/// <param name="logger">The logger to write telemetry to.</param>
3124
/// <exception cref="ArgumentNullException">When the <paramref name="serviceProvider"/> is <c>null</c>.</exception>
3225
/// <exception cref="ArgumentException">When the <paramref name="serviceProvider"/> doesn't have a registered <see cref="AzureServiceBusMessagePumpSettings"/> instance.</exception>
33-
protected CloudEventBackgroundJob(
26+
public CloudEventBackgroundJob(
27+
AzureServiceBusMessagePumpSettings settings,
3428
IConfiguration configuration,
3529
IServiceProvider serviceProvider,
36-
IOptions<CloudEventBackgroundJobOptions> options,
37-
ILogger logger) : base(configuration, serviceProvider, logger)
30+
ILogger<AzureServiceBusMessagePump> logger)
31+
: base(settings, configuration, serviceProvider, logger)
3832
{
39-
Guard.NotNull(
40-
serviceProvider,
41-
nameof(serviceProvider),
42-
$"Requires a '{nameof(IServiceProvider)}' implementation to retrieve the '{nameof(AzureServiceBusMessagePumpSettings)}'");
43-
Guard.NotNull(options, nameof(options), $"Requires a '{nameof(IOptions<CloudEventBackgroundJobOptions>)}' to correctly configure this job");
44-
Guard.For<ArgumentException>(() => options.Value is null, $"Requires a '{nameof(IOptions<CloudEventBackgroundJobOptions>)}' to correctly configure this job");
45-
46-
var messagePumpSettings = serviceProvider.GetRequiredService<AzureServiceBusMessagePumpSettings>();
47-
Guard.NotNull<AzureServiceBusMessagePumpSettings, ArgumentException>(
48-
messagePumpSettings,
49-
$"The '{nameof(serviceProvider)}:{serviceProvider.GetType().Name}' requires to have a non-null '{nameof(AzureServiceBusMessagePumpSettings)}' instance registered");
50-
51-
JobId = options.Value.JobId;
5233
}
5334

5435
/// <summary>
55-
/// Gets the unique identifier for this background job to distinguish this job instance in a multi-instance deployment.
56-
/// </summary>
57-
public string JobId { get; }
58-
59-
/// <summary>
60-
/// Deserializes a raw JSON message body.
36+
/// Tries to parse the given raw <paramref name="message" /> to the contract of the <see cref="T:Arcus.Messaging.Pumps.Abstractions.MessageHandling.IMessageHandler`2" />.
6137
/// </summary>
62-
/// <param name="rawMessageBody">Raw message body to deserialize</param>
63-
/// <param name="messageContext">Context concerning the message</param>
64-
/// <returns>Deserialized message</returns>
65-
protected override CloudNative.CloudEvents.CloudEvent DeserializeJsonMessageBody(byte[] rawMessageBody, MessageContext messageContext)
38+
/// <param name="message">The raw incoming message that will be tried to parse against the <see cref="T:Arcus.Messaging.Pumps.Abstractions.MessageHandling.IMessageHandler`2" />'s message contract.</param>
39+
/// <param name="messageType">The type of the message that the message handler can process.</param>
40+
/// <param name="result">The resulted parsed message when the <paramref name="message" /> conforms with the message handlers' contract.</param>
41+
/// <returns>
42+
/// [true] if the <paramref name="message" /> conforms the <see cref="T:Arcus.Messaging.Pumps.Abstractions.MessageHandling.IMessageHandler`2" />'s contract; otherwise [false].
43+
/// </returns>
44+
public override bool TryDeserializeToMessageFormat(string message, Type messageType, out object result)
6645
{
67-
Guard.NotNull(rawMessageBody, nameof(rawMessageBody), "Cannot deserialize raw JSON body from 'null' input");
68-
Guard.NotAny(rawMessageBody, nameof(rawMessageBody), "Cannot deserialize raw JSON body from empty input");
69-
70-
CloudNative.CloudEvents.CloudEvent cloudEvent = JsonEventFormatter.DecodeStructuredEvent(rawMessageBody);
71-
return cloudEvent;
72-
}
73-
74-
/// <inheritdoc />
75-
protected abstract override Task ProcessMessageAsync(
76-
CloudNative.CloudEvents.CloudEvent message,
77-
AzureServiceBusMessageContext messageContext,
78-
MessageCorrelationInfo correlationInfo,
79-
CancellationToken cancellationToken);
80-
81-
/// <summary>
82-
/// Triggered when the application host is ready to start the service.
83-
/// </summary>
84-
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
85-
public override async Task StartAsync(CancellationToken cancellationToken)
86-
{
87-
ServiceBusConnectionStringBuilder serviceBusConnectionString = await GetServiceBusConnectionStringAsync();
88-
89-
Logger.LogTrace("[Job: {JobId}] Creating subscription '{SubscriptionName}' on topic '{TopicPath}'...", JobId, Settings.SubscriptionName, serviceBusConnectionString.EntityPath);
90-
var subscriptionDescription = new SubscriptionDescription(serviceBusConnectionString.EntityPath, Settings.SubscriptionName)
46+
try
9147
{
92-
AutoDeleteOnIdle = TimeSpan.FromHours(1),
93-
MaxDeliveryCount = 3,
94-
UserMetadata = $"Subscription created by Arcus job: '{JobId}' to process inbound CloudEvents."
95-
};
96-
97-
var ruleDescription = new RuleDescription("Accept-All", new TrueFilter());
98-
99-
var serviceBusClient = new ManagementClient(serviceBusConnectionString);
100-
await serviceBusClient.CreateSubscriptionAsync(subscriptionDescription, ruleDescription, cancellationToken)
101-
.ConfigureAwait(continueOnCapturedContext: false);
102-
103-
Logger.LogTrace("[Job: {JobId}] Subscription '{SubscriptionName}' created on topic '{TopicPath}'", JobId, Settings.SubscriptionName, serviceBusConnectionString.EntityPath);
104-
await serviceBusClient.CloseAsync().ConfigureAwait(continueOnCapturedContext: false);
105-
106-
await base.StartAsync(cancellationToken);
107-
}
108-
109-
/// <summary>
110-
/// Triggered when the application host is performing a graceful shutdown.
111-
/// </summary>
112-
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
113-
public override async Task StopAsync(CancellationToken cancellationToken)
114-
{
115-
ServiceBusConnectionStringBuilder serviceBusConnectionString = await GetServiceBusConnectionStringAsync();
116-
117-
Logger.LogTrace("[Job: {JobId}] Deleting subscription '{SubscriptionName}' on topic '{TopicPath}'...", JobId, Settings.SubscriptionName, serviceBusConnectionString.EntityPath);
118-
var serviceBusClient = new ManagementClient(serviceBusConnectionString);
119-
await serviceBusClient.DeleteSubscriptionAsync(serviceBusConnectionString.EntityPath, Settings.SubscriptionName, cancellationToken);
120-
Logger.LogTrace("[Job: {JobId}] Subscription '{SubscriptionName}' deleted on topic '{TopicPath}'", JobId, Settings.SubscriptionName, serviceBusConnectionString.EntityPath);
121-
await serviceBusClient.CloseAsync().ConfigureAwait(continueOnCapturedContext: false);
122-
123-
await base.StopAsync(cancellationToken);
124-
}
125-
126-
private async Task<ServiceBusConnectionStringBuilder> GetServiceBusConnectionStringAsync()
127-
{
128-
Logger.LogTrace("[Job: {JobId}] Getting ServiceBus Topic connection string on topic '{TopicPath}'...", JobId, Settings.EntityName);
129-
string connectionString = await Settings.GetConnectionStringAsync();
130-
var serviceBusConnectionBuilder = new ServiceBusConnectionStringBuilder(connectionString);
131-
Logger.LogTrace("[JobId: {JobId}] Got ServiceBus Topic connection string on topic '{TopicPath}'", JobId, Settings.EntityName);
48+
if (messageType == typeof(CloudEvent))
49+
{
50+
CloudEvent cloudEvent = JsonEventFormatter.DecodeStructuredEvent(DefaultEncoding.GetBytes(message));
51+
52+
result = cloudEvent;
53+
return true;
54+
}
55+
}
56+
catch (Exception exception)
57+
{
58+
Logger.LogWarning(exception, "Unable to deserialize the CloudEvent");
59+
}
13260

133-
return serviceBusConnectionBuilder;
61+
result = null;
62+
return false;
13463
}
13564
}
13665
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using Arcus.BackgroundJobs.CloudEvents;
3+
using Arcus.Messaging.Pumps.ServiceBus;
4+
using Arcus.Messaging.Pumps.ServiceBus.Configuration;
5+
using CloudNative.CloudEvents;
6+
using GuardNet;
7+
using Microsoft.Extensions.Configuration;
8+
using Microsoft.Extensions.Logging;
9+
10+
// ReSharper disable once CheckNamespace
11+
namespace Microsoft.Extensions.DependencyInjection
12+
{
13+
public static class IServiceCollectionExtensions
14+
{
15+
/// <summary>
16+
/// Adds a background job to the <see cref="IServiceCollection"/> to receive <see cref="CloudEvent"/>'s.
17+
/// </summary>
18+
/// <param name="services">The services collection to add the job to.</param>
19+
/// <param name="subscriptionNamePrefix">The name of the Azure Service Bus subscription that will be created to receive <see cref="CloudEvent"/>'s.</param>
20+
/// <param name="serviceBusTopicConnectionStringSecretKey">The configuration key that points to the Azure Service Bus Topic connection string.</param>
21+
public static IServiceCollection AddCloudEventBackgroundJob(
22+
this IServiceCollection services,
23+
string subscriptionNamePrefix,
24+
string serviceBusTopicConnectionStringSecretKey)
25+
{
26+
Guard.NotNull(services, nameof(services));
27+
Guard.NotNullOrWhitespace(subscriptionNamePrefix, nameof(subscriptionNamePrefix), "Requires a non-blank subscription name of the Azure Service Bus Topic subscription, to receive Key Vault events");
28+
Guard.NotNullOrWhitespace(serviceBusTopicConnectionStringSecretKey, nameof(serviceBusTopicConnectionStringSecretKey), "Requires a non-blank configuration key that points to a Azure Service Bus Topic");
29+
30+
services.AddHostedService(serviceProvider =>
31+
{
32+
var settings = new AzureServiceBusMessagePumpSettings(
33+
entityName: null,
34+
subscriptionName: $"{subscriptionNamePrefix}.{Guid.NewGuid().ToString()}",
35+
ServiceBusEntity.Topic,
36+
getConnectionStringFromConfigurationFunc: null,
37+
getConnectionStringFromSecretFunc: secretProvider => secretProvider.GetRawSecretAsync(serviceBusTopicConnectionStringSecretKey),
38+
options: new AzureServiceBusMessagePumpConfiguration(AzureServiceBusTopicMessagePumpOptions.Default),
39+
serviceProvider: serviceProvider);
40+
41+
var configuration = serviceProvider.GetRequiredService<IConfiguration>();
42+
var logger = serviceProvider.GetRequiredService<ILogger<AzureServiceBusMessagePump>>();
43+
44+
return new CloudEventBackgroundJob(settings, configuration, serviceProvider, logger);
45+
});
46+
47+
return services;
48+
}
49+
}
50+
}

src/Arcus.BackgroundJobs.KeyVault/Arcus.BackgroundJobs.KeyVault.csproj

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@
1717
</PropertyGroup>
1818

1919
<ItemGroup>
20-
<PackageReference Include="Arcus.EventGrid" Version="3.0.0-preview-1" />
20+
<PackageReference Include="Arcus.EventGrid" Version="3.0.0" />
2121
<PackageReference Include="Arcus.Security.Core" Version="1.1.0" />
22-
<PackageReference Include="Arcus.Security.Providers.AzureKeyVault" Version="1.1.0" />
23-
<PackageReference Include="Microsoft.Azure.EventGrid" Version="3.2.0" />
24-
<PackageReference Include="Microsoft.Azure.KeyVault.Core" Version="3.0.4" />
2522
</ItemGroup>
2623

2724
<ItemGroup>
2825
<ProjectReference Include="..\Arcus.BackgroundJobs.CloudEvents\Arcus.BackgroundJobs.CloudEvents.csproj" />
2926
</ItemGroup>
27+
3028
</Project>

src/Arcus.BackgroundJobs.KeyVault/AutoInvalidateKeyVaultSecretJob.cs

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)