# express-bus

Tool to interact with EventBus events in SQS. Useful for identifying, deserializing, and displaying contents of EventBus events that would otherwise be annoying to parse and inspect by hand (since they're serialized and base64'd in SQS at rest).

Given the URL to an SQS queue, the tool will allow the user to step through the queue's messages and get an understanding of what is in that message, including attempting to parse the SQS header, SNS header if applicable, and EventBus message if applicable. If the message is found to be an EventBus event, the protobuf bytes will be unmarshalled and the message payload will be pretty-printed to `stdout` (in addition to other available administrative actions).

## Usage

### Receiving Messages

_WARNING: This tool can be used to permanently delete messages from SQS queues. It is intended to be used for operational debugging purposes only. Use at your own risk!_

```
$ express-bus receive -u "https://queue-url" -n 5 --action list
Message 1 of 5
===========================
SQS:
	MessageID: d2625381-3ad6-4fac-8c47-7e1c7771ff4f
	FirstReceiveTime: 2020-10-09T13:37:49-07:00
	ReceiveCount: 7
	Attributes: (None)
SNS:
	MessageID: e40f0f70-2caf-5b18-b8fe-588ae0f2d115
	Attributes:
		eventbus-rand-e6: {"Type":"Number","Value":"254388"}
		eventbus-event-type: {"Type":"String","Value":"UserFollowUserCreate"}
	EventBus:
		Type: UserFollowUserCreate
		Header:
			MessageID: 2869f2b5-0623-4ad7-b615-90826cf6a540
			CreatedAt: 2020-10-09T20:37:49Z
			Environment: production
		Payload:
			{
				"from_user_id": "502389461",
				"to_user_id": "128976889",
				"created_at": {
					"seconds": 1602275869,
					"nanos": 131432080
				},
				"to_user_follower_count": 298466
			} 

...
```

Where actions to take can be one of:

* `(default) list` - print message contents without taking any action
* `requeue` - when given a queue URL that has a deadletter queue configured, requeues matching deadletter queue messages back onto the main queue
* `delete` - delete messages from DLQ

The real power of the tool comes in expressions, being able to filter by type and by other criteria

```python
# Only look at old messages
Age > 1 * day
# Only look at some eventbus types
ReceiveCount > 4 and EventType in ("UserUpdate", "UserDelete")
# Find messages that weren't supposed to be there
IsEventBus == false
```

Use the `--event-type` and `--expr` flags to filter on various rules as in the above examples.

### Sending Messages

_WARNING: This tool can be used to enqueue arbitrary EventBus messages onto a queue. Subscribers will not be able to differentiate events enqueued by this tool from those sent by legitmate publishers. DO NOT use this to enqueue messages onto a production service's queue!_

Using the `ship` subcommand, JSON formatted files can be loaded, unmarshalled into their proper EventBus schema protobuf, and enqueued onto the provided SQS queue. The receiving subscriber (using the EventBus client) will receive the message as if it had been published from a real EventBus publisher.

`ship` is useful for setting up integration tests using shell scripts and JSON seed files. Refer to `examples/ship/` for proper JSON file format.

Example usage:
```
# cat ./integ-test-eventbus-seed.json
[
    {
        "event_type": "ClockUpdate",
        "payload": {
            "time": {
                "seconds": 1234,
                "nanos": 4567
            }
        }
    }
    ... <more event json blobs> ...
]
# express-bus ship -f ./integ-test-eventbus-seed.json -u https://integration-test-infra-queue-url
# make integration-tests
```

## Future Improvements
* Allow custom templates to be given so users can customize output to fields they care about
* CI/CD process to distribute binaries and keep the vendored EventBus schema up to date
