MESSAGE BUS PROVIDER

From truxwiki.com
Jump to navigation Jump to search

The Message Bus client gives applications the ability to send and receive messages.

Overview

The message bus client is implemented in a DLL that exposes an entry-point function named TruxtonMessageBus. An application wishing to communicate to the message bus will perform these basic steps:

  1. Manually load the DLL
  2. Get the address of the TruxtonMessageBus function in that library
  3. Call TruxtonMessageBus with the address of the MESSAGE_BUS_PROVIDER
  4. Use the function pointers in MESSAGE_BUS_PROVIDER structure to communicate with the message bus

Interface

struct MESSAGE_BUS_PROVIDER
{
    uint64_t signature;
    void *   library_handle;
    void *   connection_handle;

    MESSAGE_BUS_ANYTHING_FOR_MEDIA anything_for_media;
    MESSAGE_BUS_ARE_ALL_EMPTY      are_all_empty;
    MESSAGE_BUS_CACHE              cache;
    MESSAGE_BUS_CLOSE              clean;
    MESSAGE_BUS_CLOSE              close;
    MESSAGE_BUS_CREATE             create;
    MESSAGE_BUS_DELETE_MEDIA       delete_media;
    MESSAGE_BUS_DELETE_STATUS      delete_status_by_media;
    MESSAGE_BUS_DESTROY            destroy;
    MESSAGE_BUS_GET_LENGTH         exists;
    MESSAGE_BUS_FREE               free_message;
    MESSAGE_BUS_DESTROY            flush;
    MESSAGE_BUS_CLOSE              flush_all;
    MESSAGE_BUS_GET_LENGTH         get_length;
    MESSAGE_BUS_GET_MEDIA_QUEUES   get_media_queues;
    MESSAGE_BUS_GET_STATUS         get_status;
    MESSAGE_BUS_OPEN               open;
    MESSAGE_BUS_RECEIVE            receive;
    MESSAGE_BUS_SEND               send;
    MESSAGE_BUS_SEND               send_status;
};

Structures

struct MESSAGE_QUEUE_STATUS
{
    uint64_t count;
    char name[64];
};

This structure is used when you ask the provider for a list of message queues and the number of messages in them.

Defines

#define MESSAGE_BUS_CLIENT_SIGNATURE (0x746E65696C43424DULL)
#define MESSAGE_BUS_CLIENT_PROVIDER_ENTRY_POINT_NAME "TruxtonMessageBus"

#define MESSAGE_BUS_LOG_INFORMATION (0)
#define MESSAGE_BUS_LOG_WARNING     (1)
#define MESSAGE_BUS_LOG_ERROR       (2)
#define MESSAGE_BUS_LOG_VERBOSE     (3)

Function Types

using MESSAGE_BUS_LOG                = void   (*)(void* logging_handle, int level, char const* message);

// Method to get configuration information from the caller, returns the number of characters written to destination
using MESSAGE_BUS_GET_SETTING = int (*)(void * context, char const * name, char * destination, int destination_size);

using MESSAGE_BUS_ANYTHING_FOR_MEDIA = int    (*)(void * connection_handle, char const * name, GUID const * media_id, uint32_t maximum_stage_number);
using MESSAGE_BUS_CACHE              = int    (*)(void * connection_handle, char const * name, TRUXTON_MESSAGE const * message);
using MESSAGE_BUS_ARE_ALL_EMPTY      = int    (*)(void * connection_handle);
using MESSAGE_BUS_CLOSE              = void   (*)(void * connection_handle);
using MESSAGE_BUS_CREATE             = void   (*)(void * connection_handle, char const * name, uint32_t const queue_type);
using MESSAGE_BUS_DELETE_MEDIA       = void   (*)(void * connection_handle, GUID const * media_id);
using MESSAGE_BUS_DESTROY            = void   (*)(void * connection_handle, char const * name);
using MESSAGE_BUS_FREE               = void   (*)(void * connection_handle, TRUXTON_MESSAGE const * message);
using MESSAGE_BUS_GET_LENGTH         = int    (*)(void * connection_handle, char const * name);
using MESSAGE_BUS_GET_MEDIA_QUEUES   = int    (*)(void * connection_handle, GUID const * media_id, char * destination, int destination_size);
using MESSAGE_BUS_GET_STATUS         = int    (*)(void * connection_handle, MESSAGE_QUEUE_STATUS * array_of_status_structures, int maximum_number_of_status_structures);
using MESSAGE_BUS_OPEN               = void * (*)(void * library_handle, void * setting_context, MESSAGE_BUS_GET_SETTING, void * logging_context, MESSAGE_BUS_LOG);
using MESSAGE_BUS_RECEIVE            = int    (*)(void * connection_handle, char const * name, TRUXTON_MESSAGE * message);
using MESSAGE_BUS_SEND               = void   (*)(void * connection_handle, char const * name, TRUXTON_MESSAGE const * message);
using MESSAGE_BUS_DELETE_STATUS      = void   (*)(void * connection_handle, GUID const * media_id, int stage);

using MESSAGE_BUS_CLIENT_PROVIDER_ENTRY_POINT = void (*)(MESSAGE_BUS_PROVIDER *);

Interface Members

Data

signature

This is set to MESSAGE_BUS_CLIENT_SIGNATURE when the structure is initialized. If signature is not equal to MESSAGE_BUS_CLIENT_SIGNATURE then the contents of the structure are invalid and should not be used.

library_handle

This is the handle to the shared library that implements the Message Bus Client interface.

connection_handle

This is a member for use by callers as a convenient place to store the handle used as the first parameter to the methods in this interface. It is an opaque pointer to a structure that only the implementer knows of the contents.

Methods

anything_for_media

int anything_for_media(void * connection_handle, char const * name, GUID const * media_id, uint32_t maximum_stage_number);

This method is used when the caller wants to know if there are any messages in any queue for a particular piece of media.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the message queue to query.
media_id GUID const * The globally unique identifier of the media to query.
maximum_stage_number uint32_t The maximum stage of the message.

Return Value

anything_for_media will return zero when there are no messages for the given media, one when there is at lease a single message in any message queue for this media.

Sample Code

#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING

// Don't use min/max macros
#define NOMINMAX

#define _USE_MATH_DEFINES
#include <crtdbg.h>
#include <stdint.h>
#include <inttypes.h>
#include <ciso646>
#include <limits>
#include <random>
#include <windows.h>
#include <messagebusprovider.h>
#include <messagebusloader.h>
#pragma hdrstop

#if defined( _DEBUG ) && defined( _INC_CRTDBG )
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif // _DEBUG

#define I_AM_EQUAL_TO_THAT (0)

// This function is implemented by the caller to give settings to the provider of the message bus
static int get_setting(void * context, char const * setting_name, char * destination, int destination_size)
{
    if (setting_name == nullptr or setting_name[0] == 0x00)
    {
        return(0);
    }

    if (destination == nullptr)
    {
        return(0);
    }

    if (destination_size < 2)
    {
        return(0);
    }

    destination[0] = 0x00;

    if (_strcmpi(setting_name, "mqserver") == I_AM_EQUAL_TO_THAT)
    {
        strcpy_s(destination, destination_size, "localhost");
    }
    else if (_strcmpi(setting_name, "appname") == I_AM_EQUAL_TO_THAT)
    {
        strcpy_s(destination, destination_size, "MB Test Harness");
    }
    else if (_strcmpi(setting_name, "mqport") == I_AM_EQUAL_TO_THAT)
    {
        strcpy_s(destination, destination_size, "5432");
    }
    else if (_strcmpi(setting_name, "mqname") == I_AM_EQUAL_TO_THAT)
    {
        strcpy_s(destination, destination_size, "TruxtonMessageBus");
    }
    else if (_strcmpi(setting_name, "mquser") == I_AM_EQUAL_TO_THAT)
    {
        strcpy_s(destination, destination_size, "postgres");
    }
    else if (_strcmpi(setting_name, "mqpassword") == I_AM_EQUAL_TO_THAT)
    {
        strcpy_s(destination, destination_size, "Truxton4n6");
    }

    return(static_cast<int>(strlen(destination)));
}

// If the provider needs to log something, it will use this function
static void logging_function(void * logging_context, int level, char const * message)
{
    if (level == MESSAGE_BUS_LOG_ERROR)
    {
        printf("ERROR: %s\n", message);
    }
    else if (level == MESSAGE_BUS_LOG_WARNING)
    {
        printf("Warning: %s\n", message);
    }
    else if (level == MESSAGE_BUS_LOG_INFORMATION)
    {
        printf("%s\n", message);
    }
}

int main(int number_of_arguments, char **arguments)
{
    // Enable memory leak reporting when program exits
    _CrtSetDbgFlag((_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) bitor _CRTDBG_LEAK_CHECK_DF));

    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    GUID media_id;
    CLSIDFromString( L"{12345678-1234-1234-1234-123456789ABC}", &media_id);

    if (provider.anything_for_media(provider.connection_handle, queue_name, &media_id, std::numeric_limits<std::int32_t>::max() - 1) not_eq 1)
    {
        printf("No message queue contains a message for media.\n");
    }
    else
    {
        printf("Someone has at least one message waiting for the media.\n");
    }

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

are_all_empty

int are_all_empty(void * connection_handle);

This method is used when the caller wants to know if there are any messages in any queue.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.

Return Value

are_all_empty will return zero when there are no messages in the bus, one when there is at lease a single message in any message queue.

Sample Code

For the complete code, please see the sample for anything_for_media method.

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    if (provider.are_all_empty(provider.connection_handle) not_eq 0)
    {
        printf("The message queues are empty.\n");
    }
    else
    {
        printf("The message queues are not empty.\n");
    }

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

cache

int cache(void * connection_handle, char const * name, TRUXTON_MESSAGE const * message);

This method allows the caller to cache messages for a queue locally before sending them to the server. Messages aren't sent to the server until flush or flush_all is called.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the queue to receive the message.
message TRUXTON_MESSAGE const * The message to send.

Return Value

cache will return zero on error or the number of messages in the cache on success.

Sample Code

For the complete code, please see the sample for anything_for_media method.

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle== nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    TRUXTON_MESSAGE message;

    while( get_message_to_send( message ) == true )
    {
        if (provider.cache(provider.connection_handle, "adric", &message ) ==0)
        {
            printf("Could not cache message for adric.\n");
        }
    }

    provider.flush(provider.connection_handle, "adric");

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

clean

void clean(void * connection_handle);

This method will tidy up the messages queues should they need it. This is generally considered to be a periodic maintenance function.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.

Sample Code

For the complete code, please see the sample for anything_for_media method.

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    provider.clean(provider.connection_handle);

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

close

void close(void * connection_handle);

This method closes the connection to the server.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.

Sample Code

For the complete code, please see the sample for anything_for_media method.

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    provider.clean(provider.connection_handle);

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

create

void create(void * connection_handle, char const * name, uint32_t const queue_type);

This method will create a new message queue on the server.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the new queue.
queue_type uint32_t const 1 for an ETL queue.

Sample Code

For the complete code, please see the sample for anything_for_media method.

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    provider.create(provider.connection_handle, "adric", 1);

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

delete_media

void delete_media(void * connection_handle, GUID const * media_id);

This method will delete from all queues the messages regarding the media id given.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
media_id GUID const * The globally unique identifier for the media.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    // Enable memory leak reporting when program exits
    _CrtSetDbgFlag((_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) bitor _CRTDBG_LEAK_CHECK_DF));

    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    GUID media_id;
    CLSIDFromString( L"{12345678-1234-1234-1234-123456789ABC}", &media_id);

    provider.delete_media(provider.connection_handle, &media_id);

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

delete_status_by_media

void delete_status_by_media(void * connection_handle, GUID const * media_id, int stage);

This method deletes all messages in the "status" queue (the message queue for the Load Status Monitor) for the given media id and less than or equal to the given stage number. This is typically called when a load is being cancelled and you want all work to cease.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
media_id GUID const * The globally unique identifier for the media.
stage int The maximum (inclusive) stage number of message to delete.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    // Enable memory leak reporting when program exits
    _CrtSetDbgFlag((_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) bitor _CRTDBG_LEAK_CHECK_DF));

    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    GUID media_id;
    CLSIDFromString( L"{12345678-1234-1234-1234-123456789ABC}", &media_id);

    provider.delete_status_by_media(provider.connection_handle, &media_id, 255);

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

destroy

void destroy(void * connection_handle, char const * name);

This method will delete message queue of the given name. It is the opposite of create.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the message queue to destroy.

Sample Code

For the complete code, please see the sample for anything_for_media method.

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    provider.destroy(provider.connection_handle, "adric");

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

exists

int exists(void * connection_handle, char const * name);

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the message queue to find.

Return Value exists will return zero if the message queue does not exist in the message bus, one when message queue exists in the message bus.

Sample Code

For the complete code, please see the sample for anything_for_media method.

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle= provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle== nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    if ( provider.exists(provider.connection_handle, "adric") == 1 )
    {
        printf( "adric LIVES!!\n" );
    }

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

free_message

void free_message(void * connection_handle, TRUXTON_MESSAGE const * message);

This method is called after receiving a message. It will free any resources allocated by the provider before giving the message to you.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
message TRUXTON_MESSAGE const * The message obtained by a call to receive.
stage int The maximum (inclusive) stage number of message to delete.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    TRUXTON_MESSAGE received_message;

    received_message.Empty();

    if (provider.receive(provider.connection_handle, "adric", &received_message) == 0)
    {
        printf("FAIL! Can't read from queue\n");
    }
    else
    {
        if ( received_message.IsEmpty() == true )
        {
            printf( "The adric message queue is empty.\n" );
        }
        else
        {
            // The messages contains data we need to process
            handle_message(received_message);
        }

        provider.free_message(provider.connection_handle, &received_message);
    }

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

flush

void flush(void * connection_handle, char const * name);

This method will transmit any messages waiting to be sent by calls to cache.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the message queue to flush.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle= provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle== nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    provider.flush(provider.connection_handle, "adric");

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

flush_all

void flush_all(void * connection_handle);

This method will commit all messages in all queues to the server. This will send all messages saved by any call to cache regardless of which queue was specified.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle= provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle== nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    provider.flush_all(provider.connection_handle);

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

get_length

int get_length(void * connection_handle, char const * name);

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the message queue.

Return Value get_length will return the number of messages waiting to be retrieved in the given queue.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    int const count = provider.get_length(provider.connection_handle, "adric");

    printf( "There are %d items in the adric message queue.\n" );

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

get_media_queues

int get_media_queues(void * connection_handle, GUID const * media_id, char * destination, int destination_size);

This method retrieves a comma separated list of message queue names that contain at least one message regarding the given media identifier.

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
media_id GUID const * The globally unique identifier for the media.
destination char * The buffer to write to.
destination_size int The maximum number of bytes that can be written to the destination buffer.

Return Value get_media_queues will return the number of bytes written to the destination buffer.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle= provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle== nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    GUID media_id;
    CLSIDFromString( L"{12345678-1234-1234-1234-123456789ABC}", &media_id);

    char queue_names[1024];

    if ( provider.get_media_queues(provider.connection_handle, &media_id, queue_names, sizeof(queue_names)) > 0 )
    {
        printf( "Media is being processed by %s\n", queue_names );
    }
    else
    {
        printf( "Media isn't being processed by anybody.\n" );
    }

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

get_status

int get_status(void * connection_handle, MESSAGE_QUEUE_STATUS * array_of_status_structures, int maximum_number_of_status_structures);

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
array_of_status_structures MESSAGE_QUEUE_STATUS * An array of status structures to be filled with data..
maximum_number_of_status_structures int The maximum number of structures to fill.

Return Value get_status will return the number of structures written.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    MESSAGE_QUEUE_STATUS statii[100];

    int const number_of_entries = provider.get_status( provider.connection_handle, statii, std::size(statii));

    for( int array_index = 0; array_index < number_of_entries; array_index++ )
    {
        printf( "%s : %" PRIu64 "\n", statii[ array_index ].name, statii[ array_index ].count );
    }

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

open

void * open(void * library_handle, void * setting_context, MESSAGE_BUS_GET_SETTING get_setting, void * logging_context, MESSAGE_BUS_LOG log);

Parameters

Name Type Meaning
library_handle void * The handle to the provider library.
setting_context void * An optional opaque pointer used by the function that provides settings to the provider.
get_setting MESSAGE_BUS_SETTING The pointer to a function the provider should use to retrieved configuration settings.
logging_context void * An optional opaque pointer used by the logging function passed to the provider.
log MESSAGE_BUS_LOG An optional pointer to a function used by the provider to log its actions.

Return Value open will return a non-null value when a connection to the server is successful, nullptr on failure.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    provider.destroy(provider.connection_handle, "adric");

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

receive

int receive(void * connection_handle, char const * name, TRUXTON_MESSAGE * message);

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the message queue to retrieve a message.
message TRUXTON_MESSAGE * The address of a message structure to be filled in by the call.

Return Value receive will return one on success, zero on failure.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    TRUXTON_MESSAGE received_message;

    received_message.Empty();

    if (provider.receive(provider.connection_handle, "adric", &received_message) == 0)
    {
        printf("FAIL! Can't read from queue\n");
    }
    else
    {
        if ( received_message.IsEmpty() == true )
        {
            printf( "The adric message queue is empty.\n" );
        }
        else
        {
            // The messages contains data we need to process
            handle_message(received_message);
        }

        provider.free_message(provider.connection_handle, &received_message);
    }

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

send

void send(void * connection_handle, char const * name, TRUXTON_MESSAGE const * message);

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the message queue destined to receive the message.
message TRUXTON_MESSAGE const * The message to send.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    GUID file_id;
    CLSIDFromString( L"{12345678-1234-1234-1234-123456789ABC}", &file_id);

    TRUXTON_MESSAGE message;

    get_file_from_truxton(&file_id, &message);

    provider.send(provider.connection_handle, "adric", &message);

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}

send_status

void send_status(void * connection_handle, char const * name, TRUXTON_MESSAGE const * message);

Parameters

Name Type Meaning
connection_handle void * The handle to the message bus.
name char const * The name of the message queue.
message TRUXTON_MESSAGE cosnt * The message containing status information.

Sample Code

int main(int number_of_arguments, char **arguments)
{
    if (number_of_arguments < 2)
    {
        printf("Usage: MBTest dllpath\n");
        return(EXIT_SUCCESS);
    }

    MESSAGE_BUS_PROVIDER provider;

    // Load the implementation of a Message Bus Provider in the given filename
    auto library_handle = load_message_bus_provider(arguments[1], &provider);

    if (library_handle == nullptr )
    {
        return(EXIT_FAILURE);
    }

    // Open (establish a connection to the message bus server) giving the
    // provider the functions to get settings and report information back to us
    provider.connection_handle = provider.open(provider.library_handle, nullptr, get_setting, nullptr, logging_function);

    if (provider.connection_handle == nullptr)
    {
        unload_message_bus_provider(&provider);
        return(EXIT_FAILURE);
    }

    GUID etl_id;
    CLSIDFromString( L"{12345678-1234-1234-1234-123456789ABC}", &etl_id);

    TRUXTON_STATUS_MESSAGE status_message;

    status_message.Empty();
    status_message.MakeIdle();
    status_message.ETL_ID.Copy(etl_id);
    status_message.Stage = status_message.ETL_ID.Stage();

    TRUXTON_MESSAGE message;

    message.Empty();

    status_message.CopyTo(message);

    provider.send_status(provider.connection_handle, "status", &message);

    // close any connection the provider may have opened
    provider.close(provider.connection_handle);

    // Unload the provider from memory
    unload_message_bus_provider(&provider);

    return(EXIT_SUCCESS);
}