Skip to content

Commit

Permalink
Merge pull request #222 from Particular/release-4.0
Browse files Browse the repository at this point in the history
Release 4.0
  • Loading branch information
bording authored May 14, 2018
2 parents 9aa0eeb + 76eaacf commit 0fc8172
Show file tree
Hide file tree
Showing 67 changed files with 2,009 additions and 1,380 deletions.
4 changes: 2 additions & 2 deletions GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
assembly-versioning-scheme: Major
next-version: 3.0
next-version: 4.0
branches:
develop:
tag: alpharelease
tag: beta
release:
tag: rc
35 changes: 35 additions & 0 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
The current maintainers of this repo are [aws-maintainers](https://github.com/orgs/Particular/teams/aws-maintainers).

The maintainers [watch](https://github.com/Particular/NServiceBus.AmazonSQS/watchers) this repo and undertake the following responsibilities:

- Ensuring that the `master` and `support-x.y` branches are always releasable. "Releasable" means that the software built from the latest commit contains no known regressions from the previous release and can be released immediately.
- This does not imply that the latest commit should *always* be released, only that it *can* be, immediately after deciding to release.
- Releasing new versions of the software.
- Reviewing and merging pull requests](https://github.com/Particular/NServiceBus.AmazonSQS/pulls).
- [Issue backlog](https://github.com/Particular/NServiceBus.AmazonSQS/issues) grooming, including the triage of new issues as soon as possible after they are created.
- Managing the repo settings (options, collaborators & teams, branches, etc.).

## Merging pull requests

### Summarized workflow for merging pull requests:

1. Reviewer: Request changes or comment.
2. Submitter: Push fixup.
3. (Repeat)
4. Reviewer: Request squash.
5. Submitter: Squash and force push.
6. Reviewer: Approve.
7. (Any maintainer): Merge.

### Details

- A pull request must be approved by two maintainers before it is merged.
- A pull request created by a maintainer is implicitly approved by that maintainer.
- Before approving, the maintainer should consider whether a smoke test is required.
- Approval is given by submitting a review and choosing the **Approve** option:
- For some pull requests, it may be appropriate to require a third maintainer to give approval before the pull request is merged. This may be requested by either of the current approvers based on their assessment of factors such as the impact or risk of the changes.
- An approved pull request may be merged by any maintainer.

### Branching and workflow

This repository follows the [GitFlow](http://nvie.com/posts/a-successful-git-branching-model/) branching model and workflow.
34 changes: 16 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
NServiceBus.AmazonSQS
===============

![toucan](https://raw.githubusercontent.com/ahofman/NServiceBus.AmazonSQS/master/toucan-large.png)

This is an Amazon SQS transport for NServiceBus V5 and V6.
This is an Amazon SQS transport for NServiceBus.

Feel free to browse and contribute!

Expand All @@ -17,29 +15,29 @@ To run the tests, the Access Key ID and Secret Access Key of an AWS IAM account

The transport can be configured using the following environment variables:

* **NServiceBus.AmazonSQS.Region** corresponds to the [Region](https://docs.particular.net/transports/sqs/configuration-options#region) parameter. Default is "ap-southeast-2".
* **NServiceBus.AmazonSQS.S3Bucket** corresponds to the [S3BucketForLargeMessages](https://docs.particular.net/transports/sqs/configuration-options#s3bucketforlargemessages) parameter. Default is no S3 bucket.
* **NServiceBus.AmazonSQS.NativeDeferral** corresponds to the [NativeDeferral](https://docs.particular.net/transports/sqs/configuration-options#nativedeferral) parameter. Default is false.
* **NServiceBus_AmazonSQS_S3Bucket** corresponds to the [S3BucketForLargeMessages](https://docs.particular.net/transports/sqs/configuration-options#s3bucketforlargemessages) parameter. Default is no S3 bucket.

Additional environment variables required for AWS:

* **AWS_ACCESS_KEY_ID** access key ID to sign programmatic requests that you make to AWS. Provisioned via IAM.
* **AWS_SECRET_ACCESS_KEY** secret access key to sign programmatic requests that you make to AWS. Provisioned via IAM.


### Queue Names in Acceptance Tests

The names of queues used by the acceptance tests take the following form:

AT<datetime>-<pre-truncated-queue-name>

Where

* `AT` stands for "Acceptance Test"
* `datetime` is a date and time as yyyyMMddHHmmss that uniquely identifies a single test run. For example, when 100 tests are executed in a single test run each queue will have the same datetime timestamp.
* `pre-truncated-queue-name` is the name of the queue, "pre-truncated" (characters are removed from the beginning) so that the entire queue name is 80 characters or less.
* `AT` stands for "Acceptance Test"
* `datetime` is a date and time as yyyyMMddHHmmss that uniquely identifies a single test run. For example, when 100 tests are executed in a single test run each queue will have the same datetime timestamp.
* `pre-truncated-queue-name` is the name of the queue, "pre-truncated" (characters are removed from the beginning) so that the entire queue name is 80 characters or less.

This scheme accomplishes the following goals:

* Test runs are idempotent - each test run uses its own set of queues
* Queues for a given test run are easily searchable by prefix in the SQS portal
* The discriminator and qualifier at the end of the queue name are not interfered with
* Queue names fit the 80 character limit imposed by SQS

Project Icon
===============
Toucan by Creative Stall from the Noun Project
* Test runs are idempotent - each test run uses its own set of queues
* Queues for a given test run are easily searchable by prefix in the SQS portal
* The discriminator and qualifier at the end of the queue name are not interfered with
* Queue names fit the 80 character limit imposed by SQS
23 changes: 23 additions & 0 deletions src/AcceptanceTests/AcceptanceTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net452;netcoreapp2.0</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(SolutionDir)Test.snk</AssemblyOriginatorKeyFile>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\NServiceBus.AmazonSQS\NServiceBus.AmazonSQS.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.S3" Version="3.*" />
<PackageReference Include="AWSSDK.SQS" Version="3.*" />
<PackageReference Include="NServiceBus.AcceptanceTests.Sources" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="NUnit" Version="3.7.*" />
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0-alpha1" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public Task Configure(string endpointName, EndpointConfiguration configuration,
}
}

settings.TestExecutionTimeout = TimeSpan.FromSeconds(20);

var recoverability = configuration.Recoverability();
recoverability.DisableLegacyRetriesSatellite();
// TODO: remove when AWS SDK bug is resolved https://github.com/aws/aws-sdk-net/issues/796
// The bug causes messages to be marked as in flight, but not delivered to the client.
// Wait for tests longer than the invisibility time to make sure messages are received.
settings.TestExecutionTimeout = TimeSpan.FromSeconds(40);

return Task.FromResult(0);
}
Expand Down
12 changes: 12 additions & 0 deletions src/AcceptanceTests/CustomEndpointConfigurationExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace NServiceBus.AcceptanceTests
{
using Configuration.AdvancedExtensibility;

public static class CustomEndpointConfigurationExtensions
{
public static TransportExtensions<SqsTransport> ConfigureSqsTransport(this EndpointConfiguration configuration)
{
return new TransportExtensions<SqsTransport>(configuration.GetSettings());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
namespace NServiceBus.AcceptanceTests.DelayedDelivery
{
using System;
using System.Threading.Tasks;
using AcceptanceTesting;
using AcceptanceTesting.Customization;
using Amazon.SQS.Model;
using EndpointTemplates;
using NUnit.Framework;

public class SendOnly_Sending_when_receiver_not_properly_configured : NServiceBusAcceptanceTest
{
[Test]
public async Task Should_deliver_messages_only_if_below_queue_delay_time()
{
var payload = "some payload";
var delay = QueueDelayTime.Subtract(TimeSpan.FromSeconds(1));

var context = await Scenario.Define<Context>()
.WithEndpoint<SendOnlySender>(b => b.When(async (session, c) =>
{
var sendOptions = new SendOptions();
sendOptions.DelayDeliveryWith(delay);

c.SentAt = DateTime.UtcNow;

await session.Send(new DelayedMessage
{
Payload = payload
}, sendOptions);
}))
.WithEndpoint<NotConfiguredReceiver>()
.Done(c => c.Received)
.Run();

Assert.GreaterOrEqual(context.ReceivedAt - context.SentAt, delay, "The message has been received earlier than expected.");
Assert.AreEqual(payload, context.Payload, "The received payload doesn't match the sent one.");
}

[Test]
public void Should_fail_to_send_message_if_above_queue_delay_time()
{
var delay = QueueDelayTime.Add(TimeSpan.FromSeconds(1));

Assert.ThrowsAsync<QueueDoesNotExistException>(async () =>
{
await Scenario.Define<Context>()
.WithEndpoint<SendOnlySender>(b => b.When(async (session, c) =>
{
var sendOptions = new SendOptions();
sendOptions.DelayDeliveryWith(delay);

await session.Send(new DelayedMessage
{
Payload = ""
}, sendOptions);
}))
.Run();
});
}

static readonly TimeSpan QueueDelayTime = TimeSpan.FromSeconds(3);

public class Context : ScenarioContext
{
public bool Received { get; set; }
public string Payload { get; set; }
public DateTime SentAt { get; set; }
public DateTime ReceivedAt { get; set; }
}

public class SendOnlySender : EndpointConfigurationBuilder
{
public SendOnlySender()
{
EndpointSetup<DefaultServer>(builder =>
{
builder.ConfigureTransport().Routing().RouteToEndpoint(typeof(DelayedMessage), typeof(NotConfiguredReceiver));
builder.SendOnly();

builder.ConfigureSqsTransport().UnrestrictedDurationDelayedDelivery(QueueDelayTime);
});
}
}

public class NotConfiguredReceiver : EndpointConfigurationBuilder
{
public NotConfiguredReceiver()
{
EndpointSetup<DefaultServer>();
}

public class MyMessageHandler : IHandleMessages<DelayedMessage>
{
public Context Context { get; set; }

public Task Handle(DelayedMessage message, IMessageHandlerContext context)
{
Context.Received = true;
Context.Payload = message.Payload;
Context.ReceivedAt = DateTime.UtcNow;

return Task.FromResult(0);
}
}
}

public class DelayedMessage : IMessage
{
public string Payload { get; set; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
namespace NServiceBus.AcceptanceTests.DelayedDelivery
{
using System;
using System.Threading.Tasks;
using AcceptanceTesting;
using AcceptanceTesting.Customization;
using EndpointTemplates;
using NUnit.Framework;

public class SendOnly_Sending_when_sender_and_receiver_are_properly_configured : NServiceBusAcceptanceTest
{
[Test]
public async Task Should_deliver_message_if_below_queue_delay_time()
{
var payload = "some payload";
var delay = QueueDelayTime.Subtract(TimeSpan.FromSeconds(1));

var context = await Scenario.Define<Context>()
.WithEndpoint<SendOnlySender>(b => b.When(async (session, c) =>
{
var sendOptions = new SendOptions();
sendOptions.DelayDeliveryWith(delay);

c.SentAt = DateTime.UtcNow;

await session.Send(new DelayedMessage
{
Payload = payload
}, sendOptions);
}))
.WithEndpoint<Receiver>()
.Done(c => c.Received)
.Run();

Assert.GreaterOrEqual(context.ReceivedAt - context.SentAt, delay, "The message has been received earlier than expected.");
Assert.AreEqual(payload, context.Payload, "The received payload doesn't match the sent one.");
}

[Test]
public async Task Should_deliver_message_if_above_queue_delay_time()
{
var payload = "some payload";
var delay = QueueDelayTime.Add(TimeSpan.FromSeconds(1));

var context = await Scenario.Define<Context>()
.WithEndpoint<SendOnlySender>(b => b.When(async (session, c) =>
{
var sendOptions = new SendOptions();
sendOptions.DelayDeliveryWith(delay);

c.SentAt = DateTime.UtcNow;

await session.Send(new DelayedMessage
{
Payload = payload
}, sendOptions);
}))
.WithEndpoint<Receiver>()
.Done(c => c.Received)
.Run();

Assert.GreaterOrEqual(context.ReceivedAt - context.SentAt, delay, "The message has been received earlier than expected.");
Assert.AreEqual(payload, context.Payload, "The received payload doesn't match the sent one.");
}

static readonly TimeSpan QueueDelayTime = TimeSpan.FromSeconds(3);

public class Context : ScenarioContext
{
public bool Received { get; set; }
public string Payload { get; set; }
public DateTime SentAt { get; set; }
public DateTime ReceivedAt { get; set; }
}

public class SendOnlySender : EndpointConfigurationBuilder
{
public SendOnlySender()
{
EndpointSetup<DefaultServer>(builder =>
{
builder.ConfigureTransport().Routing().RouteToEndpoint(typeof(DelayedMessage), typeof(Receiver));
builder.SendOnly();

builder.ConfigureSqsTransport().UnrestrictedDurationDelayedDelivery(QueueDelayTime);
});
}
}

public class Receiver : EndpointConfigurationBuilder
{
public Receiver()
{
EndpointSetup<DefaultServer>(builder => { builder.ConfigureSqsTransport().UnrestrictedDurationDelayedDelivery(QueueDelayTime); });
}

public class MyMessageHandler : IHandleMessages<DelayedMessage>
{
public Context Context { get; set; }

public Task Handle(DelayedMessage message, IMessageHandlerContext context)
{
Context.Received = true;
Context.Payload = message.Payload;
Context.ReceivedAt = DateTime.UtcNow;

return Task.FromResult(0);
}
}
}

public class DelayedMessage : IMessage
{
public string Payload { get; set; }
}
}
}
Loading

0 comments on commit 0fc8172

Please sign in to comment.