Sign inSign up

troperty/customerapi-mb2-simulator

By troperty

Updated 3 months ago

Message Broker 2 simulator

Image
0

10K+

troperty/customerapi-mb2-simulator repository overview

customerapi-mb2-simulator

A simulation of the most significant functions for MessageBroker 2.0 API customers. See below for running and usage instructions.

Running

Run the simulator as a Docker container, locally or anywhere else. It is standalone and requires no external setup.

docker run -it -p 3000:3000 troperty/customerapi-mb2-simulator

This will start the simulator in interactive mode and forward port 3000 to port 3000 of the container. Thus, if you started it locally the simulator API will be available under

http://<simulator-IP>:3000/...

A note on timeouts

Both the retrieving operations, long polling and websocket (see below), depends on that your environment can handle their connection requirements. For instance the behavior of long polling will not be the desired if your network terminates the connection before rougly 60 seconds has passed. Similarly for websocket your network must understand and respect the heart beats of such a connection and not treat it as timed out.

A note on protocols

As you will notice when reading below the protocols for the simulator are HTTP and WS. In reality, when using the production system, then obviously the protocols are HTTPS and WSS.

Usage

Below here we list the different functions and how to use them in the simulator. The simulator Swagger UI can also give you some hints. You reach the Swagger UI by pointing your browser to:

http://<simulator-IP>:3000/api-docs/

Thus if you installed the simulator locally it should be:

http://localhost:3000/api-docs/

Inserting "real time" messages

When you start the simulator, it will not have any data available. So immediately searching for data will result in 204 NO CONTENT.

To be able to get anything out you must put something in first! The endpoint for doing so is:

POST
http://<simulator-IP>:3000/api/message

This is not an endpoint that you as a customer will use in your integration, it's merely here because you need to be able to insert something into the system. You can insert any data but the idea is that you will insert example real time data files and verify that you can handle the format(s) from long polling and websocket respectively (see below).

There is a defined list of valid channels in the simulator. If you send messages of those types, you will get a 200 OK back. If you send in anything else you will get a 400 BAD REQUEST accompanied by an error message.

List of Durable channels

These channels are persisted in the DB and an eventId is generated for each event of this type. These events can be searched later by calling the /events and /filtered-events APIs.

TrackConditionTrot, TrackConditionGallop, RaceDayTrot, RaceDayGallop, RaceDayCanceledTrot, RaceDayCanceledGallop, RaceDayTransferredTrot, RaceDayTransferredGallop, RaceDayStatsDrivers, RaceDayStatsJockeys, RaceDayStatsTrainersTrot, RaceDayStatsTrainersGallop, RacingCardRaceTrot, RacingCardRaceGallop, RacingCardRaceMinorTrot, RacingCardRaceMinorGallop, RaceDayStatsHorsesTrot, RaceDayStatsHorsesGallop, RaceDayStatsHorsesMinorTrot, RaceDayStatsHorsesMinorGallop, RaceCanceledTrot, RaceCanceledGallop, RaceCanceledMinorTrot, RaceCanceledMinorGallop, StartTimeChangedTrot, StartTimeChangedGallop, StartTimeChangedMinorTrot, StartTimeChangedMinorGallop, RaceDistanceChanged, RaceDistanceChangedMinor, StartMethodChangedTrot, StartMethodChangedMinorTrot, StatusMessageTrot, StatusMessageGallop, StatusMessageMinorTrot, StatusMessageMinorGallop, RaceStartedTrot, RaceStartedGallop, RaceStartedMinorTrot, RaceStartedMinorGallop, RaceRestartedTrot, RaceRestartedGallop, RaceRestartedMinorTrot, RaceRestartedMinorGallop, RaceFinishedTrot, RaceFinishedGallop, RaceFinishedMinorTrot, RaceFinishedMinorGallop, RaceResultFastTrot, RaceResultFastGallop, RaceResultFastMinorTrot, RaceResultFastMinorGallop, RaceResultTrot, RaceResultGallop, RaceResultMinorTrot, RaceResultMinorGallop, FullImageReadyTrot, FullImageReadyMinorTrot, WinningImageReadyTrot, WinningImageReadyMinorTrot, PhotofinishAnalysisTrot, PhotofinishAnalysisMinorTrot, DriverChanged, JockeyChanged, DriverChangedMinor, JockeyChangedMinor, TrainerChangedTrot, TrainerChangedGallop, TrainerChangedMinorTrot, TrainerChangedMinorGallop, ScratchingTrot, ScratchingGallop, ScratchingMinorTrot, ScratchingMinorGallop, WeightChangedGallop, WeightChangedMinorGallop, ShoeInfoChanged, ShoeInfoChangedMinor, SulkyInfoChanged, SulkyInfoChangedMinor, TrackChangeTrot, TrackChangeGallop

List of Transient channels

These events are not persisted, and just broadcasted to the connected WebSockets.

TimeToStartTrot, TimeToDefTrot, TimeResetTrot, SplitTimesTrot, PrelDisqualifiedHorsesTrot, Last500MetersTrot, TimeToStartMinorGallop, TimeToDefMinorGallop, SplitTimesMinorGallop, TimeToStartMinorTrot, TimeToDefMinorTrot, SplitTimesMinorTrot, TimeToStartGallop, TimeToDefGallop, TimeResetGallop, SplitTimesGallop, PrelDisqualifiedHorsesGallop, Last500MetersGallop, RaceStartedTrot, RaceStartedGallop, RaceStartedMinorTrot, RaceStartedMinorGallop, RaceRestartedTrot, RaceRestartedGallop, RaceRestartedMinorTrot, RaceRestartedMinorGallop, RaceFinishedTrot, RaceFinishedGallop, RaceFinishedMinorTrot, RaceFinishedMinorGallop

List of special channels

The following channels behave as both Durable as well as Transient channels. I.e. these will be persisted as well as broadcasted over WebSockets.

RaceStartedTrot, RaceStartedGallop, RaceStartedMinorTrot, RaceStartedMinorGallop, RaceRestartedTrot, RaceRestartedGallop, RaceRestartedMinorTrot, RaceRestartedMinorGallop, RaceFinishedTrot, RaceFinishedGallop, RaceFinishedMinorTrot, RaceFinishedMinorGallop

List of channels in your subscription

You won't receive any data for channels other than these.

TrackConditionTrot, RaceDayTrot, RaceResultFastTrot, StartTimeChangedTrot, ScratchingTrot, DriverChanged, RaceDayStatsDrivers, RaceDayStatsTrainersTrot, ShoeInfoChanged, SulkyInfoChanged, TrainerChangedTrot, StatusMessageTrot, RacingCardRaceTrot, RaceResultTrot, RaceFinishedTrot, RaceStartedTrot, RaceRestartedTrot, TimeToStartTrot, TimeToDefTrot, TimeResetTrot, SplitTimesTrot, PrelDisqualifiedHorsesTrot, Last500MetersTrot, RaceCanceledTrot, RaceDayCanceledTrot, RaceDayTransferredTrot, StartMethodChangedTrot, TrackChangeTrot

Operation

This is the format in which you have to POST a request to the API

{
	"channel": "<CHANNEL_NAME>",
	"meta": {
		"date": "YYYY-MM-DD",
		"trackId": <Number>,
		"raceNr": <Number>,
		"startNr": <Number>,
	},
	"data": {
		.... // Payload data
	}
}

Here, trackId, raceNr, and startNr are optional fields.

In case you have sent a Durable message, you will receive a response in the following format:

{
	"status": "success",
	"data": {
		"durable": {
			"eventId": 1,
			"channel": "<CHANNEL_NAME>",
			"date": "YYYY-MM-DD",
			"trackId": <Number>,
			"raceNr": <Number>,
			"startNr": <Number>,
			"payload": {
				.... // Payload fields
			}
		}
	}
}

In case you have sent a Transient message, you will receive a response in the following format:

{
    "status": "success",
    "data": {
        "transient": "Broadcasted to number of users: <NUMBER_OF_USERS>"
    }
}

Here, NUMBER_OF_USERS will be the users who are connected to the WebSocket right now and have subscriibed to that channel.

If there is a channel that behaves has both Durable and Transient, then it will include both durable and transient fields.

Replay of "real time" messages

You can run the same docker image with an optional environment variable to have it automatically create the events that are made available for download.

docker run -p 3000:3000 -e "AUTO_REPLAY_MESSAGE_INTERVAL=5000" troperty/customerapi-mb2-simulator

Here, you can change the value 5000 milliseconds to any number of milliseconds based on your needs. It will generate one message after every interval.

Also, you can pass an optional environment variable with AUTO_REPLAY_MESSAGE_INTERVAL.

docker run -p 3000:3000 -e "AUTO_REPLAY_MESSAGE_INTERVAL=5000" -e "INITIAL_DELAY=30000" troperty/customerapi-mb2-simulator

If INITIAL_DELAY is not passed, it will default to to whatever value of AUTO_REPLAY_MESSAGE_INTERVAL is set. But, if you want some more time to connect your web-socket to the server after start-up, or for whatever other reason, you can get more time by setting INITIAL_DELAY.

The rest of the functions of the simulator will still continue to function as is.

Authenticating - part of customer API

POST
http://<simulator-IP>:3000/customerapi/authenticate/subscription

The credentials are passed as body payload and the Swagger UI suggested values are the correct values in the simulator:

{
    "key": "mykey",
    "secret": "mysecret"
}

Pass any other values to test the behavior when authentication fails.

When authentication is successful you'll get a Bearer token back in the response. In reality this token has a validity and is bound to your identity, so you MUST keep it and pass it back to the API when making other request. In the simulator we've made it a bit easier. You'll get it back from the authentication but it's always the same for everyone so you don't have to do the auth step every time if you don't want to. The token is:

Bearer dGVzdHVzZXI=

Durable flow - part of customer API

API with possible long poll

The durable flow is the "slower" part of the real time data flow. It often has a somewhat longer validity and is made up of such things as startlists, statistics, etc. The endpoint for long polling real time data is:

GET
http://<simulator-IP>:3000/customerapi/events

You need to pass your Bearer token or else you'll get 401 UNAUTHORIZED back. If no data is available matching your criteria, then only the long polling will happen. The long poll will last for roughly 60 seconds if no message is available. If the data is available, it will be returned immediately.

For more information on this API, see the documentation here.

API without long poll

You can also search for a specific channel's data using the following API:

GET
http://<simulator-IP>:3000/customerapi/filtered_events

You need to pass your Bearer token or else you'll get 401 UNAUTHORIZED back. There is no long poll in this API. If data matching your criteria does not exist, it will return back with 204 NO CONTENT immediately.

For more information on this API, see the documentation here.

Transient flow - Websocket - part of customer API

The transient flow is the "faster" part of the real time data flow. Normally the validity of its messages is very short and is made up of such things as countdown to start, late scratchings, etc. The endpoint for connecting to websocket real time data is:

ws://<simulator-IP>:3000/customerapi/event-stream

When you connect to the WebSocket, you will get a message like this:

{
    "type": "Connection",
    "message": "Connection is established. Awaiting auth token within 10 seconds",
    "timestamp": "2023-11-30T12:19:54.179Z",
    "id": "f02ce795-5a65-4527-9250-dcb35ac5d0a3"
}

You have to send the first message as a plain-text message with the authentication token dGVzdHVzZXI= within 10 seconds.

If you send the correct auth token dGVzdHVzZXI= within 10 seconds, your connection will be authenticated with the following message.

{
    "type": "Authenticated",
    "message": "Connection is authenticated.",
    "timestamp": "2023-11-30T12:20:01.575Z",
    "id": "f02ce795-5a65-4527-9250-dcb35ac5d0a3"
}

After this only, the Transient messages of the channels you have subscribed to will be received on the WebSocket.

For more information on this WebSocket endpoint, see the documentation here.

Tag summary

Content type

Image

Digest

sha256:7b4ba0bc1

Size

64.7 MB

Last updated

3 months ago

docker pull troperty/customerapi-mb2-simulator