Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Configuration Options

CredentialSource

Mandatory

Default: AWS SDK credentials

By default the endpoint uses the SDK to retrieve AWS credentials. The AWS SDK permits a large number of transparent methods for configuring the credentials as outlined in the .NET SDK guidelines.

Example: To manually control the credentials retrieval, specify:

var transport = new SqsTransport(
    new AmazonSQSClient(new InstanceProfileAWSCredentials()), 
    new AmazonSimpleNotificationServiceClient());

endpointConfiguration.UseTransport(transport);

for S3 specify

var transport = new SqsTransport
{
    S3 = new S3Settings(bucketName, keyPrefix,
        new AmazonS3Client(new InstanceProfileAWSCredentials()))
};

endpointConfiguration.UseTransport(transport);

Region

Mandatory

Default: AWS SDK region

By default the endpoint uses the SDK to retrieve the default AWS region from the AWS_REGION environment variable.

This is the Amazon Web Services Region in which to access the SQS service. The value must be a valid AWS region code.

Example: To manually control the region, specify

var transport = new SqsTransport(new AmazonSQSClient(
    new AmazonSQSConfig
    {
        RegionEndpoint = RegionEndpoint.APSoutheast2
    }), 
    new AmazonSimpleNotificationServiceClient());

endpointConfiguration.UseTransport(transport);

for S3 specify

var transport = new SqsTransport
{
    S3 = new S3Settings(bucketName, keyPrefix,
        new AmazonS3Client(new AmazonS3Config
        {
            RegionEndpoint = RegionEndpoint.APSoutheast2
        }))
};

endpointConfiguration.UseTransport(transport);

ProxyHost and ProxyPort

Optional

Default: Empty

This is the name of the host of the proxy server that the client must authenticate to.

var transport = new SqsTransport(new AmazonSQSClient(
        new AmazonSQSConfig
        {
            ProxyCredentials = new NetworkCredential(userName, password),
            ProxyHost = "127.0.0.1",
            ProxyPort = 8888
        }),
    new AmazonSimpleNotificationServiceClient());

endpointConfiguration.UseTransport(transport);

for S3 specify

var transport = new SqsTransport
{
    S3 = new S3Settings(bucketName, keyPrefix,
        new AmazonS3Client(new AmazonS3Config
        {
            ProxyCredentials = new NetworkCredential(userName, password),
            ProxyHost = "127.0.0.1",
            ProxyPort = 8888
        }))
};

endpointConfiguration.UseTransport(transport);

SQS Client

Optional

Default: new AmazonSQSClient()

By default the transport uses a parameterless constructor to build the SQS client. This overrides the default SQS client with a custom one.

Example: To use a custom client, specify:

var transport = new SqsTransport(
    new AmazonSQSClient(new AmazonSQSConfig()),
    new AmazonSimpleNotificationServiceClient());

endpointConfiguration.UseTransport(transport);

SNS Client

Optional

Default: new AmazonSimpleNotificationServiceClient()

By default the transport uses a parameterless constructor to build the SNS client. This overrides the default SNS client with a custom one.

Example: To use a custom client, specify:

var transport = new SqsTransport(
    new AmazonSQSClient(new AmazonSQSConfig()),
    new AmazonSimpleNotificationServiceClient());

endpointConfiguration.UseTransport(transport);

Do not wrap message payload in a transport envelope

Optional

Default: false

By default the transport wraps outgoing messages in an envelope that contains also the message headers. The payload itself is encoded with Base64. This is done to ensure compatibility with endpoints running version 6.0 of the transport or below.

Example: To disable message wrapping and Base64-encoding of outgoing messages:

var transport = new SqsTransport
{
    DoNotWrapOutgoingMessages = true
};

endpointConfiguration.UseTransport(transport);

Message Attributes

When the DoNotWrapOutgoingMessages setting is enabled, all NServiceBus headers are stored in the NServiceBus.AmazonSQS.Headers message attribute. If the message is being sent to a non-NServiceBus endpoint, the consumer can use message attributes to handle a message in a particular way without having to process the message body first.

Retention period

Optional

Default: 4 days

This is the maximum time that a message will be retained within SQS and S3. When a sent message is not received and successfully processed within the specified time, the message will be lost. This value applies to both SQS and S3 - messages in SQS will be deleted after this amount of time, and large message bodies stored in S3 will automatically be deleted after this amount of time.

The maximum value is 14 days.

Example: To set this to the maximum value, specify:

var transport = new SqsTransport
{
    MaxTimeToLive = TimeSpan.FromDays(10)
};

endpointConfiguration.UseTransport(transport);

Queue name prefix

Optional

Default: None

This string value is prepended to the name of every SQS queue referenced by the endpoint. This is useful when deploying many instances of the same application in the same AWS region (e.g. a development instance, a QA instance, and a production instance), and the queue names must be distinguished from each other.

Example: For a development instance, specify:

var transport = new SqsTransport
{
    QueueNamePrefix = "DEV-"
};

endpointConfiguration.UseTransport(transport);

For example, queue names for the endpoint called "SampleEndpoint" might be:

DEV-SampleEndpoint
DEV-SampleEndpoint-Retries
DEV-SampleEndpoint-Timeouts
DEV-SampleEndpoint-TimeoutsDispatcher

Queue name generator

Optional

Default: $"{queueNamePrefix}{queueName} with unsupported characters like . are replaced with a hyphen -

Provides the ability to override the queue name generation with a custom function that allows creating queues in alignment with custom conventions.

var transport = new SqsTransport
{
    QueueNameGenerator = (name, prefix) =>
    {
        if (name.StartsWith(prefix))
        {
            return name;
        }

        return prefix + "-" + name;
    }
};

endpointConfiguration.UseTransport(transport);

Offload large messages to S3

Optional

Default: Disabled. Any attempt to send a message larger than the SQS limit will fail.

This option configures the S3 bucket to be used to store messages larger than 256 kB. If this option is not specified, S3 will not be used at all and any attempt to send a message larger than 256 kB will fail.

If the specified bucket doesn't exist, it will be created when the endpoint starts.

Example: To use a bucket named nsb-sqs-messages, specify:

var transport = new SqsTransport
{
    S3 = new S3Settings(
        bucketForLargeMessages: "nsb-sqs-messages",
        keyPrefix: "my/sample/path")
};

endpointConfiguration.UseTransport(transport);

Key prefix

Mandatory

This is the path within the specified S3 bucket to store large messages.

S3 Client

Optional

Default: new AmazonS3Client()

By default the transport uses a parameterless constructor to build the S3 client. This overrides the default S3 client with a custom one.

Example: To use a custom client, specify:

var transport = new SqsTransport
{
    S3 = new S3Settings(bucketName, keyPrefix,
        new AmazonS3Client(new AmazonS3Config()))
};

endpointConfiguration.UseTransport(transport);

Encryption

Optional

Default: Disabled

Specifies how the large messages stored in S3 are to be encrypted. Default option is no encryption. The alternative is to either use a managed encyption key:

var transport = new SqsTransport
{
    S3 = new S3Settings(bucketName, keyPrefix)
    {
        Encryption = new S3EncryptionWithManagedKey(ServerSideEncryptionMethod.AES256, "keyId")
    }
};

endpointConfiguration.UseTransport(transport);

or to provide a custom key:

var transport = new SqsTransport
{
    S3 = new S3Settings(bucketName, keyPrefix)
    {
        Encryption = new S3EncryptionWithCustomerProvidedKey(ServerSideEncryptionCustomerMethod.AES256, "key", "keyMD5")
    }
};

endpointConfiguration.UseTransport(transport);

V1 Compatibility Mode

Optional

Default: Disabled

This option enables serialization of the TimeToBeReceived and ReplyToAddress message headers in the message envelope for compatibility with endpoints using version 1 of the transport.

Example: To enable version 1 compatibility, specify:

#pragma warning disable CS0618 // Type or member is obsolete
        var transport = new SqsTransport
        {
            EnableV1CompatibilityMode = true
        };
#pragma warning restore CS0618 // Type or member is obsolete

        endpointConfiguration.UseTransport(transport);

Topic name prefix

Optional

Default: None

This string value is prepended to the name of every SNS topic subscribed by the endpoint. This is useful when deploying many instances of the same application in the same AWS region (e.g. a development instance, a QA instance, and a production instance), and the topic names must be distinguished from each other.

Example: For a development instance, specify:

var transport = new SqsTransport
{
    TopicNamePrefix = "DEV-"
};

endpointConfiguration.UseTransport(transport);

For example, topic names for the topic called "MyNameSpace.MyEvent" might be:

DEV-MyNameSpace-MyEvent

Topic name generator

Optional

Default: $"{topicNamePrefix}{eventType.FullName} with unsupported characters like . being replaced with a hyphen -

Provides the ability to override the topic name generation with a custom function that allows creating topics in alignment with custom conventions.

var transport = new SqsTransport
{
    TopicNameGenerator = (eventType, topicNamePrefix) => $"{topicNamePrefix}{eventType.Name}"
};

endpointConfiguration.UseTransport(transport);

Be aware that ServiceControl doesn't allow customization of this convention when publishing ServiceControl events. ServiceControl events will be published using the default naming convention.

Custom topics mappings

The transport topology describes in depth how the topology is determined by subscribers. There are scenarios in which a custom mapping is needed.

The MapEvent transport configuration API can be used to customize the way subscribers determine the topic to subscribe to. If the subscribers have knowledge of both the published event type and the subscribed one, the following API can be used:

var transport = new SqsTransport();

transport.MapEvent<SubscribedEvent, PublishedEvent>();

endpointConfiguration.UseTransport(transport);

If the published type is not known at compilation time, the following API can be used:

var transport = new SqsTransport();

transport.MapEvent<SubscribedEvent>("topic-used-by-the-publisher");

endpointConfiguration.UseTransport(transport);

Policy

NServiceBus automatically subscribes to all event types an endpoint has handlers for. For example, an endpoint may have two handlers:

public class OrderAcceptedHandler : IHandleMessages<OrderAccepted> { ... }
public class OrderPaidHandler : IHandleMessages<OrderPaid> { ... }

The transport creates a policy statement for the event types it subscribes to:

{
  ...
  "Statement": [
    {
      ...
      "Action": "sqs:SendMessage",
      "Resource": "arn:aws:sqs:some-region:some-account:endpoint",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": [
            "arn:aws:sns:some-region:some-account:Sales-OrderAccepted",
            "arn:aws:sns:some-region:some-account:Sales-OrderPaid"
          ]
        }
      }
    }
  ]
}

The policy statement is updated when an endpoint explicitly subscribes to an event type using session.Subscribe<CustomEvent>(). Unsubscribing does not modify the policy.

Wildcards

Account condition

Allow all messages from any topic in the account. The account name is extracted from the subscribed topic ARN.

var transport = new SqsTransport();

transport.Policies.AccountCondition = true;

config.UseTransport(transport);

Prefix condition

Allow all messages from any topic with the specified topic name prefix.

var transport = new SqsTransport();

transport.Policies.TopicNamePrefixCondition = true;

config.UseTransport(transport);

Namespace condition

Allow all messages in specific namespaces.

var transport = new SqsTransport();

transport.Policies.TopicNamespaceConditions
    .Add("Sales.");
transport.Policies.TopicNamespaceConditions
    .Add("Shipping.HighValueOrders.");

config.UseTransport(transport);

Disabling runtime policy modification

If the policy is modified during deployment it may be better to disable runtime policy modification.

var transport = new SqsTransport();

transport.Policies.SetupTopicPoliciesWhenSubscribing = false;

config.UseTransport(transport);

Message driven pub/sub compatibility mode

To gradually move an existing system from message driven pub/sub to native pub/sub using SNS, it's possible to enable message-driven pub/sub compatibility mode.

Message-driven pub/sub compatibility mode must be enabled on publisher endpoints. When enabled, publishers will still consume subscription messages sent by endpoints using message-driven pub/sub, and when publishing an event, it will be published both to legacy subscribers and to SNS. Publishers deduplicate published events.

To enable message-driven Pub/Sub compatibility mode, configure the endpoint as follows:

var routing = endpointConfiguration.UseTransport(new SqsTransport());

routing.EnableMessageDrivenPubSubCompatibilityMode();

Subscription cache configuration

The default value for SNS topic subscription cache invalidation (5 seconds) can be changed using:

var migrationSettings = routing.EnableMessageDrivenPubSubCompatibilityMode();
migrationSettings.SubscriptionsCacheTTL(TimeSpan.FromSeconds(30));

Topic cache configuration

The default value for SNS topic cache invalidation (5 seconds) can be changed using:

var migrationSettings = routing.EnableMessageDrivenPubSubCompatibilityMode();
migrationSettings.TopicCacheTTL(TimeSpan.FromSeconds(30));

Message visibility timeout

The default value for the message visibility timeout setting (30 seconds) can be changed using:

var migrationSettings = routing.EnableMessageDrivenPubSubCompatibilityMode();
migrationSettings.MessageVisibilityTimeout(timeoutInSeconds: 10);