Skip to main content

Local Testing

Our RabbitMQ docker image, called "Baby Steps", is pre-loaded with Bayes Live Odds test data. It can be used to set up a local testing environment for offline integration testing. This integration can be the foundation block for final integration — you will only need to change the config and credentials according to the Bayes Live Odds Production Differences.

Baby Steps: Customer documentation

Notes:

  • The usage examples are for Linux/MacOS, and they may vary on Windows.
  • Fixture data usually received through the Fixtures API is not integrated into babysteps.

Run Bayes Live Odds Babysteps container

# Start the container, do not modify hostname
docker run -it \
--hostname live-odds-babysteps -p 5672:5672 \
public.ecr.aws/bayesgg/bayes-live-odds-babysteps:2.1

Connect and Consume

Assuming

  1. You are using the logging_consumer.
  2. The bayes-live-odds-babysteps container is running on the same host (i.e. reachable via localhost and not running on some remote host or in a virtual machine).
export DOCKERHOST=localhost
export RABBITMQ_CONSUME_URI=amqp://live-odds-babysteps:wK9HJafO1yJt@${DOCKERHOST}/egest
export RABBITMQ_QUEUE_NAME=babysteps.outbox
python logging_consumer.py

This will connect to bayes-live-odds-babysteps and start consuming the messages. It will simply log the message body for each message.

If you are not using the logging_consumer, make sure to configure your RabbitMQ/AMQP client as follows:

username     : live-odds-babysteps
password : wK9HJafO1yJt
vhost : egest
queue : babysteps.outbox
queue_declare: false

Logging Consumer

RabbitMQ consumer that logs to console and file. (Click here to expand)
#!/usr/bin/env python

# Copyright 2019, Bayes Esports Solutions GmbH, all rights reserved.

# Requirements:
# kombu (pip install kombu)

# Usage:
# $ export RABBITMQ_CONSUME_URI=amqps://{user}:{password}@{host}/{vhost}
# $ export RABBITMQ_QUEUE_NAME=foobar.outbox
# $ python logging_consumer.py

import logging
import os
import sys
import time

from kombu import Connection, Queue, disable_insecure_serializers
from kombu.mixins import ConsumerMixin

logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

disable_insecure_serializers()


class WorkerConfig(object):
"""Container to hold some configuration."""
def __init__(self):
self.rabbitmq_consume_uri = os.environ['RABBITMQ_CONSUME_URI']
self.queue = os.environ['RABBITMQ_QUEUE_NAME']
self.prefetch_count = int(os.environ.get('PREFETCH', '10'))

try:
self.stop_after = int(os.environ.get('STOP_AFTER_MESSAGES', ''))
except ValueError:
self.stop_after = None

self.savefile = os.environ.get('SAVEFILE', 'consumer-{}.json'.format(int(time.time())))
self.savefile = os.path.abspath(os.path.expanduser(self.savefile))
logger.info('Savefile is %s', self.savefile)


class Worker(ConsumerMixin):
"""RabbitMQ Consumer that consumers messages and saves them into a file, 1 message per line.
Stops after consuming `config.stop_after` number of messages if provided.
"""
def __init__(self, config=None):
self.config = config if config is not None else WorkerConfig()

self.connection = Connection(config.rabbitmq_consume_uri, heartbeat=30)
self.queue = Queue(config.queue, no_declare=True)

self.stop_after = config.stop_after
self.message_counter = 0

def get_consumers(self, Consumer, channel):
return [
Consumer(queues=[self.queue], callbacks=[self.on_message], prefetch_count=self.config.prefetch_count),
]

def on_message(self, body, message):
logger.info('Received message body with length: %d\n%s', len(body), body)

with open(self.config.savefile, 'a') as f:
f.write(body)
f.write('\n')
message.ack()

self.message_counter += 1
if self.stop_after is not None and self.message_counter == self.stop_after:
sys.exit(0)


if __name__ == '__main__':
config = WorkerConfig()
worker = Worker(config=config)

try:
worker.run()
except KeyboardInterrupt:
worker.should_stop = True

Bayes Live Odds Production Differences

The parts making up RABBITMQ_CONSUME_URI would be different.

  • AMQPS (encrypted) instead of AMQP. For production, you would use amqps://*** in python. Other languages/client libraries might require explicit port=5671, ssl=True.
  • The connection parameters (username, password, hostname, queue name) will be different as well.

Troubleshooting

AWS ECR Authentication

If you get the following error:

Error response from daemon: pull access denied for public.ecr.aws/bayesgg/bayes-live-odds-babysteps, repository does not exist or may require 'docker login': denied: Your authorization token has expired. Reauthenticate and try again.

logout from the repository first.

docker logout public.ecr.aws