Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add exchange parameter to AMQP External Rule #170

Merged
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 docs/resources/rule_amqp_external.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Optional:

Required:

- `exchange` (String) The RabbitMQ exchange, if needed, supports interpolation; see https://faqs.ably.com/what-is-the-format-of-the-routingkey-for-an-amqp-or-kinesis-reactor-rule for more info. If you don't use RabbitMQ exchanges, leave this blank.
- `mandatory_route` (Boolean) Reject delivery of the message if the route does not exist, otherwise fail silently.
- `persistent_messages` (Boolean) Marks the message as persistent, instructing the broker to write it to disk if it is in a durable queue.
- `routing_key` (String) The Kafka partition key. This is used to determine which partition a message should be routed to, where a topic has been partitioned. routingKey should be in the format topic:key where topic is the topic to publish to, and key is the value to use as the message key
Expand Down
4 changes: 4 additions & 0 deletions docs/resources/rule_http.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ resource "ably_rule_http" "rule0" {
signing_key_id = ably_api_key.api_key_0.id
enveloped = true
format = "json"
# Note, "enveloped" can only be set to true for "single" request_mode.
# "batch" request_mode is automatically enveloped.
enveloped = false
}
}
```
Expand Down Expand Up @@ -78,6 +81,7 @@ Required:

Optional:

- `enveloped` (Boolean) Delivered messages are wrapped in an Ably envelope by default that contains metadata about the message and its payload. The form of the envelope depends on whether it is part of a Webhook/Function or a Queue/Firehose rule. For everything besides Webhooks, you can ensure you only get the raw payload by unchecking "Enveloped" when setting up the rule.
- `format` (String) JSON provides a text-based encoding, whereas MsgPack provides a more efficient binary encoding
- `headers` (Attributes List) If you have additional information to send, you'll need to include the relevant headers (see [below for nested schema](#nestedatt--target--headers))
- `signing_key_id` (String) The signing key ID for use in batch mode. Ably will optionally sign the payload using an API key ensuring your servers can validate the payload using the private API key. See the [webhook security docs](https://ably.com/docs/general/webhooks#security) for more information
Expand Down
6 changes: 4 additions & 2 deletions examples/playground/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

| Name | Version |
|------|---------|
| <a name="provider_ably"></a> [ably](#provider\_ably) | 0.4.2 |
| <a name="provider_tls"></a> [tls](#provider\_tls) | 4.0.3 |
| <a name="provider_ably"></a> [ably](#provider\_ably) | 0.5.0 |
| <a name="provider_tls"></a> [tls](#provider\_tls) | 4.0.5 |

## Modules

Expand All @@ -25,6 +25,8 @@ No modules.
| [ably_app.app1](https://registry.terraform.io/providers/ably/ably/latest/docs/resources/app) | resource |
| [ably_namespace.namespace0](https://registry.terraform.io/providers/ably/ably/latest/docs/resources/namespace) | resource |
| [ably_queue.example_queue](https://registry.terraform.io/providers/ably/ably/latest/docs/resources/queue) | resource |
| [ably_rule_amqp.rule0](https://registry.terraform.io/providers/ably/ably/latest/docs/resources/rule_amqp) | resource |
| [ably_rule_amqp_external.rule0](https://registry.terraform.io/providers/ably/ably/latest/docs/resources/rule_amqp_external) | resource |
| [ably_rule_azure_function.rule0](https://registry.terraform.io/providers/ably/ably/latest/docs/resources/rule_azure_function) | resource |
| [ably_rule_cloudflare_worker.rule0](https://registry.terraform.io/providers/ably/ably/latest/docs/resources/rule_cloudflare_worker) | resource |
| [ably_rule_google_function.google_function](https://registry.terraform.io/providers/ably/ably/latest/docs/resources/rule_google_function) | resource |
Expand Down
24 changes: 12 additions & 12 deletions examples/playground/rule_amqp.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
resource "ably_rule_amqp" "rule0" {
app_id = ably_app.app0.id
status = "enabled"
source = {
channel_filter = "^my-channel.*",
type = "channel.message"
}
request_mode = "single"
target = {
queue_id = ably_queue.example_queue.id
app_id = ably_app.app0.id
status = "enabled"
source = {
channel_filter = "^my-channel.*",
type = "channel.message"
}
request_mode = "single"
target = {
queue_id = ably_queue.example_queue.id
headers = [
{
name : "User-Agent",
Expand All @@ -19,8 +19,8 @@ resource "ably_rule_amqp" "rule0" {
},
]

enveloped = false
format = "json"
}
enveloped = false
format = "json"
}
}

17 changes: 9 additions & 8 deletions examples/playground/rule_amqp_external.tf
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
resource "ably_rule_amqp_external" "rule0" {
app_id = ably_app.app0.id
status = "enabled"
app_id = ably_app.app0.id
status = "enabled"
request_mode = "single"
source = {
channel_filter = "^my-channel.*",
type = "channel.message"
}
target = {
url = "amqps://test.com"
routing_key = "new:key"
mandatory_route = true
url = "amqps://test.com"
routing_key = "new:key"
exchange = "testexchange"
mandatory_route = true
persistent_messages = true
message_ttl = 55
message_ttl = 55
headers = [
{
name : "User-Agent",
Expand All @@ -23,7 +24,7 @@ resource "ably_rule_amqp_external" "rule0" {
},
]
signing_key_id = ably_api_key.api_key_1.id
enveloped = false
format = "json"
enveloped = false
format = "json"
}
}
2 changes: 1 addition & 1 deletion examples/playground/rule_http.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ resource "ably_rule_http" "rule0" {
format = "json"
# Note, "enveloped" can only be set to true for "single" request_mode.
# "batch" request_mode is automatically enveloped.
enveloped = false
enveloped = false
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/ably/terraform-provider-ably
go 1.19

require (
github.com/ably/ably-control-go v0.1.0
github.com/ably/ably-control-go v0.2.0
github.com/hashicorp/terraform-plugin-docs v0.13.0
github.com/hashicorp/terraform-plugin-framework v0.16.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.21.0
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C6
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ably/ably-control-go v0.1.0 h1:flhd5ZiJZyWs+RxOK//ozsev6VpmRrqOmvXhVvgon3I=
github.com/ably/ably-control-go v0.1.0/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk=
github.com/ably/ably-control-go v0.1.1-0.20231211162000-164517f286eb h1:WVq8ysFKqCc8OtM77GnWF7s+cyEcRBT5+i2iirOZeoQ=
github.com/ably/ably-control-go v0.1.1-0.20231211162000-164517f286eb/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk=
github.com/ably/ably-control-go v0.1.1-0.20231213094545-a41bf3d025ef h1:tJthta4QnJVvbH/gR1G8hkdHQi/djOd8fkU8QS7IXx0=
github.com/ably/ably-control-go v0.1.1-0.20231213094545-a41bf3d025ef/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk=
github.com/ably/ably-control-go v0.2.0 h1:a6fOGtEAzGYYWL/k7tNHHc2WHur3mm7ZPuU7n/RsayU=
github.com/ably/ably-control-go v0.2.0/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
Expand Down
1 change: 1 addition & 0 deletions internal/provider/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ type AblyRuleTargetAmqp struct {
type AblyRuleTargetAmqpExternal struct {
Url string `tfsdk:"url"`
RoutingKey string `tfsdk:"routing_key"`
Exchange string `tfsdk:"exchange"`
MandatoryRoute bool `tfsdk:"mandatory_route"`
PersistentMessages bool `tfsdk:"persistent_messages"`
MessageTtl types.Int64 `tfsdk:"message_ttl"`
Expand Down
5 changes: 5 additions & 0 deletions internal/provider/resource_ably_rule_amqp_external.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ func (r resourceRuleAmqpExternal) GetSchema(_ context.Context) (tfsdk.Schema, di
Required: true,
Description: "The Kafka partition key. This is used to determine which partition a message should be routed to, where a topic has been partitioned. routingKey should be in the format topic:key where topic is the topic to publish to, and key is the value to use as the message key",
},
"exchange": {
Type: types.StringType,
Required: true,
Description: "The RabbitMQ exchange, if needed, supports interpolation; see https://faqs.ably.com/what-is-the-format-of-the-routingkey-for-an-amqp-or-kinesis-reactor-rule for more info. If you don't use RabbitMQ exchanges, leave this blank.",
},
"mandatory_route": {
Type: types.BoolType,
Required: true,
Expand Down
23 changes: 15 additions & 8 deletions internal/provider/resource_ably_rule_amqp_external_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func TestAccAblyRuleAmqpExternal(t *testing.T) {
"channel.message",
"amqps://test.example",
"topic:key",
"exchange",
true,
true,
44,
Expand All @@ -55,6 +56,7 @@ func TestAccAblyRuleAmqpExternal(t *testing.T) {
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "source.channel_filter", "^my-channel.*"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "source.type", "channel.message"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "target.routing_key", "topic:key"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "target.exchange", "exchange"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "target.enveloped", "true"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "target.format", "json"),
),
Expand All @@ -68,6 +70,7 @@ func TestAccAblyRuleAmqpExternal(t *testing.T) {
"channel.message",
"amqps://test.example",
"newtopic:key",
"newexchange",
false,
false,
23,
Expand All @@ -81,6 +84,7 @@ func TestAccAblyRuleAmqpExternal(t *testing.T) {
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "source.channel_filter", "^my-channel.*"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "source.type", "channel.message"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "target.routing_key", "newtopic:key"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "target.exchange", "newexchange"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "target.enveloped", "false"),
resource.TestCheckResourceAttr("ably_rule_amqp_external.rule0", "target.format", "msgpack"),
),
Expand All @@ -98,7 +102,8 @@ func testAccAblyRuleAmqpExternalConfig(
sourceType string,
targetUrl string,
targetRoutingKey string,
targetManditoryRoute bool,
targetExchange string,
targetMandatoryRoute bool,
targetPersistentMessages bool,
targetMessageTtl int,
targetHeaders string,
Expand Down Expand Up @@ -133,13 +138,15 @@ resource "ably_rule_amqp_external" "rule0" {
target = {
url = %[5]q
routing_key = %[6]q,
mandatory_route = %[7]t
persistent_messages = %[8]t
message_ttl = %[9]d
headers = %[10]s
enveloped = %[11]s,
format = %[12]q,
exchange = %[7]q,
mandatory_route = %[8]t
persistent_messages = %[9]t
message_ttl = %[10]d
headers = %[11]s
enveloped = %[12]s,
format = %[13]q,

}
}
`, appName, ruleStatus, channelFilter, sourceType, targetUrl, targetRoutingKey, targetManditoryRoute, targetPersistentMessages, targetMessageTtl, targetHeaders, targetEnveloped, targetFormat)
`, appName, ruleStatus, channelFilter, sourceType, targetUrl, targetRoutingKey, targetExchange, targetMandatoryRoute, targetPersistentMessages, targetMessageTtl, targetHeaders, targetEnveloped, targetFormat)
}
2 changes: 2 additions & 0 deletions internal/provider/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ func GetPlanRule(plan AblyRule) ably_control_go.NewRule {
target = &ably_control_go.AmqpExternalTarget{
Url: t.Url,
RoutingKey: t.RoutingKey,
Exchange: t.Exchange,
MandatoryRoute: t.MandatoryRoute,
PersistentMessages: t.PersistentMessages,
MessageTTL: int(t.MessageTtl.ValueInt64()),
Expand Down Expand Up @@ -373,6 +374,7 @@ func GetRuleResponse(ably_rule *ably_control_go.Rule, plan *AblyRule) AblyRule {
resp_target = &AblyRuleTargetAmqpExternal{
Url: v.Url,
RoutingKey: v.RoutingKey,
Exchange: v.Exchange,
MandatoryRoute: v.MandatoryRoute,
PersistentMessages: v.PersistentMessages,
MessageTtl: ttl,
Expand Down
Loading