[PATCH 1/3] [MAMAC] mamaPlugin Feature - additional


Gary Molloy <g.molloy@...>
 

From 76a6db152998cbb32de58eb1cb9d6c1ab9307a1e Mon Sep 17 00:00:00 2001

From: Gary Molloy <g.molloy@...>

Date: Wed, 29 Apr 2015 13:05:23 -0400

Subject: [PATCH] [MAMAC] mamaPlugin Feature - addition

 

Addition to the existing mamaPlugin patch to remove references to internal shared objects and a missing null check.

 

Signed-off-by: Gary Molloy <g.molloy@...>

---

mama/c_cpp/src/c/plugin.c |   61 ++++++++++++++++++++------------------------

1 files changed, 28 insertions(+), 33 deletions(-)

 

diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c

index b6475fe..303ab9f 100644

--- a/mama/c_cpp/src/c/plugin.c

+++ b/mama/c_cpp/src/c/plugin.c

@@ -216,9 +216,6 @@ mama_initPlugins(void)

         }

     }

-    mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising mamacenterprise");

-    mama_loadPlugin ("mamacenterprise");

-

     return MAMA_STATUS_OK;

}

@@ -243,15 +240,10 @@ mama_loadPlugin (const char* pluginName)

     if (pluginImpl == NULL)

     {

        /* The plugin name should be of the format mamaplugin<name> */

-        if (strncmp(pluginName, "mamacenterprise", MAX_PLUGIN_STRING) == 0)

-            snprintf(loadPluginName, MAX_PLUGIN_STRING,

-                "%s",

-                pluginName);

-        else

-            snprintf(loadPluginName, MAX_PLUGIN_STRING,

-                "%s%s",

-                PLUGIN_NAME,

-                pluginName);

+        snprintf(loadPluginName, MAX_PLUGIN_STRING,

+            "%s%s",

+            PLUGIN_NAME,

+            pluginName);

         pluginLib = openSharedLib (loadPluginName, NULL);

@@ -345,31 +337,34 @@ mama_shutdownPlugins (void)

     for (plugin = 0; plugin <= gPluginNo; plugin++)

     {

-        if (gPlugins[plugin]->mPluginHandle != NULL)

+        if (gPlugins[plugin] != NULL)

         {

-            /* Fire the user shutdown hook first - if one is present */

-            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            if (gPlugins[plugin]->mPluginHandle != NULL)

             {

-                gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

-            }

+                /* Fire the user shutdown hook first - if one is present */

+                if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+                {

+                    gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+                }

-            ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

-            if (0!=ret)

-            {

-                 mama_log (MAMA_LOG_LEVEL_WARN,

-                            "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

-                            gPlugins[plugin]->mPluginName);

-            }

-            else

-            {

-                 mama_log (MAMA_LOG_LEVEL_WARN,

-                            "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

-                            gPlugins[plugin]->mPluginName);

-            }

+                ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

+                if (0!=ret)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+                else

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

+                                gPlugins[plugin]->mPluginName);

+                }

-            free ((char*)gPlugins[plugin]->mPluginName);

-            free (gPlugins[plugin]);

-            gPlugins[plugin] = NULL;

+                free ((char*)gPlugins[plugin]->mPluginName);

+                free (gPlugins[plugin]);

+                gPlugins[plugin] = NULL;

+            }

         }

     }

     return status;

--

1.7.1

 

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 

From: openmama-dev-bounces@... [mailto:openmama-dev-bounces@...] On Behalf Of Gary Molloy
Sent: 23 April 2015 17:54
To: openmama-dev@...
Subject: [Openmama-dev] [PATCH 1/3] [MAMAC] mamaPlugin Feature

 

Testing Strategy:-

Not middleware or O/S specific. 
 

Using the attached template you can create your own plugin and load it in via your mama.properties, for example:

 

mama.plugin.name_0=template

 

You can run up a mamaPublisher to test your plugin, for example:

 

mamapublisherc -tport pub -m wmw -l MAMA_INBOUND_TOPIC -v -v -v -v -v

 

You can expect to see output similar this if your plugin was loaded successfully:

 

2015-04-09 13:45:02: (f9018280) : mama_initPlugins(): Initialising [mama.plugin.name_0] template 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Sucessfully registered plugin functions for [template] 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Successfully run the init hook for mama plugin [template]  

 

If your plugin was not loaded successful you can expect to see output similar to this:

 

2015-04-09 13:45:02: (f9018280) : mama_initPlugins(): Initialising [mama.plugin.name_0] template 

2015-04-09 13:45:02: (f9018280) : mamaPlugin_registerFunctions(): Cannot load plugin, does not implement required function: [templateMamaPlugin_shutdownHook] 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Failed to register plugin functions for [template] 

 

Further documentation on the mamaPlugin feature will be available shortly which will provide more details on the feature which will include the various hooks available etc...

 

 

=========================================================================================================

 

From e2a6a3f9c5750cee780cb6185a1310b4e4b70629 Mon Sep 17 00:00:00 2001

From: Gary Molloy <g.molloy@...>

Date: Thu, 23 Apr 2015 11:22:14 -0400

Subject: [PATCH 1/3] [MAMAC] mamaPlugin Feature

 

A new feature, mamaPlugin has been introduced that will allow you to

create and run your own code within 'hooks' into the MAMA codebase.

 

A mamaPlugin is essentially a shared object.

 

Signed-off-by: Gary Molloy <g.molloy@...>

---

mama/c_cpp/src/c/Makefile.am    |    1 +

mama/c_cpp/src/c/SConscript     |    1 +

mama/c_cpp/src/c/SConscript.win |    1 +

mama/c_cpp/src/c/mama.c         |   10 +-

mama/c_cpp/src/c/mama/types.h   |   10 +

mama/c_cpp/src/c/plugin.c       |  472 +++++++++++++++++++++++++++++++++++++++

mama/c_cpp/src/c/plugin.h       |   59 +++++

mama/c_cpp/src/c/publisher.c    |   10 +

mama/c_cpp/src/c/transport.c    |   21 ++-

9 files changed, 579 insertions(+), 6 deletions(-)

create mode 100644 mama/c_cpp/src/c/plugin.c

create mode 100644 mama/c_cpp/src/c/plugin.h

 

diff --git a/mama/c_cpp/src/c/Makefile.am b/mama/c_cpp/src/c/Makefile.am

index c831ce4..318c353 100644

--- a/mama/c_cpp/src/c/Makefile.am

+++ b/mama/c_cpp/src/c/Makefile.am

@@ -131,6 +131,7 @@ libmama_la_SOURCES = \

     mamaStrUtils.h \

     mamaStrUtils.c \

               marketdata.c \

+    plugin.c \

     middleware.c \

               msg.c \

               msgfield.c \

diff --git a/mama/c_cpp/src/c/SConscript b/mama/c_cpp/src/c/SConscript

index 4362f50..f47e18c 100644

--- a/mama/c_cpp/src/c/SConscript

+++ b/mama/c_cpp/src/c/SConscript

@@ -98,6 +98,7 @@ libmama_sources = \

     mama.c

     mamaStrUtils.c

               marketdata.c

+    plugin.c

     middleware.c

               msg.c

               msgfield.c

diff --git a/mama/c_cpp/src/c/SConscript.win b/mama/c_cpp/src/c/SConscript.win

index 77e3e18..9a6ff05 100644

--- a/mama/c_cpp/src/c/SConscript.win

+++ b/mama/c_cpp/src/c/SConscript.win

@@ -50,6 +50,7 @@ dqpublishermanager.c

inbox.c

msgtype.c

msgutils.c

+plugin.c

senderId.c

reservedfields.c

subscription.c

diff --git a/mama/c_cpp/src/c/mama.c b/mama/c_cpp/src/c/mama.c

index 33a0768..5e31856 100644

--- a/mama/c_cpp/src/c/mama.c

+++ b/mama/c_cpp/src/c/mama.c

@@ -35,6 +35,7 @@

#include <payloadbridge.h>

#include <property.h>

#include <platform.h>

+#include <plugin.h>

 

 #include "fileutils.h"

#include "reservedfieldsimpl.h"

@@ -42,7 +43,6 @@

#include <mama/stat.h>

#include <mama/statfields.h>

#include <statsgeneratorinternal.h>

-#include <statsgeneratorinternal.h>

#include <mama/statscollector.h>

#include "transportimpl.h"

 

@@ -740,6 +740,9 @@ mama_openWithPropertiesCount (const char* path,

                               }

     }

 

+    /* This will initialise all plugins */

+    mama_initPlugins();

+

     prop = properties_Get (gProperties, "mama.catchcallbackexceptions.enable");

     if (prop != NULL && strtobool(prop))

     {

@@ -1253,9 +1256,12 @@ mama_closeCount (unsigned int* count)

                 gImpl.myPayloadLibraries[(uint8_t)payload] = NULL;

             }

         }

-       

+

        gDefaultPayload = NULL;

 

+       /* This will shutdown all plugins */

+       mama_shutdownPlugins();

+

         /* Look for a bridge for each of the middlewares and close them */

         for (middleware = 0; middleware != MAMA_MIDDLEWARE_MAX; ++middleware)

         {

diff --git a/mama/c_cpp/src/c/mama/types.h b/mama/c_cpp/src/c/mama/types.h

index 50d6608..03f6da8 100644

--- a/mama/c_cpp/src/c/mama/types.h

+++ b/mama/c_cpp/src/c/mama/types.h

@@ -74,6 +74,16 @@ typedef struct mamaBridgeImpl_* mamaBridge;

typedef struct mamaPayloadBridgeImpl_* mamaPayloadBridge;

 

 /**

+ * @brief Container for holding a mama plugin object

+ */

+typedef struct mamaPluginImpl_*     mamaPlugin;

+

+/**

+ * @brief Container for holding a mama plugin info

+ */

+typedef void*       mamaPluginInfo;

+

+/**

  * Flexible date/time format

  */

typedef   mama_u64_t*   mamaDateTime;

diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c

new file mode 100644

index 0000000..b6475fe

--- /dev/null

+++ b/mama/c_cpp/src/c/plugin.c

@@ -0,0 +1,472 @@

+/* $Id$

+ *

+ * OpenMAMA: The open middleware agnostic messaging API

+ * Copyright (C) 2011 NYSE Technologies, Inc.

+ *

+ * This library is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU Lesser General Public

+ * License as published by the Free Software Foundation; either

+ * version 2.1 of the License, or (at your option) any later version.

+ *

+ * This library is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

+ * Lesser General Public License for more details.

+ *

+ * You should have received a copy of the GNU Lesser General Public

+ * License along with this library; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+ * 02110-1301 USA

+ */

+

+#include <string.h>

+#include <stdio.h>

+#include <limits.h>

+

+#include "wombat/port.h"

+#include "wombat/environment.h"

+#include "wombat/strutils.h"

+#include <wombat/wtable.h>

+

+#include <mama/mama.h>

+#include <mama/error.h>

+#include <mamainternal.h>

+#include <mama/version.h>

+#include <property.h>

+#include <plugin.h>

+#include <platform.h>

+

+#define PLUGIN_PROPERTY "mama.plugin.name_"

+#define PLUGIN_NAME "mamaplugin"

+

+#define MAX_PLUGINS 100

+#define MAX_PLUGIN_STRING 1024

+

+#define MAX_FUNC_STRING 256

+

+/**

+ * @brief Mechanism for registering required plugin functions.

+ *

+ * Taking a function string name search the shared library handle, using the

+ * loadLibFunc portability method, for the function. If it is found, set the

+ * appropriate function pointer in the plugin struct to the result. If not,

+ * log as an error the fact that the funciton cannot be found, and return

+ * MAMA_STATUS_PLATFORM

+ *

+ * @param FUNCSTRINGNAME The string function name.

+ * @param FUNCIMPLNAME The name of the function pointer in the plugin struct

+ * @param FUNCIMPLTYPE The type of the function pointer expected.

+ */

+#define REGISTER_PLUGIN_FUNCTION(FUNCSTRINGNAME, FUNCIMPLNAME, FUNCIMPLTYPE)    \

+do {                                                                            \

+    snprintf (functionName, MAX_FUNC_STRING, "%s"#FUNCSTRINGNAME, name);        \

+    result = loadLibFunc (pluginLib, functionName);                             \

+                                                                                \

+    if (NULL != result) {                                                       \

+        (pluginImpl)->FUNCIMPLNAME = *(FUNCIMPLTYPE*)&result;                   \

+        result = NULL;                                                          \

+    } else {                                                                    \

+        mama_log (MAMA_LOG_LEVEL_ERROR,                                         \

+                  "mamaPlugin_registerFunctions(): "                            \

+                  "Cannot load plugin, does not implement required function: [%s]",\

+                  functionName);                                                \

+        status = MAMA_STATUS_PLATFORM;                                          \

+        return status;                                                          \

+    }                                                                           \

+} while (0)

+

+/**

+ * @brief Mechanism for registering required plugin functions.

+ *

+ * Taking a function string name search the shared library handle, using the

+ * loadLibFunc portability method, for the function. If it is found, set the

+ * appropriate function pointer in the plugin struct to the result. If not

+ * log the fact that the function has not been found, and continue.

+ *

+ * @param FUNCSTRINGNAME The string function name.

+ * @param FUNCIMPLNAME The name of the function pointer in the plugin struct

+ * @param FUNCIMPLTYPE The type of the function pointer expected.

+ */

+#define REGISTER_OPTIONAL_PLUGIN_FUNCTION(FUNCSTRINGNAME,                       \

+                                          FUNCIMPLNAME,                         \

+                                          FUNCIMPLTYPE)                         \

+do {                                                                            \

+    snprintf (functionName, MAX_FUNC_STRING, "%s"#FUNCSTRINGNAME, name);        \

+    result = loadLibFunc (pluginLib, functionName);                             \

+                                                                                \

+    if (NULL != result) {                                                       \

+        (pluginImpl)->FUNCIMPLNAME = *(FUNCIMPLTYPE*)&result;                   \

+        result = NULL;                                                          \

+    } else {                                                                    \

+        mama_log (MAMA_LOG_LEVEL_FINE,                                          \

+                  "mamaPlugin_registerFunctions(): "                            \

+                  "Optional plugin function [%s] not found. Unavailable.",      \

+                  functionName);                                                \

+    }                                                                           \

+} while (0)

+

+typedef struct mamaPluginImpl_

+{

+    LIB_HANDLE          mPluginHandle;

+    char*               mPluginName;

+    mamaPluginInfo      mPluginInfo;

+

+    mamaPlugin_publisherPreSendHook     mamaPluginPublisherPreSendHook;

+    mamaPlugin_transportPostCreateHook  mamaPluginTransportPostCreateHook;

+    mamaPlugin_shutdownHook             mamaPluginShutdownHook;

+    mamaPlugin_initHook                 mamaPluginInitHook;

+

+} mamaPluginImpl;

+

+static mamaPluginImpl*      gPlugins[MAX_PLUGINS];

+static volatile int         gPluginNo = 0;

+

+/**

+ * @brief Used to load register all possible plugin functions to be

+ *        used within Mama.

+ *

+ * param[in] pluginLib

+ * param[in] name

+ * param[in] pluginImpl The plugin impl to be used

+ *

+ * @return mama_status return code can be one of:

+ *          MAMA_STATUS_OK

+ */

+mama_status

+mamaPlugin_registerFunctions   (LIB_HANDLE      pluginLib,

+                                const char*     name,

+                                mamaPluginInfo  pluginInfo,

+                                mamaPluginImpl* pluginImpl);

+

+/**

+ * @brief Used find a plugin using the library name

+ *

+ * param[in] name

+ *

+ * @return a valid mamaPluginImpl if found

+ */

+mamaPluginImpl*

+mamaPlugin_findPlugin (const char* name);

+

+/**

+ * @brief Used find a plugin using the library name

+ *

+ * param[in] pluginName

+ *

+ * @return mama_status return code can be one of:

+ *          MAMA_STATUS_OK

+ */

+mama_status

+mama_loadPlugin (const char* pluginName);

+

+

+/**

+ * Register function pointers associated with a specific plugin.

+ */

+mama_status

+mamaPlugin_registerFunctions (LIB_HANDLE      pluginLib,

+                              const char*     name,

+                              mamaPluginInfo  pluginInfo,

+                              mamaPluginImpl* pluginImpl)

+{

+    mama_status  status        = MAMA_STATUS_OK;

+    void*        result        = NULL;

+    char         functionName[MAX_FUNC_STRING];

+

+    /* Save off some informatin on the plugin */

+    pluginImpl->mPluginHandle = pluginLib;

+    pluginImpl->mPluginName = strdup(name);

+    pluginImpl->mPluginInfo = pluginInfo;

+

+

+    /* Required fuctions */

+    REGISTER_PLUGIN_FUNCTION (MamaPlugin_initHook, mamaPluginInitHook,

+                              mamaPlugin_initHook);

+    REGISTER_PLUGIN_FUNCTION (MamaPlugin_shutdownHook, mamaPluginShutdownHook,

+                              mamaPlugin_shutdownHook);

+

+

+    /* Optional fuctions */

+    REGISTER_OPTIONAL_PLUGIN_FUNCTION (MamaPlugin_publisherPreSendHook, mamaPluginPublisherPreSendHook,

+                                       mamaPlugin_publisherPreSendHook);

+    REGISTER_OPTIONAL_PLUGIN_FUNCTION (MamaPlugin_transportPostCreateHook, mamaPluginTransportPostCreateHook,

+                                       mamaPlugin_transportPostCreateHook);

+

+   return status;

+}

+

+mama_status

+mama_initPlugins(void)

+{

+    int             pluginCount      = 0;

+    const char*     prop             = NULL;

+    char            propString[MAX_PLUGIN_STRING];

+

+    for (pluginCount = 0; pluginCount < MAX_PLUGINS; pluginCount++)

+    {

+        snprintf(propString, MAX_PLUGIN_STRING,

+            PLUGIN_PROPERTY"%d",

+            pluginCount);

+

+        prop = properties_Get (mamaInternal_getProperties (), propString);

+        if (prop != NULL && strlen(prop)!= 0)

+        {

+            mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising [%s] %s", propString, prop);

+            mama_loadPlugin (prop);

+        }

+    }

+

+    mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising mamacenterprise");

+    mama_loadPlugin ("mamacenterprise");

+

+    return MAMA_STATUS_OK;

+}

+

+mama_status

+mama_loadPlugin (const char* pluginName)

+{

+    LIB_HANDLE              pluginLib       = NULL;

+    mamaPluginImpl*         pluginImpl      = NULL;

+    mama_status             status          = MAMA_STATUS_OK;

+    mamaPluginInfo          pluginInfo      = NULL;

+    char                    loadPluginName  [MAX_PLUGIN_STRING];

+    mamaPluginImpl*         aPluginImpl     = NULL;

+

+    if (!pluginName)

+        return MAMA_STATUS_NULL_ARG;

+

+    pluginImpl = mamaPlugin_findPlugin(pluginName);

+

+    /*

+     * Check to see if pluginImpl has already been loaded

+     */

+    if (pluginImpl == NULL)

+    {

+       /* The plugin name should be of the format mamaplugin<name> */

+        if (strncmp(pluginName, "mamacenterprise", MAX_PLUGIN_STRING) == 0)

+            snprintf(loadPluginName, MAX_PLUGIN_STRING,

+                "%s",

+                pluginName);

+        else

+            snprintf(loadPluginName, MAX_PLUGIN_STRING,

+                "%s%s",

+                PLUGIN_NAME,

+                pluginName);

+

+        pluginLib = openSharedLib (loadPluginName, NULL);

+

+        if (!pluginLib)

+        {

+

+           mama_log (MAMA_LOG_LEVEL_ERROR,

+                    "mama_loadPlugin(): "

+                    "Could not open plugin library [%s] [%s]",

+                    pluginName,

+                    getLibError());

+            return MAMA_STATUS_PLATFORM;

+        }

+

+        /* Create structure to hold plugin information */

+        aPluginImpl = (mamaPluginImpl*)calloc (1, sizeof(mamaPluginImpl));

+

+        status = mamaPlugin_registerFunctions (pluginLib,

+                                               pluginName,

+                                               pluginInfo,

+                                               aPluginImpl);

+

+        if (MAMA_STATUS_OK == status)

+        {

+            mama_log (MAMA_LOG_LEVEL_NORMAL,

+                     "mama_loadPlugin(): "

+                     "Sucessfully registered plugin functions for [%s]",

+                     pluginName);

+

+        }

+        else

+        {

+            mama_log (MAMA_LOG_LEVEL_WARN,

+                     "mama_loadPlugin(): "

+                     "Failed to register plugin functions for [%s]",

+                     pluginName);

+

+            closeSharedLib (aPluginImpl->mPluginHandle);

+

+            free ((char*)aPluginImpl->mPluginName);

+            free ((mamaPluginImpl*)aPluginImpl);

+

+            return status;

+        }

+

+        /* Invoke the init function */

+        status = aPluginImpl->mamaPluginInitHook (aPluginImpl->mPluginInfo);

+

+        if (MAMA_STATUS_OK == status)

+        {

+            mama_log (MAMA_LOG_LEVEL_NORMAL,

+                      "mama_loadPlugin(): Successfully run the init hook for mama plugin [%s]",

+                       aPluginImpl->mPluginName);

+        }

+        else

+        {

+            mama_log (MAMA_LOG_LEVEL_WARN,

+                      "mama_loadPlugin(): Init hook failed for mama plugin [%s]",

+                       aPluginImpl->mPluginName);

+

+            closeSharedLib (aPluginImpl->mPluginHandle);

+

+            free ((char*)aPluginImpl->mPluginName);

+            free ((mamaPluginImpl*)aPluginImpl);

+

+            return status;

+        }

+

+        /* Save off the plugin impl and increment the plugin counter */

+        gPlugins[gPluginNo] = aPluginImpl;

+        gPluginNo++;

+

+    }

+    else

+    {

+        mama_log (MAMA_LOG_LEVEL_NORMAL,

+                 "mama_loadPlugin(): "

+                 "Plugin [%s] has already been loaded and initialised",

+                 pluginName);

+    }

+

+    return MAMA_STATUS_OK;

+}

+

+mama_status

+mama_shutdownPlugins (void)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+    int          ret    = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin]->mPluginHandle != NULL)

+        {

+            /* Fire the user shutdown hook first - if one is present */

+            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            {

+                gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+            }

+

+            ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

+            if (0!=ret)

+            {

+                 mama_log (MAMA_LOG_LEVEL_WARN,

+                            "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

+                            gPlugins[plugin]->mPluginName);

+            }

+            else

+            {

+                 mama_log (MAMA_LOG_LEVEL_WARN,

+                            "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

+                            gPlugins[plugin]->mPluginName);

+            }

+

+            free ((char*)gPlugins[plugin]->mPluginName);

+            free (gPlugins[plugin]);

+            gPlugins[plugin] = NULL;

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_firePublisherPreSendHook (mamaPublisher publisher, mamaMsg message)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginPublisherPreSendHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginPublisherPreSendHook (gPlugins[plugin]->mPluginInfo, publisher, message);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_firePublisherPreSendHook(): Publisher pre send hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_fireTransportPostCreateHook (mamaTransport transport)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginTransportPostCreateHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginTransportPostCreateHook (gPlugins[plugin]->mPluginInfo, transport);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_fireTransportPostCreateHook(): Transport post create hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_fireShutdownHook (void)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_fireShutdownHook(): Shutdown hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mamaPluginImpl*

+mamaPlugin_findPlugin (const char* name)

+{

+    int plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin])

+        {

+            if ((strncmp(gPlugins[plugin]->mPluginName, name, MAX_PLUGIN_STRING) == 0))

+            {

+                return gPlugins[plugin];

+            }

+        }

+    }

+    return NULL;

+}

diff --git a/mama/c_cpp/src/c/plugin.h b/mama/c_cpp/src/c/plugin.h

new file mode 100644

index 0000000..df43b27

--- /dev/null

+++ b/mama/c_cpp/src/c/plugin.h

@@ -0,0 +1,59 @@

+/* $Id$

+ *

+ * OpenMAMA: The open middleware agnostic messaging API

+ * Copyright (C) 2011 NYSE Technologies, Inc.

+ *

+ * This library is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU Lesser General Public

+ * License as published by the Free Software Foundation; either

+ * version 2.1 of the License, or (at your option) any later version.

+ *

+ * This library is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

+ * Lesser General Public License for more details.

+ *

+ * You should have received a copy of the GNU Lesser General Public

+ * License along with this library; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+ * 02110-1301 USA

+ */

+

+#ifndef PluginH__

+#define PluginH__

+

+

+/**

+ * @brief Containers used within the mama plugin

+ */

+typedef mama_status (*mamaPlugin_publisherPreSendHook) (mamaPluginInfo pluginInfo, mamaPublisher publisher, mamaMsg message);

+typedef mama_status (*mamaPlugin_transportPostCreateHook) (mamaPluginInfo pluginInfo, mamaTransport transport);

+typedef mama_status (*mamaPlugin_shutdownHook) (mamaPluginInfo pluginInfo);

+typedef mama_status (*mamaPlugin_initHook) (mamaPluginInfo* pluginInfo);

+

+/**

+ * Initialize the internal plugin interface

+ *

+ * @return mama status code

+ */

+extern mama_status

+mama_initPlugins (void);

+

+/**

+ * Shutdown the internal plugin interface

+ *

+ * @return mama status code

+ */

+extern mama_status

+mama_shutdownPlugins (void);

+

+extern mama_status

+mamaPlugin_firePublisherPreSendHook (mamaPublisher publisher, mamaMsg message);

+

+extern mama_status

+mamaPlugin_fireTransportPostCreateHook (mamaTransport transport);

+

+extern mama_status

+mamaPlugin_fireShutdownHook (void);

+

+#endif /* PluginH__ */

diff --git a/mama/c_cpp/src/c/publisher.c b/mama/c_cpp/src/c/publisher.c

index 4612d17..6a7f92d 100644

--- a/mama/c_cpp/src/c/publisher.c

+++ b/mama/c_cpp/src/c/publisher.c

@@ -23,6 +23,7 @@

#include "mama/publisher.h"

 

 #include "bridge.h"

+#include "plugin.h"

#include "throttle.h"

#include "transportimpl.h"

 

@@ -245,6 +246,15 @@ mamaPublisher_send (mamaPublisher publisher,

     if (!impl->mMamaPublisherBridgeImpl) return MAMA_STATUS_INVALID_ARG;

     if (!impl->mBridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL;

 

+    /* Calling plugin hook */

+    status = mamaPlugin_firePublisherPreSendHook (publisher, msg);

+    if (MAMA_STATUS_OK != status)

+    {

+        mama_log (MAMA_LOG_LEVEL_ERROR,

+                  "mamaPublisher_send(): PublisherPreSendHook failed. Not sending message.");

+        return status;

+    }

+

     status = impl->mBridgeImpl->bridgeMamaPublisherSend

         (impl->mMamaPublisherBridgeImpl,

          msg);

diff --git a/mama/c_cpp/src/c/transport.c b/mama/c_cpp/src/c/transport.c

index 339dbc0..622f47d 100644

--- a/mama/c_cpp/src/c/transport.c

+++ b/mama/c_cpp/src/c/transport.c

@@ -25,6 +25,7 @@

 

 #include "mama/mama.h"

#include "throttle.h"

+#include "plugin.h"

#include "list.h"

#include "transportimpl.h"

#include "bridge.h"

@@ -876,10 +877,22 @@ mamaTransport_create (mamaTransport transport,

 

     if ((!self->mDisableRefresh) && (!mamaTransportInternal_disableRefreshes(name)))

     {

-        return refreshTransport_create (&self->mRefreshTransport,

-                                    (mamaTransport)self,

-                                    self->mListeners,

-                                    self->mBridgeImpl);

+        status = refreshTransport_create (&self->mRefreshTransport,

+                                          (mamaTransport)self,

+                                          self->mListeners,

+                                          self->mBridgeImpl);

+

+        if (MAMA_STATUS_OK != status)

+            return status;

+    }

+

+    /* Calling plugin hook*/

+    status = mamaPlugin_fireTransportPostCreateHook (transport);

+    if (MAMA_STATUS_OK != status)

+    {

+        mama_log (MAMA_LOG_LEVEL_ERROR,

+                  "mamaTransport_create(): TransportPostCreateHook failed with a status of %s",

+                   mamaStatus_stringForStatus(status));

     }

 

     return MAMA_STATUS_OK;

--

1.7.1

 

 

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 


Gary Molloy <g.molloy@...>
 

Hi Guys,

 

As promised, please find below a link to a document on the mamaPlugin feature:

https://docs.google.com/document/d/1HcV43uFJrV_pX0M0N7oDoZkWly0LjmyIxM9U-YpBtFQ/edit?usp=sharing

Thanks,

Gary

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 

From: Gary Molloy
Sent: 30 April 2015 10:58
To: openmama-dev@...
Subject: RE: [PATCH 1/3] [MAMAC] mamaPlugin Feature - additional

 

From 76a6db152998cbb32de58eb1cb9d6c1ab9307a1e Mon Sep 17 00:00:00 2001

From: Gary Molloy <g.molloy@...>

Date: Wed, 29 Apr 2015 13:05:23 -0400

Subject: [PATCH] [MAMAC] mamaPlugin Feature - addition

 

Addition to the existing mamaPlugin patch to remove references to internal shared objects and a missing null check.

 

Signed-off-by: Gary Molloy <g.molloy@...>

---

mama/c_cpp/src/c/plugin.c |   61 ++++++++++++++++++++------------------------

1 files changed, 28 insertions(+), 33 deletions(-)

 

diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c

index b6475fe..303ab9f 100644

--- a/mama/c_cpp/src/c/plugin.c

+++ b/mama/c_cpp/src/c/plugin.c

@@ -216,9 +216,6 @@ mama_initPlugins(void)

         }

     }

 

-    mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising mamacenterprise");

-    mama_loadPlugin ("mamacenterprise");

-

     return MAMA_STATUS_OK;

}

 

@@ -243,15 +240,10 @@ mama_loadPlugin (const char* pluginName)

     if (pluginImpl == NULL)

     {

        /* The plugin name should be of the format mamaplugin<name> */

-        if (strncmp(pluginName, "mamacenterprise", MAX_PLUGIN_STRING) == 0)

-            snprintf(loadPluginName, MAX_PLUGIN_STRING,

-                "%s",

-                pluginName);

-        else

-            snprintf(loadPluginName, MAX_PLUGIN_STRING,

-                "%s%s",

-                PLUGIN_NAME,

-                pluginName);

+        snprintf(loadPluginName, MAX_PLUGIN_STRING,

+            "%s%s",

+            PLUGIN_NAME,

+            pluginName);

 

         pluginLib = openSharedLib (loadPluginName, NULL);

 

@@ -345,31 +337,34 @@ mama_shutdownPlugins (void)

 

     for (plugin = 0; plugin <= gPluginNo; plugin++)

     {

-        if (gPlugins[plugin]->mPluginHandle != NULL)

+        if (gPlugins[plugin] != NULL)

         {

-            /* Fire the user shutdown hook first - if one is present */

-            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            if (gPlugins[plugin]->mPluginHandle != NULL)

             {

-                gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

-            }

+                /* Fire the user shutdown hook first - if one is present */

+                if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+                {

+                    gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+                }

 

-            ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

-            if (0!=ret)

-            {

-                 mama_log (MAMA_LOG_LEVEL_WARN,

-                            "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

-                            gPlugins[plugin]->mPluginName);

-            }

-            else

-            {

-                 mama_log (MAMA_LOG_LEVEL_WARN,

-                            "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

-                            gPlugins[plugin]->mPluginName);

-            }

+                ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

+                if (0!=ret)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+                else

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

+                                gPlugins[plugin]->mPluginName);

+                }

 

-            free ((char*)gPlugins[plugin]->mPluginName);

-            free (gPlugins[plugin]);

-            gPlugins[plugin] = NULL;

+                free ((char*)gPlugins[plugin]->mPluginName);

+                free (gPlugins[plugin]);

+                gPlugins[plugin] = NULL;

+            }

         }

     }

     return status;

--

1.7.1

 

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 

From: openmama-dev-bounces@... [mailto:openmama-dev-bounces@...] On Behalf Of Gary Molloy
Sent: 23 April 2015 17:54
To: openmama-dev@...
Subject: [Openmama-dev] [PATCH 1/3] [MAMAC] mamaPlugin Feature

 

Testing Strategy:-

Not middleware or O/S specific. 
 

Using the attached template you can create your own plugin and load it in via your mama.properties, for example:

 

mama.plugin.name_0=template

 

You can run up a mamaPublisher to test your plugin, for example:

 

mamapublisherc -tport pub -m wmw -l MAMA_INBOUND_TOPIC -v -v -v -v -v

 

You can expect to see output similar this if your plugin was loaded successfully:

 

2015-04-09 13:45:02: (f9018280) : mama_initPlugins(): Initialising [mama.plugin.name_0] template 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Sucessfully registered plugin functions for [template] 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Successfully run the init hook for mama plugin [template]  

 

If your plugin was not loaded successful you can expect to see output similar to this:

 

2015-04-09 13:45:02: (f9018280) : mama_initPlugins(): Initialising [mama.plugin.name_0] template 

2015-04-09 13:45:02: (f9018280) : mamaPlugin_registerFunctions(): Cannot load plugin, does not implement required function: [templateMamaPlugin_shutdownHook] 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Failed to register plugin functions for [template] 

 

Further documentation on the mamaPlugin feature will be available shortly which will provide more details on the feature which will include the various hooks available etc...

 

 

=========================================================================================================

 

From e2a6a3f9c5750cee780cb6185a1310b4e4b70629 Mon Sep 17 00:00:00 2001

From: Gary Molloy <g.molloy@...>

Date: Thu, 23 Apr 2015 11:22:14 -0400

Subject: [PATCH 1/3] [MAMAC] mamaPlugin Feature

 

A new feature, mamaPlugin has been introduced that will allow you to

create and run your own code within 'hooks' into the MAMA codebase.

 

A mamaPlugin is essentially a shared object.

 

Signed-off-by: Gary Molloy <g.molloy@...>

---

mama/c_cpp/src/c/Makefile.am    |    1 +

mama/c_cpp/src/c/SConscript     |    1 +

mama/c_cpp/src/c/SConscript.win |    1 +

mama/c_cpp/src/c/mama.c         |   10 +-

mama/c_cpp/src/c/mama/types.h   |   10 +

mama/c_cpp/src/c/plugin.c       |  472 +++++++++++++++++++++++++++++++++++++++

mama/c_cpp/src/c/plugin.h       |   59 +++++

mama/c_cpp/src/c/publisher.c    |   10 +

mama/c_cpp/src/c/transport.c    |   21 ++-

9 files changed, 579 insertions(+), 6 deletions(-)

create mode 100644 mama/c_cpp/src/c/plugin.c

create mode 100644 mama/c_cpp/src/c/plugin.h

 

diff --git a/mama/c_cpp/src/c/Makefile.am b/mama/c_cpp/src/c/Makefile.am

index c831ce4..318c353 100644

--- a/mama/c_cpp/src/c/Makefile.am

+++ b/mama/c_cpp/src/c/Makefile.am

@@ -131,6 +131,7 @@ libmama_la_SOURCES = \

     mamaStrUtils.h \

     mamaStrUtils.c \

               marketdata.c \

+    plugin.c \

     middleware.c \

               msg.c \

               msgfield.c \

diff --git a/mama/c_cpp/src/c/SConscript b/mama/c_cpp/src/c/SConscript

index 4362f50..f47e18c 100644

--- a/mama/c_cpp/src/c/SConscript

+++ b/mama/c_cpp/src/c/SConscript

@@ -98,6 +98,7 @@ libmama_sources = \

     mama.c

     mamaStrUtils.c

               marketdata.c

+    plugin.c

     middleware.c

               msg.c

               msgfield.c

diff --git a/mama/c_cpp/src/c/SConscript.win b/mama/c_cpp/src/c/SConscript.win

index 77e3e18..9a6ff05 100644

--- a/mama/c_cpp/src/c/SConscript.win

+++ b/mama/c_cpp/src/c/SConscript.win

@@ -50,6 +50,7 @@ dqpublishermanager.c

inbox.c

msgtype.c

msgutils.c

+plugin.c

senderId.c

reservedfields.c

subscription.c

diff --git a/mama/c_cpp/src/c/mama.c b/mama/c_cpp/src/c/mama.c

index 33a0768..5e31856 100644

--- a/mama/c_cpp/src/c/mama.c

+++ b/mama/c_cpp/src/c/mama.c

@@ -35,6 +35,7 @@

#include <payloadbridge.h>

#include <property.h>

#include <platform.h>

+#include <plugin.h>

 

 #include "fileutils.h"

#include "reservedfieldsimpl.h"

@@ -42,7 +43,6 @@

#include <mama/stat.h>

#include <mama/statfields.h>

#include <statsgeneratorinternal.h>

-#include <statsgeneratorinternal.h>

#include <mama/statscollector.h>

#include "transportimpl.h"

 

@@ -740,6 +740,9 @@ mama_openWithPropertiesCount (const char* path,

                               }

     }

 

+    /* This will initialise all plugins */

+    mama_initPlugins();

+

     prop = properties_Get (gProperties, "mama.catchcallbackexceptions.enable");

     if (prop != NULL && strtobool(prop))

     {

@@ -1253,9 +1256,12 @@ mama_closeCount (unsigned int* count)

                 gImpl.myPayloadLibraries[(uint8_t)payload] = NULL;

             }

         }

-       

+

        gDefaultPayload = NULL;

 

+       /* This will shutdown all plugins */

+       mama_shutdownPlugins();

+

         /* Look for a bridge for each of the middlewares and close them */

         for (middleware = 0; middleware != MAMA_MIDDLEWARE_MAX; ++middleware)

         {

diff --git a/mama/c_cpp/src/c/mama/types.h b/mama/c_cpp/src/c/mama/types.h

index 50d6608..03f6da8 100644

--- a/mama/c_cpp/src/c/mama/types.h

+++ b/mama/c_cpp/src/c/mama/types.h

@@ -74,6 +74,16 @@ typedef struct mamaBridgeImpl_* mamaBridge;

typedef struct mamaPayloadBridgeImpl_* mamaPayloadBridge;

 

 /**

+ * @brief Container for holding a mama plugin object

+ */

+typedef struct mamaPluginImpl_*     mamaPlugin;

+

+/**

+ * @brief Container for holding a mama plugin info

+ */

+typedef void*       mamaPluginInfo;

+

+/**

  * Flexible date/time format

  */

typedef   mama_u64_t*   mamaDateTime;

diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c

new file mode 100644

index 0000000..b6475fe

--- /dev/null

+++ b/mama/c_cpp/src/c/plugin.c

@@ -0,0 +1,472 @@

+/* $Id$

+ *

+ * OpenMAMA: The open middleware agnostic messaging API

+ * Copyright (C) 2011 NYSE Technologies, Inc.

+ *

+ * This library is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU Lesser General Public

+ * License as published by the Free Software Foundation; either

+ * version 2.1 of the License, or (at your option) any later version.

+ *

+ * This library is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

+ * Lesser General Public License for more details.

+ *

+ * You should have received a copy of the GNU Lesser General Public

+ * License along with this library; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+ * 02110-1301 USA

+ */

+

+#include <string.h>

+#include <stdio.h>

+#include <limits.h>

+

+#include "wombat/port.h"

+#include "wombat/environment.h"

+#include "wombat/strutils.h"

+#include <wombat/wtable.h>

+

+#include <mama/mama.h>

+#include <mama/error.h>

+#include <mamainternal.h>

+#include <mama/version.h>

+#include <property.h>

+#include <plugin.h>

+#include <platform.h>

+

+#define PLUGIN_PROPERTY "mama.plugin.name_"

+#define PLUGIN_NAME "mamaplugin"

+

+#define MAX_PLUGINS 100

+#define MAX_PLUGIN_STRING 1024

+

+#define MAX_FUNC_STRING 256

+

+/**

+ * @brief Mechanism for registering required plugin functions.

+ *

+ * Taking a function string name search the shared library handle, using the

+ * loadLibFunc portability method, for the function. If it is found, set the

+ * appropriate function pointer in the plugin struct to the result. If not,

+ * log as an error the fact that the funciton cannot be found, and return

+ * MAMA_STATUS_PLATFORM

+ *

+ * @param FUNCSTRINGNAME The string function name.

+ * @param FUNCIMPLNAME The name of the function pointer in the plugin struct

+ * @param FUNCIMPLTYPE The type of the function pointer expected.

+ */

+#define REGISTER_PLUGIN_FUNCTION(FUNCSTRINGNAME, FUNCIMPLNAME, FUNCIMPLTYPE)    \

+do {                                                                            \

+    snprintf (functionName, MAX_FUNC_STRING, "%s"#FUNCSTRINGNAME, name);        \

+    result = loadLibFunc (pluginLib, functionName);                             \

+                                                                                \

+    if (NULL != result) {                                                       \

+        (pluginImpl)->FUNCIMPLNAME = *(FUNCIMPLTYPE*)&result;                   \

+        result = NULL;                                                          \

+    } else {                                                                    \

+        mama_log (MAMA_LOG_LEVEL_ERROR,                                         \

+                  "mamaPlugin_registerFunctions(): "                            \

+                  "Cannot load plugin, does not implement required function: [%s]",\

+                  functionName);                                                \

+        status = MAMA_STATUS_PLATFORM;                                          \

+        return status;                                                          \

+    }                                                                           \

+} while (0)

+

+/**

+ * @brief Mechanism for registering required plugin functions.

+ *

+ * Taking a function string name search the shared library handle, using the

+ * loadLibFunc portability method, for the function. If it is found, set the

+ * appropriate function pointer in the plugin struct to the result. If not

+ * log the fact that the function has not been found, and continue.

+ *

+ * @param FUNCSTRINGNAME The string function name.

+ * @param FUNCIMPLNAME The name of the function pointer in the plugin struct

+ * @param FUNCIMPLTYPE The type of the function pointer expected.

+ */

+#define REGISTER_OPTIONAL_PLUGIN_FUNCTION(FUNCSTRINGNAME,                       \

+                                          FUNCIMPLNAME,                         \

+                                          FUNCIMPLTYPE)                         \

+do {                                                                            \

+    snprintf (functionName, MAX_FUNC_STRING, "%s"#FUNCSTRINGNAME, name);        \

+    result = loadLibFunc (pluginLib, functionName);                             \

+                                                                                \

+    if (NULL != result) {                                                       \

+        (pluginImpl)->FUNCIMPLNAME = *(FUNCIMPLTYPE*)&result;                   \

+        result = NULL;                                                          \

+    } else {                                                                    \

+        mama_log (MAMA_LOG_LEVEL_FINE,                                          \

+                  "mamaPlugin_registerFunctions(): "                            \

+                  "Optional plugin function [%s] not found. Unavailable.",      \

+                  functionName);                                                \

+    }                                                                           \

+} while (0)

+

+typedef struct mamaPluginImpl_

+{

+    LIB_HANDLE          mPluginHandle;

+    char*               mPluginName;

+    mamaPluginInfo      mPluginInfo;

+

+    mamaPlugin_publisherPreSendHook     mamaPluginPublisherPreSendHook;

+    mamaPlugin_transportPostCreateHook  mamaPluginTransportPostCreateHook;

+    mamaPlugin_shutdownHook             mamaPluginShutdownHook;

+    mamaPlugin_initHook                 mamaPluginInitHook;

+

+} mamaPluginImpl;

+

+static mamaPluginImpl*      gPlugins[MAX_PLUGINS];

+static volatile int         gPluginNo = 0;

+

+/**

+ * @brief Used to load register all possible plugin functions to be

+ *        used within Mama.

+ *

+ * param[in] pluginLib

+ * param[in] name

+ * param[in] pluginImpl The plugin impl to be used

+ *

+ * @return mama_status return code can be one of:

+ *          MAMA_STATUS_OK

+ */

+mama_status

+mamaPlugin_registerFunctions   (LIB_HANDLE      pluginLib,

+                                const char*     name,

+                                mamaPluginInfo  pluginInfo,

+                                mamaPluginImpl* pluginImpl);

+

+/**

+ * @brief Used find a plugin using the library name

+ *

+ * param[in] name

+ *

+ * @return a valid mamaPluginImpl if found

+ */

+mamaPluginImpl*

+mamaPlugin_findPlugin (const char* name);

+

+/**

+ * @brief Used find a plugin using the library name

+ *

+ * param[in] pluginName

+ *

+ * @return mama_status return code can be one of:

+ *          MAMA_STATUS_OK

+ */

+mama_status

+mama_loadPlugin (const char* pluginName);

+

+

+/**

+ * Register function pointers associated with a specific plugin.

+ */

+mama_status

+mamaPlugin_registerFunctions (LIB_HANDLE      pluginLib,

+                              const char*     name,

+                              mamaPluginInfo  pluginInfo,

+                              mamaPluginImpl* pluginImpl)

+{

+    mama_status  status        = MAMA_STATUS_OK;

+    void*        result        = NULL;

+    char         functionName[MAX_FUNC_STRING];

+

+    /* Save off some informatin on the plugin */

+    pluginImpl->mPluginHandle = pluginLib;

+    pluginImpl->mPluginName = strdup(name);

+    pluginImpl->mPluginInfo = pluginInfo;

+

+

+    /* Required fuctions */

+    REGISTER_PLUGIN_FUNCTION (MamaPlugin_initHook, mamaPluginInitHook,

+                              mamaPlugin_initHook);

+    REGISTER_PLUGIN_FUNCTION (MamaPlugin_shutdownHook, mamaPluginShutdownHook,

+                              mamaPlugin_shutdownHook);

+

+

+    /* Optional fuctions */

+    REGISTER_OPTIONAL_PLUGIN_FUNCTION (MamaPlugin_publisherPreSendHook, mamaPluginPublisherPreSendHook,

+                                       mamaPlugin_publisherPreSendHook);

+    REGISTER_OPTIONAL_PLUGIN_FUNCTION (MamaPlugin_transportPostCreateHook, mamaPluginTransportPostCreateHook,

+                                       mamaPlugin_transportPostCreateHook);

+

+   return status;

+}

+

+mama_status

+mama_initPlugins(void)

+{

+    int             pluginCount      = 0;

+    const char*     prop             = NULL;

+    char            propString[MAX_PLUGIN_STRING];

+

+    for (pluginCount = 0; pluginCount < MAX_PLUGINS; pluginCount++)

+    {

+        snprintf(propString, MAX_PLUGIN_STRING,

+            PLUGIN_PROPERTY"%d",

+            pluginCount);

+

+        prop = properties_Get (mamaInternal_getProperties (), propString);

+        if (prop != NULL && strlen(prop)!= 0)

+        {

+            mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising [%s] %s", propString, prop);

+            mama_loadPlugin (prop);

+        }

+    }

+

+    mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising mamacenterprise");

+    mama_loadPlugin ("mamacenterprise");

+

+    return MAMA_STATUS_OK;

+}

+

+mama_status

+mama_loadPlugin (const char* pluginName)

+{

+    LIB_HANDLE              pluginLib       = NULL;

+    mamaPluginImpl*         pluginImpl      = NULL;

+    mama_status             status          = MAMA_STATUS_OK;

+    mamaPluginInfo          pluginInfo      = NULL;

+    char                    loadPluginName  [MAX_PLUGIN_STRING];

+    mamaPluginImpl*         aPluginImpl     = NULL;

+

+    if (!pluginName)

+        return MAMA_STATUS_NULL_ARG;

+

+    pluginImpl = mamaPlugin_findPlugin(pluginName);

+

+    /*

+     * Check to see if pluginImpl has already been loaded

+     */

+    if (pluginImpl == NULL)

+    {

+       /* The plugin name should be of the format mamaplugin<name> */

+        if (strncmp(pluginName, "mamacenterprise", MAX_PLUGIN_STRING) == 0)

+            snprintf(loadPluginName, MAX_PLUGIN_STRING,

+                "%s",

+                pluginName);

+        else

+            snprintf(loadPluginName, MAX_PLUGIN_STRING,

+                "%s%s",

+                PLUGIN_NAME,

+                pluginName);

+

+        pluginLib = openSharedLib (loadPluginName, NULL);

+

+        if (!pluginLib)

+        {

+

+           mama_log (MAMA_LOG_LEVEL_ERROR,

+                    "mama_loadPlugin(): "

+                    "Could not open plugin library [%s] [%s]",

+                    pluginName,

+                    getLibError());

+            return MAMA_STATUS_PLATFORM;

+        }

+

+        /* Create structure to hold plugin information */

+        aPluginImpl = (mamaPluginImpl*)calloc (1, sizeof(mamaPluginImpl));

+

+        status = mamaPlugin_registerFunctions (pluginLib,

+                                               pluginName,

+                                               pluginInfo,

+                                               aPluginImpl);

+

+        if (MAMA_STATUS_OK == status)

+        {

+            mama_log (MAMA_LOG_LEVEL_NORMAL,

+                     "mama_loadPlugin(): "

+                     "Sucessfully registered plugin functions for [%s]",

+                     pluginName);

+

+        }

+        else

+        {

+            mama_log (MAMA_LOG_LEVEL_WARN,

+                     "mama_loadPlugin(): "

+                     "Failed to register plugin functions for [%s]",

+                     pluginName);

+

+            closeSharedLib (aPluginImpl->mPluginHandle);

+

+            free ((char*)aPluginImpl->mPluginName);

+            free ((mamaPluginImpl*)aPluginImpl);

+

+            return status;

+        }

+

+        /* Invoke the init function */

+        status = aPluginImpl->mamaPluginInitHook (aPluginImpl->mPluginInfo);

+

+        if (MAMA_STATUS_OK == status)

+        {

+            mama_log (MAMA_LOG_LEVEL_NORMAL,

+                      "mama_loadPlugin(): Successfully run the init hook for mama plugin [%s]",

+                       aPluginImpl->mPluginName);

+        }

+        else

+        {

+            mama_log (MAMA_LOG_LEVEL_WARN,

+                      "mama_loadPlugin(): Init hook failed for mama plugin [%s]",

+                       aPluginImpl->mPluginName);

+

+            closeSharedLib (aPluginImpl->mPluginHandle);

+

+            free ((char*)aPluginImpl->mPluginName);

+            free ((mamaPluginImpl*)aPluginImpl);

+

+            return status;

+        }

+

+        /* Save off the plugin impl and increment the plugin counter */

+        gPlugins[gPluginNo] = aPluginImpl;

+        gPluginNo++;

+

+    }

+    else

+    {

+        mama_log (MAMA_LOG_LEVEL_NORMAL,

+                 "mama_loadPlugin(): "

+                 "Plugin [%s] has already been loaded and initialised",

+                 pluginName);

+    }

+

+    return MAMA_STATUS_OK;

+}

+

+mama_status

+mama_shutdownPlugins (void)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+    int          ret    = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin]->mPluginHandle != NULL)

+        {

+            /* Fire the user shutdown hook first - if one is present */

+            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            {

+                gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+            }

+

+            ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

+            if (0!=ret)

+            {

+                 mama_log (MAMA_LOG_LEVEL_WARN,

+                            "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

+                            gPlugins[plugin]->mPluginName);

+            }

+            else

+            {

+                 mama_log (MAMA_LOG_LEVEL_WARN,

+                            "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

+                            gPlugins[plugin]->mPluginName);

+            }

+

+            free ((char*)gPlugins[plugin]->mPluginName);

+            free (gPlugins[plugin]);

+            gPlugins[plugin] = NULL;

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_firePublisherPreSendHook (mamaPublisher publisher, mamaMsg message)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginPublisherPreSendHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginPublisherPreSendHook (gPlugins[plugin]->mPluginInfo, publisher, message);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_firePublisherPreSendHook(): Publisher pre send hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_fireTransportPostCreateHook (mamaTransport transport)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginTransportPostCreateHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginTransportPostCreateHook (gPlugins[plugin]->mPluginInfo, transport);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_fireTransportPostCreateHook(): Transport post create hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_fireShutdownHook (void)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_fireShutdownHook(): Shutdown hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mamaPluginImpl*

+mamaPlugin_findPlugin (const char* name)

+{

+    int plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin])

+        {

+            if ((strncmp(gPlugins[plugin]->mPluginName, name, MAX_PLUGIN_STRING) == 0))

+            {

+                return gPlugins[plugin];

+            }

+        }

+    }

+    return NULL;

+}

diff --git a/mama/c_cpp/src/c/plugin.h b/mama/c_cpp/src/c/plugin.h

new file mode 100644

index 0000000..df43b27

--- /dev/null

+++ b/mama/c_cpp/src/c/plugin.h

@@ -0,0 +1,59 @@

+/* $Id$

+ *

+ * OpenMAMA: The open middleware agnostic messaging API

+ * Copyright (C) 2011 NYSE Technologies, Inc.

+ *

+ * This library is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU Lesser General Public

+ * License as published by the Free Software Foundation; either

+ * version 2.1 of the License, or (at your option) any later version.

+ *

+ * This library is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

+ * Lesser General Public License for more details.

+ *

+ * You should have received a copy of the GNU Lesser General Public

+ * License along with this library; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+ * 02110-1301 USA

+ */

+

+#ifndef PluginH__

+#define PluginH__

+

+

+/**

+ * @brief Containers used within the mama plugin

+ */

+typedef mama_status (*mamaPlugin_publisherPreSendHook) (mamaPluginInfo pluginInfo, mamaPublisher publisher, mamaMsg message);

+typedef mama_status (*mamaPlugin_transportPostCreateHook) (mamaPluginInfo pluginInfo, mamaTransport transport);

+typedef mama_status (*mamaPlugin_shutdownHook) (mamaPluginInfo pluginInfo);

+typedef mama_status (*mamaPlugin_initHook) (mamaPluginInfo* pluginInfo);

+

+/**

+ * Initialize the internal plugin interface

+ *

+ * @return mama status code

+ */

+extern mama_status

+mama_initPlugins (void);

+

+/**

+ * Shutdown the internal plugin interface

+ *

+ * @return mama status code

+ */

+extern mama_status

+mama_shutdownPlugins (void);

+

+extern mama_status

+mamaPlugin_firePublisherPreSendHook (mamaPublisher publisher, mamaMsg message);

+

+extern mama_status

+mamaPlugin_fireTransportPostCreateHook (mamaTransport transport);

+

+extern mama_status

+mamaPlugin_fireShutdownHook (void);

+

+#endif /* PluginH__ */

diff --git a/mama/c_cpp/src/c/publisher.c b/mama/c_cpp/src/c/publisher.c

index 4612d17..6a7f92d 100644

--- a/mama/c_cpp/src/c/publisher.c

+++ b/mama/c_cpp/src/c/publisher.c

@@ -23,6 +23,7 @@

#include "mama/publisher.h"

 

 #include "bridge.h"

+#include "plugin.h"

#include "throttle.h"

#include "transportimpl.h"

 

@@ -245,6 +246,15 @@ mamaPublisher_send (mamaPublisher publisher,

     if (!impl->mMamaPublisherBridgeImpl) return MAMA_STATUS_INVALID_ARG;

     if (!impl->mBridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL;

 

+    /* Calling plugin hook */

+    status = mamaPlugin_firePublisherPreSendHook (publisher, msg);

+    if (MAMA_STATUS_OK != status)

+    {

+        mama_log (MAMA_LOG_LEVEL_ERROR,

+                  "mamaPublisher_send(): PublisherPreSendHook failed. Not sending message.");

+        return status;

+    }

+

     status = impl->mBridgeImpl->bridgeMamaPublisherSend

         (impl->mMamaPublisherBridgeImpl,

          msg);

diff --git a/mama/c_cpp/src/c/transport.c b/mama/c_cpp/src/c/transport.c

index 339dbc0..622f47d 100644

--- a/mama/c_cpp/src/c/transport.c

+++ b/mama/c_cpp/src/c/transport.c

@@ -25,6 +25,7 @@

 

 #include "mama/mama.h"

#include "throttle.h"

+#include "plugin.h"

#include "list.h"

#include "transportimpl.h"

#include "bridge.h"

@@ -876,10 +877,22 @@ mamaTransport_create (mamaTransport transport,

 

     if ((!self->mDisableRefresh) && (!mamaTransportInternal_disableRefreshes(name)))

     {

-        return refreshTransport_create (&self->mRefreshTransport,

-                                    (mamaTransport)self,

-                                    self->mListeners,

-                                    self->mBridgeImpl);

+        status = refreshTransport_create (&self->mRefreshTransport,

+                                          (mamaTransport)self,

+                                          self->mListeners,

+                                          self->mBridgeImpl);

+

+        if (MAMA_STATUS_OK != status)

+            return status;

+    }

+

+    /* Calling plugin hook*/

+    status = mamaPlugin_fireTransportPostCreateHook (transport);

+    if (MAMA_STATUS_OK != status)

+    {

+        mama_log (MAMA_LOG_LEVEL_ERROR,

+                  "mamaTransport_create(): TransportPostCreateHook failed with a status of %s",

+                   mamaStatus_stringForStatus(status));

     }

 

     return MAMA_STATUS_OK;

--

1.7.1

 

 

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 


Keith Rudd
 

Classification: Public

Thanks for forwarding the doc Gary.

 

I found the mamaPlugin details an interesting read.

 

One question:

-          What was the logic behind selection of the points where plug-in hooks can get called?

 

I was thinking of a case where you used this as a way of having a custom entitlements implementation.

In this sense, the hook at the point of mamaPublisher_send() makes sense because you could use that to implement publishing entitlements control, which is lacking in OpenMAMA.

 

However, there’s no hook at the point of mamaSubscription_create(), so you’d have to rely on the existing OpenMAMA hook (OEA Client interface) to check subscriber entitlements. It’s possible to do both of course but this leads to a rather in-elegant hybrid solution mixing the OEA client interface plus use of a custom hook library.

 

Probably better to be able to do one or the other entirely. (So extend OEAClient interface, or add plug in hook at ALL the points where entitlement checking might be relevant)

 

Were there some other particular use cases in mind that drove the selection of plugin hook points?

 

Regards,

Keith

 

From: openmama-dev-bounces@... [mailto:openmama-dev-bounces@...] On Behalf Of Gary Molloy
Sent: 01 May 2015 17:31
To: openmama-dev@...
Subject: Re: [Openmama-dev] [PATCH 1/3] [MAMAC] mamaPlugin Feature - additional

 

Hi Guys,

 

As promised, please find below a link to a document on the mamaPlugin feature:

https://docs.google.com/document/d/1HcV43uFJrV_pX0M0N7oDoZkWly0LjmyIxM9U-YpBtFQ/edit?usp=sharing

Thanks,

Gary

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 

From: Gary Molloy
Sent: 30 April 2015 10:58
To: openmama-dev@...
Subject: RE: [PATCH 1/3] [MAMAC] mamaPlugin Feature - additional

 

From 76a6db152998cbb32de58eb1cb9d6c1ab9307a1e Mon Sep 17 00:00:00 2001

From: Gary Molloy <g.molloy@...>

Date: Wed, 29 Apr 2015 13:05:23 -0400

Subject: [PATCH] [MAMAC] mamaPlugin Feature - addition

 

Addition to the existing mamaPlugin patch to remove references to internal shared objects and a missing null check.

 

Signed-off-by: Gary Molloy <g.molloy@...>

---

mama/c_cpp/src/c/plugin.c |   61 ++++++++++++++++++++------------------------

1 files changed, 28 insertions(+), 33 deletions(-)

 

diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c

index b6475fe..303ab9f 100644

--- a/mama/c_cpp/src/c/plugin.c

+++ b/mama/c_cpp/src/c/plugin.c

@@ -216,9 +216,6 @@ mama_initPlugins(void)

         }

     }

 

-    mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising mamacenterprise");

-    mama_loadPlugin ("mamacenterprise");

-

     return MAMA_STATUS_OK;

}

 

@@ -243,15 +240,10 @@ mama_loadPlugin (const char* pluginName)

     if (pluginImpl == NULL)

     {

        /* The plugin name should be of the format mamaplugin<name> */

-        if (strncmp(pluginName, "mamacenterprise", MAX_PLUGIN_STRING) == 0)

-            snprintf(loadPluginName, MAX_PLUGIN_STRING,

-                "%s",

-                pluginName);

-        else

-            snprintf(loadPluginName, MAX_PLUGIN_STRING,

-                "%s%s",

-                PLUGIN_NAME,

-                pluginName);

+        snprintf(loadPluginName, MAX_PLUGIN_STRING,

+            "%s%s",

+            PLUGIN_NAME,

+            pluginName);

 

         pluginLib = openSharedLib (loadPluginName, NULL);

 

@@ -345,31 +337,34 @@ mama_shutdownPlugins (void)

 

     for (plugin = 0; plugin <= gPluginNo; plugin++)

     {

-        if (gPlugins[plugin]->mPluginHandle != NULL)

+        if (gPlugins[plugin] != NULL)

         {

-            /* Fire the user shutdown hook first - if one is present */

-            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            if (gPlugins[plugin]->mPluginHandle != NULL)

             {

-                gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

-            }

+                /* Fire the user shutdown hook first - if one is present */

+                if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+                {

+                    gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+                }

 

-            ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

-            if (0!=ret)

-            {

-                 mama_log (MAMA_LOG_LEVEL_WARN,

-                            "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

-                            gPlugins[plugin]->mPluginName);

-            }

-            else

-            {

-                 mama_log (MAMA_LOG_LEVEL_WARN,

-                            "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

-                            gPlugins[plugin]->mPluginName);

-            }

+                ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

+                if (0!=ret)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+                else

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

+                                gPlugins[plugin]->mPluginName);

+                }

 

-            free ((char*)gPlugins[plugin]->mPluginName);

-            free (gPlugins[plugin]);

-            gPlugins[plugin] = NULL;

+                free ((char*)gPlugins[plugin]->mPluginName);

+                free (gPlugins[plugin]);

+                gPlugins[plugin] = NULL;

+            }

         }

     }

     return status;

--

1.7.1

 

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 

From: openmama-dev-bounces@... [mailto:openmama-dev-bounces@...] On Behalf Of Gary Molloy
Sent: 23 April 2015 17:54
To: openmama-dev@...
Subject: [Openmama-dev] [PATCH 1/3] [MAMAC] mamaPlugin Feature

 

Testing Strategy:-

Not middleware or O/S specific. 
 

Using the attached template you can create your own plugin and load it in via your mama.properties, for example:

 

mama.plugin.name_0=template

 

You can run up a mamaPublisher to test your plugin, for example:

 

mamapublisherc -tport pub -m wmw -l MAMA_INBOUND_TOPIC -v -v -v -v -v

 

You can expect to see output similar this if your plugin was loaded successfully:

 

2015-04-09 13:45:02: (f9018280) : mama_initPlugins(): Initialising [mama.plugin.name_0] template 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Sucessfully registered plugin functions for [template] 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Successfully run the init hook for mama plugin [template]  

 

If your plugin was not loaded successful you can expect to see output similar to this:

 

2015-04-09 13:45:02: (f9018280) : mama_initPlugins(): Initialising [mama.plugin.name_0] template 

2015-04-09 13:45:02: (f9018280) : mamaPlugin_registerFunctions(): Cannot load plugin, does not implement required function: [templateMamaPlugin_shutdownHook] 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Failed to register plugin functions for [template] 

 

Further documentation on the mamaPlugin feature will be available shortly which will provide more details on the feature which will include the various hooks available etc...

 

 

=========================================================================================================

 

From e2a6a3f9c5750cee780cb6185a1310b4e4b70629 Mon Sep 17 00:00:00 2001

From: Gary Molloy <g.molloy@...>

Date: Thu, 23 Apr 2015 11:22:14 -0400

Subject: [PATCH 1/3] [MAMAC] mamaPlugin Feature

 

A new feature, mamaPlugin has been introduced that will allow you to

create and run your own code within 'hooks' into the MAMA codebase.

 

A mamaPlugin is essentially a shared object.

 

Signed-off-by: Gary Molloy <g.molloy@...>

---

mama/c_cpp/src/c/Makefile.am    |    1 +

mama/c_cpp/src/c/SConscript     |    1 +

mama/c_cpp/src/c/SConscript.win |    1 +

mama/c_cpp/src/c/mama.c         |   10 +-

mama/c_cpp/src/c/mama/types.h   |   10 +

mama/c_cpp/src/c/plugin.c       |  472 +++++++++++++++++++++++++++++++++++++++

mama/c_cpp/src/c/plugin.h       |   59 +++++

mama/c_cpp/src/c/publisher.c    |   10 +

mama/c_cpp/src/c/transport.c    |   21 ++-

9 files changed, 579 insertions(+), 6 deletions(-)

create mode 100644 mama/c_cpp/src/c/plugin.c

create mode 100644 mama/c_cpp/src/c/plugin.h

 

diff --git a/mama/c_cpp/src/c/Makefile.am b/mama/c_cpp/src/c/Makefile.am

index c831ce4..318c353 100644

--- a/mama/c_cpp/src/c/Makefile.am

+++ b/mama/c_cpp/src/c/Makefile.am

@@ -131,6 +131,7 @@ libmama_la_SOURCES = \

     mamaStrUtils.h \

     mamaStrUtils.c \

               marketdata.c \

+    plugin.c \

     middleware.c \

               msg.c \

               msgfield.c \

diff --git a/mama/c_cpp/src/c/SConscript b/mama/c_cpp/src/c/SConscript

index 4362f50..f47e18c 100644

--- a/mama/c_cpp/src/c/SConscript

+++ b/mama/c_cpp/src/c/SConscript

@@ -98,6 +98,7 @@ libmama_sources = \

     mama.c

     mamaStrUtils.c

               marketdata.c

+    plugin.c

     middleware.c

               msg.c

               msgfield.c

diff --git a/mama/c_cpp/src/c/SConscript.win b/mama/c_cpp/src/c/SConscript.win

index 77e3e18..9a6ff05 100644

--- a/mama/c_cpp/src/c/SConscript.win

+++ b/mama/c_cpp/src/c/SConscript.win

@@ -50,6 +50,7 @@ dqpublishermanager.c

inbox.c

msgtype.c

msgutils.c

+plugin.c

senderId.c

reservedfields.c

subscription.c

diff --git a/mama/c_cpp/src/c/mama.c b/mama/c_cpp/src/c/mama.c

index 33a0768..5e31856 100644

--- a/mama/c_cpp/src/c/mama.c

+++ b/mama/c_cpp/src/c/mama.c

@@ -35,6 +35,7 @@

#include <payloadbridge.h>

#include <property.h>

#include <platform.h>

+#include <plugin.h>

 

 #include "fileutils.h"

#include "reservedfieldsimpl.h"

@@ -42,7 +43,6 @@

#include <mama/stat.h>

#include <mama/statfields.h>

#include <statsgeneratorinternal.h>

-#include <statsgeneratorinternal.h>

#include <mama/statscollector.h>

#include "transportimpl.h"

 

@@ -740,6 +740,9 @@ mama_openWithPropertiesCount (const char* path,

                               }

     }

 

+    /* This will initialise all plugins */

+    mama_initPlugins();

+

     prop = properties_Get (gProperties, "mama.catchcallbackexceptions.enable");

     if (prop != NULL && strtobool(prop))

     {

@@ -1253,9 +1256,12 @@ mama_closeCount (unsigned int* count)

                 gImpl.myPayloadLibraries[(uint8_t)payload] = NULL;

             }

         }

-       

+

        gDefaultPayload = NULL;

 

+       /* This will shutdown all plugins */

+       mama_shutdownPlugins();

+

         /* Look for a bridge for each of the middlewares and close them */

         for (middleware = 0; middleware != MAMA_MIDDLEWARE_MAX; ++middleware)

         {

diff --git a/mama/c_cpp/src/c/mama/types.h b/mama/c_cpp/src/c/mama/types.h

index 50d6608..03f6da8 100644

--- a/mama/c_cpp/src/c/mama/types.h

+++ b/mama/c_cpp/src/c/mama/types.h

@@ -74,6 +74,16 @@ typedef struct mamaBridgeImpl_* mamaBridge;

typedef struct mamaPayloadBridgeImpl_* mamaPayloadBridge;

 

 /**

+ * @brief Container for holding a mama plugin object

+ */

+typedef struct mamaPluginImpl_*     mamaPlugin;

+

+/**

+ * @brief Container for holding a mama plugin info

+ */

+typedef void*       mamaPluginInfo;

+

+/**

  * Flexible date/time format

  */

typedef   mama_u64_t*   mamaDateTime;

diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c

new file mode 100644

index 0000000..b6475fe

--- /dev/null

+++ b/mama/c_cpp/src/c/plugin.c

@@ -0,0 +1,472 @@

+/* $Id$

+ *

+ * OpenMAMA: The open middleware agnostic messaging API

+ * Copyright (C) 2011 NYSE Technologies, Inc.

+ *

+ * This library is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU Lesser General Public

+ * License as published by the Free Software Foundation; either

+ * version 2.1 of the License, or (at your option) any later version.

+ *

+ * This library is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

+ * Lesser General Public License for more details.

+ *

+ * You should have received a copy of the GNU Lesser General Public

+ * License along with this library; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+ * 02110-1301 USA

+ */

+

+#include <string.h>

+#include <stdio.h>

+#include <limits.h>

+

+#include "wombat/port.h"

+#include "wombat/environment.h"

+#include "wombat/strutils.h"

+#include <wombat/wtable.h>

+

+#include <mama/mama.h>

+#include <mama/error.h>

+#include <mamainternal.h>

+#include <mama/version.h>

+#include <property.h>

+#include <plugin.h>

+#include <platform.h>

+

+#define PLUGIN_PROPERTY "mama.plugin.name_"

+#define PLUGIN_NAME "mamaplugin"

+

+#define MAX_PLUGINS 100

+#define MAX_PLUGIN_STRING 1024

+

+#define MAX_FUNC_STRING 256

+

+/**

+ * @brief Mechanism for registering required plugin functions.

+ *

+ * Taking a function string name search the shared library handle, using the

+ * loadLibFunc portability method, for the function. If it is found, set the

+ * appropriate function pointer in the plugin struct to the result. If not,

+ * log as an error the fact that the funciton cannot be found, and return

+ * MAMA_STATUS_PLATFORM

+ *

+ * @param FUNCSTRINGNAME The string function name.

+ * @param FUNCIMPLNAME The name of the function pointer in the plugin struct

+ * @param FUNCIMPLTYPE The type of the function pointer expected.

+ */

+#define REGISTER_PLUGIN_FUNCTION(FUNCSTRINGNAME, FUNCIMPLNAME, FUNCIMPLTYPE)    \

+do {                                                                            \

+    snprintf (functionName, MAX_FUNC_STRING, "%s"#FUNCSTRINGNAME, name);        \

+    result = loadLibFunc (pluginLib, functionName);                             \

+                                                                                \

+    if (NULL != result) {                                                       \

+        (pluginImpl)->FUNCIMPLNAME = *(FUNCIMPLTYPE*)&result;                   \

+        result = NULL;                                                          \

+    } else {                                                                    \

+        mama_log (MAMA_LOG_LEVEL_ERROR,                                         \

+                  "mamaPlugin_registerFunctions(): "                            \

+                  "Cannot load plugin, does not implement required function: [%s]",\

+                  functionName);                                                \

+        status = MAMA_STATUS_PLATFORM;                                          \

+        return status;                                                          \

+    }                                                                           \

+} while (0)

+

+/**

+ * @brief Mechanism for registering required plugin functions.

+ *

+ * Taking a function string name search the shared library handle, using the

+ * loadLibFunc portability method, for the function. If it is found, set the

+ * appropriate function pointer in the plugin struct to the result. If not

+ * log the fact that the function has not been found, and continue.

+ *

+ * @param FUNCSTRINGNAME The string function name.

+ * @param FUNCIMPLNAME The name of the function pointer in the plugin struct

+ * @param FUNCIMPLTYPE The type of the function pointer expected.

+ */

+#define REGISTER_OPTIONAL_PLUGIN_FUNCTION(FUNCSTRINGNAME,                       \

+                                          FUNCIMPLNAME,                         \

+                                          FUNCIMPLTYPE)                         \

+do {                                                                            \

+    snprintf (functionName, MAX_FUNC_STRING, "%s"#FUNCSTRINGNAME, name);        \

+    result = loadLibFunc (pluginLib, functionName);                             \

+                                                                                \

+    if (NULL != result) {                                                       \

+        (pluginImpl)->FUNCIMPLNAME = *(FUNCIMPLTYPE*)&result;                   \

+        result = NULL;                                                          \

+    } else {                                                                    \

+        mama_log (MAMA_LOG_LEVEL_FINE,                                          \

+                  "mamaPlugin_registerFunctions(): "                            \

+                  "Optional plugin function [%s] not found. Unavailable.",      \

+                  functionName);                                                \

+    }                                                                           \

+} while (0)

+

+typedef struct mamaPluginImpl_

+{

+    LIB_HANDLE          mPluginHandle;

+    char*               mPluginName;

+    mamaPluginInfo      mPluginInfo;

+

+    mamaPlugin_publisherPreSendHook     mamaPluginPublisherPreSendHook;

+    mamaPlugin_transportPostCreateHook  mamaPluginTransportPostCreateHook;

+    mamaPlugin_shutdownHook             mamaPluginShutdownHook;

+    mamaPlugin_initHook                 mamaPluginInitHook;

+

+} mamaPluginImpl;

+

+static mamaPluginImpl*      gPlugins[MAX_PLUGINS];

+static volatile int         gPluginNo = 0;

+

+/**

+ * @brief Used to load register all possible plugin functions to be

+ *        used within Mama.

+ *

+ * param[in] pluginLib

+ * param[in] name

+ * param[in] pluginImpl The plugin impl to be used

+ *

+ * @return mama_status return code can be one of:

+ *          MAMA_STATUS_OK

+ */

+mama_status

+mamaPlugin_registerFunctions   (LIB_HANDLE      pluginLib,

+                                const char*     name,

+                                mamaPluginInfo  pluginInfo,

+                                mamaPluginImpl* pluginImpl);

+

+/**

+ * @brief Used find a plugin using the library name

+ *

+ * param[in] name

+ *

+ * @return a valid mamaPluginImpl if found

+ */

+mamaPluginImpl*

+mamaPlugin_findPlugin (const char* name);

+

+/**

+ * @brief Used find a plugin using the library name

+ *

+ * param[in] pluginName

+ *

+ * @return mama_status return code can be one of:

+ *          MAMA_STATUS_OK

+ */

+mama_status

+mama_loadPlugin (const char* pluginName);

+

+

+/**

+ * Register function pointers associated with a specific plugin.

+ */

+mama_status

+mamaPlugin_registerFunctions (LIB_HANDLE      pluginLib,

+                              const char*     name,

+                              mamaPluginInfo  pluginInfo,

+                              mamaPluginImpl* pluginImpl)

+{

+    mama_status  status        = MAMA_STATUS_OK;

+    void*        result        = NULL;

+    char         functionName[MAX_FUNC_STRING];

+

+    /* Save off some informatin on the plugin */

+    pluginImpl->mPluginHandle = pluginLib;

+    pluginImpl->mPluginName = strdup(name);

+    pluginImpl->mPluginInfo = pluginInfo;

+

+

+    /* Required fuctions */

+    REGISTER_PLUGIN_FUNCTION (MamaPlugin_initHook, mamaPluginInitHook,

+                              mamaPlugin_initHook);

+    REGISTER_PLUGIN_FUNCTION (MamaPlugin_shutdownHook, mamaPluginShutdownHook,

+                              mamaPlugin_shutdownHook);

+

+

+    /* Optional fuctions */

+    REGISTER_OPTIONAL_PLUGIN_FUNCTION (MamaPlugin_publisherPreSendHook, mamaPluginPublisherPreSendHook,

+                                       mamaPlugin_publisherPreSendHook);

+    REGISTER_OPTIONAL_PLUGIN_FUNCTION (MamaPlugin_transportPostCreateHook, mamaPluginTransportPostCreateHook,

+                                       mamaPlugin_transportPostCreateHook);

+

+   return status;

+}

+

+mama_status

+mama_initPlugins(void)

+{

+    int             pluginCount      = 0;

+    const char*     prop             = NULL;

+    char            propString[MAX_PLUGIN_STRING];

+

+    for (pluginCount = 0; pluginCount < MAX_PLUGINS; pluginCount++)

+    {

+        snprintf(propString, MAX_PLUGIN_STRING,

+            PLUGIN_PROPERTY"%d",

+            pluginCount);

+

+        prop = properties_Get (mamaInternal_getProperties (), propString);

+        if (prop != NULL && strlen(prop)!= 0)

+        {

+            mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising [%s] %s", propString, prop);

+            mama_loadPlugin (prop);

+        }

+    }

+

+    mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising mamacenterprise");

+    mama_loadPlugin ("mamacenterprise");

+

+    return MAMA_STATUS_OK;

+}

+

+mama_status

+mama_loadPlugin (const char* pluginName)

+{

+    LIB_HANDLE              pluginLib       = NULL;

+    mamaPluginImpl*         pluginImpl      = NULL;

+    mama_status             status          = MAMA_STATUS_OK;

+    mamaPluginInfo          pluginInfo      = NULL;

+    char                    loadPluginName  [MAX_PLUGIN_STRING];

+    mamaPluginImpl*         aPluginImpl     = NULL;

+

+    if (!pluginName)

+        return MAMA_STATUS_NULL_ARG;

+

+    pluginImpl = mamaPlugin_findPlugin(pluginName);

+

+    /*

+     * Check to see if pluginImpl has already been loaded

+     */

+    if (pluginImpl == NULL)

+    {

+       /* The plugin name should be of the format mamaplugin<name> */

+        if (strncmp(pluginName, "mamacenterprise", MAX_PLUGIN_STRING) == 0)

+            snprintf(loadPluginName, MAX_PLUGIN_STRING,

+                "%s",

+                pluginName);

+        else

+            snprintf(loadPluginName, MAX_PLUGIN_STRING,

+                "%s%s",

+                PLUGIN_NAME,

+                pluginName);

+

+        pluginLib = openSharedLib (loadPluginName, NULL);

+

+        if (!pluginLib)

+        {

+

+           mama_log (MAMA_LOG_LEVEL_ERROR,

+                    "mama_loadPlugin(): "

+                    "Could not open plugin library [%s] [%s]",

+                    pluginName,

+                    getLibError());

+            return MAMA_STATUS_PLATFORM;

+        }

+

+        /* Create structure to hold plugin information */

+        aPluginImpl = (mamaPluginImpl*)calloc (1, sizeof(mamaPluginImpl));

+

+        status = mamaPlugin_registerFunctions (pluginLib,

+                                               pluginName,

+                                               pluginInfo,

+                                               aPluginImpl);

+

+        if (MAMA_STATUS_OK == status)

+        {

+            mama_log (MAMA_LOG_LEVEL_NORMAL,

+                     "mama_loadPlugin(): "

+                     "Sucessfully registered plugin functions for [%s]",

+                     pluginName);

+

+        }

+        else

+        {

+            mama_log (MAMA_LOG_LEVEL_WARN,

+                     "mama_loadPlugin(): "

+                     "Failed to register plugin functions for [%s]",

+                     pluginName);

+

+            closeSharedLib (aPluginImpl->mPluginHandle);

+

+            free ((char*)aPluginImpl->mPluginName);

+            free ((mamaPluginImpl*)aPluginImpl);

+

+            return status;

+        }

+

+        /* Invoke the init function */

+        status = aPluginImpl->mamaPluginInitHook (aPluginImpl->mPluginInfo);

+

+        if (MAMA_STATUS_OK == status)

+        {

+            mama_log (MAMA_LOG_LEVEL_NORMAL,

+                      "mama_loadPlugin(): Successfully run the init hook for mama plugin [%s]",

+                       aPluginImpl->mPluginName);

+        }

+        else

+        {

+            mama_log (MAMA_LOG_LEVEL_WARN,

+                      "mama_loadPlugin(): Init hook failed for mama plugin [%s]",

+                       aPluginImpl->mPluginName);

+

+            closeSharedLib (aPluginImpl->mPluginHandle);

+

+            free ((char*)aPluginImpl->mPluginName);

+            free ((mamaPluginImpl*)aPluginImpl);

+

+            return status;

+        }

+

+        /* Save off the plugin impl and increment the plugin counter */

+        gPlugins[gPluginNo] = aPluginImpl;

+        gPluginNo++;

+

+    }

+    else

+    {

+        mama_log (MAMA_LOG_LEVEL_NORMAL,

+                 "mama_loadPlugin(): "

+                 "Plugin [%s] has already been loaded and initialised",

+                 pluginName);

+    }

+

+    return MAMA_STATUS_OK;

+}

+

+mama_status

+mama_shutdownPlugins (void)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+    int          ret    = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin]->mPluginHandle != NULL)

+        {

+            /* Fire the user shutdown hook first - if one is present */

+            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            {

+                gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+            }

+

+            ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

+            if (0!=ret)

+            {

+                 mama_log (MAMA_LOG_LEVEL_WARN,

+                            "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

+                            gPlugins[plugin]->mPluginName);

+            }

+            else

+            {

+                 mama_log (MAMA_LOG_LEVEL_WARN,

+                            "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

+                            gPlugins[plugin]->mPluginName);

+            }

+

+            free ((char*)gPlugins[plugin]->mPluginName);

+            free (gPlugins[plugin]);

+            gPlugins[plugin] = NULL;

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_firePublisherPreSendHook (mamaPublisher publisher, mamaMsg message)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginPublisherPreSendHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginPublisherPreSendHook (gPlugins[plugin]->mPluginInfo, publisher, message);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_firePublisherPreSendHook(): Publisher pre send hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_fireTransportPostCreateHook (mamaTransport transport)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginTransportPostCreateHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginTransportPostCreateHook (gPlugins[plugin]->mPluginInfo, transport);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_fireTransportPostCreateHook(): Transport post create hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_fireShutdownHook (void)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_fireShutdownHook(): Shutdown hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mamaPluginImpl*

+mamaPlugin_findPlugin (const char* name)

+{

+    int plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin])

+        {

+            if ((strncmp(gPlugins[plugin]->mPluginName, name, MAX_PLUGIN_STRING) == 0))

+            {

+                return gPlugins[plugin];

+            }

+        }

+    }

+    return NULL;

+}

diff --git a/mama/c_cpp/src/c/plugin.h b/mama/c_cpp/src/c/plugin.h

new file mode 100644

index 0000000..df43b27

--- /dev/null

+++ b/mama/c_cpp/src/c/plugin.h

@@ -0,0 +1,59 @@

+/* $Id$

+ *

+ * OpenMAMA: The open middleware agnostic messaging API

+ * Copyright (C) 2011 NYSE Technologies, Inc.

+ *

+ * This library is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU Lesser General Public

+ * License as published by the Free Software Foundation; either

+ * version 2.1 of the License, or (at your option) any later version.

+ *

+ * This library is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

+ * Lesser General Public License for more details.

+ *

+ * You should have received a copy of the GNU Lesser General Public

+ * License along with this library; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+ * 02110-1301 USA

+ */

+

+#ifndef PluginH__

+#define PluginH__

+

+

+/**

+ * @brief Containers used within the mama plugin

+ */

+typedef mama_status (*mamaPlugin_publisherPreSendHook) (mamaPluginInfo pluginInfo, mamaPublisher publisher, mamaMsg message);

+typedef mama_status (*mamaPlugin_transportPostCreateHook) (mamaPluginInfo pluginInfo, mamaTransport transport);

+typedef mama_status (*mamaPlugin_shutdownHook) (mamaPluginInfo pluginInfo);

+typedef mama_status (*mamaPlugin_initHook) (mamaPluginInfo* pluginInfo);

+

+/**

+ * Initialize the internal plugin interface

+ *

+ * @return mama status code

+ */

+extern mama_status

+mama_initPlugins (void);

+

+/**

+ * Shutdown the internal plugin interface

+ *

+ * @return mama status code

+ */

+extern mama_status

+mama_shutdownPlugins (void);

+

+extern mama_status

+mamaPlugin_firePublisherPreSendHook (mamaPublisher publisher, mamaMsg message);

+

+extern mama_status

+mamaPlugin_fireTransportPostCreateHook (mamaTransport transport);

+

+extern mama_status

+mamaPlugin_fireShutdownHook (void);

+

+#endif /* PluginH__ */

diff --git a/mama/c_cpp/src/c/publisher.c b/mama/c_cpp/src/c/publisher.c

index 4612d17..6a7f92d 100644

--- a/mama/c_cpp/src/c/publisher.c

+++ b/mama/c_cpp/src/c/publisher.c

@@ -23,6 +23,7 @@

#include "mama/publisher.h"

 

 #include "bridge.h"

+#include "plugin.h"

#include "throttle.h"

#include "transportimpl.h"

 

@@ -245,6 +246,15 @@ mamaPublisher_send (mamaPublisher publisher,

     if (!impl->mMamaPublisherBridgeImpl) return MAMA_STATUS_INVALID_ARG;

     if (!impl->mBridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL;

 

+    /* Calling plugin hook */

+    status = mamaPlugin_firePublisherPreSendHook (publisher, msg);

+    if (MAMA_STATUS_OK != status)

+    {

+        mama_log (MAMA_LOG_LEVEL_ERROR,

+                  "mamaPublisher_send(): PublisherPreSendHook failed. Not sending message.");

+        return status;

+    }

+

     status = impl->mBridgeImpl->bridgeMamaPublisherSend

         (impl->mMamaPublisherBridgeImpl,

          msg);

diff --git a/mama/c_cpp/src/c/transport.c b/mama/c_cpp/src/c/transport.c

index 339dbc0..622f47d 100644

--- a/mama/c_cpp/src/c/transport.c

+++ b/mama/c_cpp/src/c/transport.c

@@ -25,6 +25,7 @@

 

 #include "mama/mama.h"

#include "throttle.h"

+#include "plugin.h"

#include "list.h"

#include "transportimpl.h"

#include "bridge.h"

@@ -876,10 +877,22 @@ mamaTransport_create (mamaTransport transport,

 

     if ((!self->mDisableRefresh) && (!mamaTransportInternal_disableRefreshes(name)))

     {

-        return refreshTransport_create (&self->mRefreshTransport,

-                                    (mamaTransport)self,

-                                    self->mListeners,

-                                    self->mBridgeImpl);

+        status = refreshTransport_create (&self->mRefreshTransport,

+                                          (mamaTransport)self,

+                                          self->mListeners,

+                                          self->mBridgeImpl);

+

+        if (MAMA_STATUS_OK != status)

+            return status;

+    }

+

+    /* Calling plugin hook*/

+    status = mamaPlugin_fireTransportPostCreateHook (transport);

+    if (MAMA_STATUS_OK != status)

+    {

+        mama_log (MAMA_LOG_LEVEL_ERROR,

+                  "mamaTransport_create(): TransportPostCreateHook failed with a status of %s",

+                   mamaStatus_stringForStatus(status));

     }

 

     return MAMA_STATUS_OK;

--

1.7.1

 

 

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 



---
This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.

Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures and to http://www.db.com/unitedkingdom/content/privacy.htm for information about privacy.


Glenn McClements <g.mcclements@...>
 

Hi Keith,
Sorry forgot to follow this up on thread as we’ve caught up elsewhere, but for the benefit of everyone else on the list in answer to your question: 

-          What was the logic behind selection of the points where plug-in hooks can get called?



I think most of the answers are on another part of thread (copied below). For entitlements the first pass would be to remove the existing callouts to DART and replace them with plugin calls. This could then be extended to support server side entitlements as plugin hooks can be added easily. 

---
To give some background on this change, it’s a first pass at a plugin framework that I hope to build on to allow OpenMAMA to become much more of a flexible framework.

The initial hooks were there because of an immediate need, but I’d like to get feedback on where else people would find hooks useful. One area which I’d like to explore is for pluggable entitlements. Using the plugin framework rather than the bridge mechanism:

- the plugins are already dynamic in the sense that any can be loaded at runtime 
- there is the concept of optional functions, so that a plugin can implement as many or as few hooks as they wish. We can also add new hooks without breaking compatibility. 
- the hooks are multi purpose, and multiple plugins can be called from the same hook
----

Glenn 

From: <openmama-dev-bounces@...> on behalf of Keith Rudd
Date: Monday, 11 May 2015 14:30
To: Gary Molloy, "openmama-dev@..."
Subject: Re: [Openmama-dev] [PATCH 1/3] [MAMAC] mamaPlugin Feature - additional

Classification: Public

Thanks for forwarding the doc Gary.

 

I found the mamaPlugin details an interesting read.

 

One question:

-          What was the logic behind selection of the points where plug-in hooks can get called?

 

I was thinking of a case where you used this as a way of having a custom entitlements implementation.

In this sense, the hook at the point of mamaPublisher_send() makes sense because you could use that to implement publishing entitlements control, which is lacking in OpenMAMA.

 

However, there’s no hook at the point of mamaSubscription_create(), so you’d have to rely on the existing OpenMAMA hook (OEA Client interface) to check subscriber entitlements. It’s possible to do both of course but this leads to a rather in-elegant hybrid solution mixing the OEA client interface plus use of a custom hook library.

 

Probably better to be able to do one or the other entirely. (So extend OEAClient interface, or add plug in hook at ALL the points where entitlement checking might be relevant)

 

Were there some other particular use cases in mind that drove the selection of plugin hook points?

 

Regards,

Keith

 

From: openmama-dev-bounces@... [mailto:openmama-dev-bounces@...] On Behalf Of Gary Molloy
Sent: 01 May 2015 17:31
To: openmama-dev@...
Subject: Re: [Openmama-dev] [PATCH 1/3] [MAMAC] mamaPlugin Feature - additional

 

Hi Guys,

 

As promised, please find below a link to a document on the mamaPlugin feature:

https://docs.google.com/document/d/1HcV43uFJrV_pX0M0N7oDoZkWly0LjmyIxM9U-YpBtFQ/edit?usp=sharing

Thanks,

Gary

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 

From: Gary Molloy
Sent: 30 April 2015 10:58
To: openmama-dev@...
Subject: RE: [PATCH 1/3] [MAMAC] mamaPlugin Feature - additional

 

From 76a6db152998cbb32de58eb1cb9d6c1ab9307a1e Mon Sep 17 00:00:00 2001

From: Gary Molloy <g.molloy@...>

Date: Wed, 29 Apr 2015 13:05:23 -0400

Subject: [PATCH] [MAMAC] mamaPlugin Feature - addition

 

Addition to the existing mamaPlugin patch to remove references to internal shared objects and a missing null check.

 

Signed-off-by: Gary Molloy <g.molloy@...>

---

mama/c_cpp/src/c/plugin.c |   61 ++++++++++++++++++++------------------------

1 files changed, 28 insertions(+), 33 deletions(-)

 

diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c

index b6475fe..303ab9f 100644

--- a/mama/c_cpp/src/c/plugin.c

+++ b/mama/c_cpp/src/c/plugin.c

@@ -216,9 +216,6 @@ mama_initPlugins(void)

         }

     }

 

-    mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising mamacenterprise");

-    mama_loadPlugin ("mamacenterprise");

-

     return MAMA_STATUS_OK;

}

 

@@ -243,15 +240,10 @@ mama_loadPlugin (const char* pluginName)

     if (pluginImpl == NULL)

     {

        /* The plugin name should be of the format mamaplugin<name> */

-        if (strncmp(pluginName, "mamacenterprise", MAX_PLUGIN_STRING) == 0)

-            snprintf(loadPluginName, MAX_PLUGIN_STRING,

-                "%s",

-                pluginName);

-        else

-            snprintf(loadPluginName, MAX_PLUGIN_STRING,

-                "%s%s",

-                PLUGIN_NAME,

-                pluginName);

+        snprintf(loadPluginName, MAX_PLUGIN_STRING,

+            "%s%s",

+            PLUGIN_NAME,

+            pluginName);

 

         pluginLib = openSharedLib (loadPluginName, NULL);

 

@@ -345,31 +337,34 @@ mama_shutdownPlugins (void)

 

     for (plugin = 0; plugin <= gPluginNo; plugin++)

     {

-        if (gPlugins[plugin]->mPluginHandle != NULL)

+        if (gPlugins[plugin] != NULL)

         {

-            /* Fire the user shutdown hook first - if one is present */

-            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            if (gPlugins[plugin]->mPluginHandle != NULL)

             {

-                gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

-            }

+                /* Fire the user shutdown hook first - if one is present */

+                if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+                {

+                    gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+                }

 

-            ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

-            if (0!=ret)

-            {

-                 mama_log (MAMA_LOG_LEVEL_WARN,

-                            "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

-                            gPlugins[plugin]->mPluginName);

-            }

-            else

-            {

-                 mama_log (MAMA_LOG_LEVEL_WARN,

-                            "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

-                            gPlugins[plugin]->mPluginName);

-            }

+                ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

+                if (0!=ret)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+                else

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

+                                gPlugins[plugin]->mPluginName);

+                }

 

-            free ((char*)gPlugins[plugin]->mPluginName);

-            free (gPlugins[plugin]);

-            gPlugins[plugin] = NULL;

+                free ((char*)gPlugins[plugin]->mPluginName);

+                free (gPlugins[plugin]);

+                gPlugins[plugin] = NULL;

+            }

         }

     }

     return status;

--

1.7.1

 

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 

From: openmama-dev-bounces@... [mailto:openmama-dev-bounces@...] On Behalf Of Gary Molloy
Sent: 23 April 2015 17:54
To: openmama-dev@...
Subject: [Openmama-dev] [PATCH 1/3] [MAMAC] mamaPlugin Feature

 

Testing Strategy:-

Not middleware or O/S specific. 
 

Using the attached template you can create your own plugin and load it in via your mama.properties, for example:

 

mama.plugin.name_0=template

 

You can run up a mamaPublisher to test your plugin, for example:

 

mamapublisherc -tport pub -m wmw -l MAMA_INBOUND_TOPIC -v -v -v -v -v

 

You can expect to see output similar this if your plugin was loaded successfully:

 

2015-04-09 13:45:02: (f9018280) : mama_initPlugins(): Initialising [mama.plugin.name_0] template 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Sucessfully registered plugin functions for [template] 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Successfully run the init hook for mama plugin [template]  

 

If your plugin was not loaded successful you can expect to see output similar to this:

 

2015-04-09 13:45:02: (f9018280) : mama_initPlugins(): Initialising [mama.plugin.name_0] template 

2015-04-09 13:45:02: (f9018280) : mamaPlugin_registerFunctions(): Cannot load plugin, does not implement required function: [templateMamaPlugin_shutdownHook] 

2015-04-09 13:45:02: (f9018280) : mama_loadPlugin(): Failed to register plugin functions for [template] 

 

Further documentation on the mamaPlugin feature will be available shortly which will provide more details on the feature which will include the various hooks available etc...

 

 

=========================================================================================================

 

From e2a6a3f9c5750cee780cb6185a1310b4e4b70629 Mon Sep 17 00:00:00 2001

From: Gary Molloy <g.molloy@...>

Date: Thu, 23 Apr 2015 11:22:14 -0400

Subject: [PATCH 1/3] [MAMAC] mamaPlugin Feature

 

A new feature, mamaPlugin has been introduced that will allow you to

create and run your own code within 'hooks' into the MAMA codebase.

 

A mamaPlugin is essentially a shared object.

 

Signed-off-by: Gary Molloy <g.molloy@...>

---

mama/c_cpp/src/c/Makefile.am    |    1 +

mama/c_cpp/src/c/SConscript     |    1 +

mama/c_cpp/src/c/SConscript.win |    1 +

mama/c_cpp/src/c/mama.c         |   10 +-

mama/c_cpp/src/c/mama/types.h   |   10 +

mama/c_cpp/src/c/plugin.c       |  472 +++++++++++++++++++++++++++++++++++++++

mama/c_cpp/src/c/plugin.h       |   59 +++++

mama/c_cpp/src/c/publisher.c    |   10 +

mama/c_cpp/src/c/transport.c    |   21 ++-

9 files changed, 579 insertions(+), 6 deletions(-)

create mode 100644 mama/c_cpp/src/c/plugin.c

create mode 100644 mama/c_cpp/src/c/plugin.h

 

diff --git a/mama/c_cpp/src/c/Makefile.am b/mama/c_cpp/src/c/Makefile.am

index c831ce4..318c353 100644

--- a/mama/c_cpp/src/c/Makefile.am

+++ b/mama/c_cpp/src/c/Makefile.am

@@ -131,6 +131,7 @@ libmama_la_SOURCES = \

     mamaStrUtils.h \

     mamaStrUtils.c \

               marketdata.c \

+    plugin.c \

     middleware.c \

               msg.c \

               msgfield.c \

diff --git a/mama/c_cpp/src/c/SConscript b/mama/c_cpp/src/c/SConscript

index 4362f50..f47e18c 100644

--- a/mama/c_cpp/src/c/SConscript

+++ b/mama/c_cpp/src/c/SConscript

@@ -98,6 +98,7 @@ libmama_sources = \

     mama.c

     mamaStrUtils.c

               marketdata.c

+    plugin.c

     middleware.c

               msg.c

               msgfield.c

diff --git a/mama/c_cpp/src/c/SConscript.win b/mama/c_cpp/src/c/SConscript.win

index 77e3e18..9a6ff05 100644

--- a/mama/c_cpp/src/c/SConscript.win

+++ b/mama/c_cpp/src/c/SConscript.win

@@ -50,6 +50,7 @@ dqpublishermanager.c

inbox.c

msgtype.c

msgutils.c

+plugin.c

senderId.c

reservedfields.c

subscription.c

diff --git a/mama/c_cpp/src/c/mama.c b/mama/c_cpp/src/c/mama.c

index 33a0768..5e31856 100644

--- a/mama/c_cpp/src/c/mama.c

+++ b/mama/c_cpp/src/c/mama.c

@@ -35,6 +35,7 @@

#include <payloadbridge.h>

#include <property.h>

#include <platform.h>

+#include <plugin.h>

 

 #include "fileutils.h"

#include "reservedfieldsimpl.h"

@@ -42,7 +43,6 @@

#include <mama/stat.h>

#include <mama/statfields.h>

#include <statsgeneratorinternal.h>

-#include <statsgeneratorinternal.h>

#include <mama/statscollector.h>

#include "transportimpl.h"

 

@@ -740,6 +740,9 @@ mama_openWithPropertiesCount (const char* path,

                               }

     }

 

+    /* This will initialise all plugins */

+    mama_initPlugins();

+

     prop = properties_Get (gProperties, "mama.catchcallbackexceptions.enable");

     if (prop != NULL && strtobool(prop))

     {

@@ -1253,9 +1256,12 @@ mama_closeCount (unsigned int* count)

                 gImpl.myPayloadLibraries[(uint8_t)payload] = NULL;

             }

         }

-       

+

        gDefaultPayload = NULL;

 

+       /* This will shutdown all plugins */

+       mama_shutdownPlugins();

+

         /* Look for a bridge for each of the middlewares and close them */

         for (middleware = 0; middleware != MAMA_MIDDLEWARE_MAX; ++middleware)

         {

diff --git a/mama/c_cpp/src/c/mama/types.h b/mama/c_cpp/src/c/mama/types.h

index 50d6608..03f6da8 100644

--- a/mama/c_cpp/src/c/mama/types.h

+++ b/mama/c_cpp/src/c/mama/types.h

@@ -74,6 +74,16 @@ typedef struct mamaBridgeImpl_* mamaBridge;

typedef struct mamaPayloadBridgeImpl_* mamaPayloadBridge;

 

 /**

+ * @brief Container for holding a mama plugin object

+ */

+typedef struct mamaPluginImpl_*     mamaPlugin;

+

+/**

+ * @brief Container for holding a mama plugin info

+ */

+typedef void*       mamaPluginInfo;

+

+/**

  * Flexible date/time format

  */

typedef   mama_u64_t*   mamaDateTime;

diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c

new file mode 100644

index 0000000..b6475fe

--- /dev/null

+++ b/mama/c_cpp/src/c/plugin.c

@@ -0,0 +1,472 @@

+/* $Id$

+ *

+ * OpenMAMA: The open middleware agnostic messaging API

+ * Copyright (C) 2011 NYSE Technologies, Inc.

+ *

+ * This library is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU Lesser General Public

+ * License as published by the Free Software Foundation; either

+ * version 2.1 of the License, or (at your option) any later version.

+ *

+ * This library is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

+ * Lesser General Public License for more details.

+ *

+ * You should have received a copy of the GNU Lesser General Public

+ * License along with this library; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+ * 02110-1301 USA

+ */

+

+#include <string.h>

+#include <stdio.h>

+#include <limits.h>

+

+#include "wombat/port.h"

+#include "wombat/environment.h"

+#include "wombat/strutils.h"

+#include <wombat/wtable.h>

+

+#include <mama/mama.h>

+#include <mama/error.h>

+#include <mamainternal.h>

+#include <mama/version.h>

+#include <property.h>

+#include <plugin.h>

+#include <platform.h>

+

+#define PLUGIN_PROPERTY "mama.plugin.name_"

+#define PLUGIN_NAME "mamaplugin"

+

+#define MAX_PLUGINS 100

+#define MAX_PLUGIN_STRING 1024

+

+#define MAX_FUNC_STRING 256

+

+/**

+ * @brief Mechanism for registering required plugin functions.

+ *

+ * Taking a function string name search the shared library handle, using the

+ * loadLibFunc portability method, for the function. If it is found, set the

+ * appropriate function pointer in the plugin struct to the result. If not,

+ * log as an error the fact that the funciton cannot be found, and return

+ * MAMA_STATUS_PLATFORM

+ *

+ * @param FUNCSTRINGNAME The string function name.

+ * @param FUNCIMPLNAME The name of the function pointer in the plugin struct

+ * @param FUNCIMPLTYPE The type of the function pointer expected.

+ */

+#define REGISTER_PLUGIN_FUNCTION(FUNCSTRINGNAME, FUNCIMPLNAME, FUNCIMPLTYPE)    \

+do {                                                                            \

+    snprintf (functionName, MAX_FUNC_STRING, "%s"#FUNCSTRINGNAME, name);        \

+    result = loadLibFunc (pluginLib, functionName);                             \

+                                                                                \

+    if (NULL != result) {                                                       \

+        (pluginImpl)->FUNCIMPLNAME = *(FUNCIMPLTYPE*)&result;                   \

+        result = NULL;                                                          \

+    } else {                                                                    \

+        mama_log (MAMA_LOG_LEVEL_ERROR,                                         \

+                  "mamaPlugin_registerFunctions(): "                            \

+                  "Cannot load plugin, does not implement required function: [%s]",\

+                  functionName);                                                \

+        status = MAMA_STATUS_PLATFORM;                                          \

+        return status;                                                          \

+    }                                                                           \

+} while (0)

+

+/**

+ * @brief Mechanism for registering required plugin functions.

+ *

+ * Taking a function string name search the shared library handle, using the

+ * loadLibFunc portability method, for the function. If it is found, set the

+ * appropriate function pointer in the plugin struct to the result. If not

+ * log the fact that the function has not been found, and continue.

+ *

+ * @param FUNCSTRINGNAME The string function name.

+ * @param FUNCIMPLNAME The name of the function pointer in the plugin struct

+ * @param FUNCIMPLTYPE The type of the function pointer expected.

+ */

+#define REGISTER_OPTIONAL_PLUGIN_FUNCTION(FUNCSTRINGNAME,                       \

+                                          FUNCIMPLNAME,                         \

+                                          FUNCIMPLTYPE)                         \

+do {                                                                            \

+    snprintf (functionName, MAX_FUNC_STRING, "%s"#FUNCSTRINGNAME, name);        \

+    result = loadLibFunc (pluginLib, functionName);                             \

+                                                                                \

+    if (NULL != result) {                                                       \

+        (pluginImpl)->FUNCIMPLNAME = *(FUNCIMPLTYPE*)&result;                   \

+        result = NULL;                                                          \

+    } else {                                                                    \

+        mama_log (MAMA_LOG_LEVEL_FINE,                                          \

+                  "mamaPlugin_registerFunctions(): "                            \

+                  "Optional plugin function [%s] not found. Unavailable.",      \

+                  functionName);                                                \

+    }                                                                           \

+} while (0)

+

+typedef struct mamaPluginImpl_

+{

+    LIB_HANDLE          mPluginHandle;

+    char*               mPluginName;

+    mamaPluginInfo      mPluginInfo;

+

+    mamaPlugin_publisherPreSendHook     mamaPluginPublisherPreSendHook;

+    mamaPlugin_transportPostCreateHook  mamaPluginTransportPostCreateHook;

+    mamaPlugin_shutdownHook             mamaPluginShutdownHook;

+    mamaPlugin_initHook                 mamaPluginInitHook;

+

+} mamaPluginImpl;

+

+static mamaPluginImpl*      gPlugins[MAX_PLUGINS];

+static volatile int         gPluginNo = 0;

+

+/**

+ * @brief Used to load register all possible plugin functions to be

+ *        used within Mama.

+ *

+ * param[in] pluginLib

+ * param[in] name

+ * param[in] pluginImpl The plugin impl to be used

+ *

+ * @return mama_status return code can be one of:

+ *          MAMA_STATUS_OK

+ */

+mama_status

+mamaPlugin_registerFunctions   (LIB_HANDLE      pluginLib,

+                                const char*     name,

+                                mamaPluginInfo  pluginInfo,

+                                mamaPluginImpl* pluginImpl);

+

+/**

+ * @brief Used find a plugin using the library name

+ *

+ * param[in] name

+ *

+ * @return a valid mamaPluginImpl if found

+ */

+mamaPluginImpl*

+mamaPlugin_findPlugin (const char* name);

+

+/**

+ * @brief Used find a plugin using the library name

+ *

+ * param[in] pluginName

+ *

+ * @return mama_status return code can be one of:

+ *          MAMA_STATUS_OK

+ */

+mama_status

+mama_loadPlugin (const char* pluginName);

+

+

+/**

+ * Register function pointers associated with a specific plugin.

+ */

+mama_status

+mamaPlugin_registerFunctions (LIB_HANDLE      pluginLib,

+                              const char*     name,

+                              mamaPluginInfo  pluginInfo,

+                              mamaPluginImpl* pluginImpl)

+{

+    mama_status  status        = MAMA_STATUS_OK;

+    void*        result        = NULL;

+    char         functionName[MAX_FUNC_STRING];

+

+    /* Save off some informatin on the plugin */

+    pluginImpl->mPluginHandle = pluginLib;

+    pluginImpl->mPluginName = strdup(name);

+    pluginImpl->mPluginInfo = pluginInfo;

+

+

+    /* Required fuctions */

+    REGISTER_PLUGIN_FUNCTION (MamaPlugin_initHook, mamaPluginInitHook,

+                              mamaPlugin_initHook);

+    REGISTER_PLUGIN_FUNCTION (MamaPlugin_shutdownHook, mamaPluginShutdownHook,

+                              mamaPlugin_shutdownHook);

+

+

+    /* Optional fuctions */

+    REGISTER_OPTIONAL_PLUGIN_FUNCTION (MamaPlugin_publisherPreSendHook, mamaPluginPublisherPreSendHook,

+                                       mamaPlugin_publisherPreSendHook);

+    REGISTER_OPTIONAL_PLUGIN_FUNCTION (MamaPlugin_transportPostCreateHook, mamaPluginTransportPostCreateHook,

+                                       mamaPlugin_transportPostCreateHook);

+

+   return status;

+}

+

+mama_status

+mama_initPlugins(void)

+{

+    int             pluginCount      = 0;

+    const char*     prop             = NULL;

+    char            propString[MAX_PLUGIN_STRING];

+

+    for (pluginCount = 0; pluginCount < MAX_PLUGINS; pluginCount++)

+    {

+        snprintf(propString, MAX_PLUGIN_STRING,

+            PLUGIN_PROPERTY"%d",

+            pluginCount);

+

+        prop = properties_Get (mamaInternal_getProperties (), propString);

+        if (prop != NULL && strlen(prop)!= 0)

+        {

+            mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising [%s] %s", propString, prop);

+            mama_loadPlugin (prop);

+        }

+    }

+

+    mama_log (MAMA_LOG_LEVEL_FINE, "mama_initPlugins(): Initialising mamacenterprise");

+    mama_loadPlugin ("mamacenterprise");

+

+    return MAMA_STATUS_OK;

+}

+

+mama_status

+mama_loadPlugin (const char* pluginName)

+{

+    LIB_HANDLE              pluginLib       = NULL;

+    mamaPluginImpl*         pluginImpl      = NULL;

+    mama_status             status          = MAMA_STATUS_OK;

+    mamaPluginInfo          pluginInfo      = NULL;

+    char                    loadPluginName  [MAX_PLUGIN_STRING];

+    mamaPluginImpl*         aPluginImpl     = NULL;

+

+    if (!pluginName)

+        return MAMA_STATUS_NULL_ARG;

+

+    pluginImpl = mamaPlugin_findPlugin(pluginName);

+

+    /*

+     * Check to see if pluginImpl has already been loaded

+     */

+    if (pluginImpl == NULL)

+    {

+       /* The plugin name should be of the format mamaplugin<name> */

+        if (strncmp(pluginName, "mamacenterprise", MAX_PLUGIN_STRING) == 0)

+            snprintf(loadPluginName, MAX_PLUGIN_STRING,

+                "%s",

+                pluginName);

+        else

+            snprintf(loadPluginName, MAX_PLUGIN_STRING,

+                "%s%s",

+                PLUGIN_NAME,

+                pluginName);

+

+        pluginLib = openSharedLib (loadPluginName, NULL);

+

+        if (!pluginLib)

+        {

+

+           mama_log (MAMA_LOG_LEVEL_ERROR,

+                    "mama_loadPlugin(): "

+                    "Could not open plugin library [%s] [%s]",

+                    pluginName,

+                    getLibError());

+            return MAMA_STATUS_PLATFORM;

+        }

+

+        /* Create structure to hold plugin information */

+        aPluginImpl = (mamaPluginImpl*)calloc (1, sizeof(mamaPluginImpl));

+

+        status = mamaPlugin_registerFunctions (pluginLib,

+                                               pluginName,

+                                               pluginInfo,

+                                               aPluginImpl);

+

+        if (MAMA_STATUS_OK == status)

+        {

+            mama_log (MAMA_LOG_LEVEL_NORMAL,

+                     "mama_loadPlugin(): "

+                     "Sucessfully registered plugin functions for [%s]",

+                     pluginName);

+

+        }

+        else

+        {

+            mama_log (MAMA_LOG_LEVEL_WARN,

+                     "mama_loadPlugin(): "

+                     "Failed to register plugin functions for [%s]",

+                     pluginName);

+

+            closeSharedLib (aPluginImpl->mPluginHandle);

+

+            free ((char*)aPluginImpl->mPluginName);

+            free ((mamaPluginImpl*)aPluginImpl);

+

+            return status;

+        }

+

+        /* Invoke the init function */

+        status = aPluginImpl->mamaPluginInitHook (aPluginImpl->mPluginInfo);

+

+        if (MAMA_STATUS_OK == status)

+        {

+            mama_log (MAMA_LOG_LEVEL_NORMAL,

+                      "mama_loadPlugin(): Successfully run the init hook for mama plugin [%s]",

+                       aPluginImpl->mPluginName);

+        }

+        else

+        {

+            mama_log (MAMA_LOG_LEVEL_WARN,

+                      "mama_loadPlugin(): Init hook failed for mama plugin [%s]",

+                       aPluginImpl->mPluginName);

+

+            closeSharedLib (aPluginImpl->mPluginHandle);

+

+            free ((char*)aPluginImpl->mPluginName);

+            free ((mamaPluginImpl*)aPluginImpl);

+

+            return status;

+        }

+

+        /* Save off the plugin impl and increment the plugin counter */

+        gPlugins[gPluginNo] = aPluginImpl;

+        gPluginNo++;

+

+    }

+    else

+    {

+        mama_log (MAMA_LOG_LEVEL_NORMAL,

+                 "mama_loadPlugin(): "

+                 "Plugin [%s] has already been loaded and initialised",

+                 pluginName);

+    }

+

+    return MAMA_STATUS_OK;

+}

+

+mama_status

+mama_shutdownPlugins (void)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+    int          ret    = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin]->mPluginHandle != NULL)

+        {

+            /* Fire the user shutdown hook first - if one is present */

+            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            {

+                gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+            }

+

+            ret = closeSharedLib (gPlugins[plugin]->mPluginHandle);

+            if (0!=ret)

+            {

+                 mama_log (MAMA_LOG_LEVEL_WARN,

+                            "mama_shutdownPlugins(): Failed to close Mama Plugin [%s]",

+                            gPlugins[plugin]->mPluginName);

+            }

+            else

+            {

+                 mama_log (MAMA_LOG_LEVEL_WARN,

+                            "mama_shutdownPlugins(): Mama Plugin [%s] successfully closed",

+                            gPlugins[plugin]->mPluginName);

+            }

+

+            free ((char*)gPlugins[plugin]->mPluginName);

+            free (gPlugins[plugin]);

+            gPlugins[plugin] = NULL;

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_firePublisherPreSendHook (mamaPublisher publisher, mamaMsg message)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginPublisherPreSendHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginPublisherPreSendHook (gPlugins[plugin]->mPluginInfo, publisher, message);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_firePublisherPreSendHook(): Publisher pre send hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_fireTransportPostCreateHook (mamaTransport transport)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginTransportPostCreateHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginTransportPostCreateHook (gPlugins[plugin]->mPluginInfo, transport);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_fireTransportPostCreateHook(): Transport post create hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mama_status

+mamaPlugin_fireShutdownHook (void)

+{

+    mama_status  status = MAMA_STATUS_OK;

+    int          plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin] != NULL)

+        {

+            if (gPlugins[plugin]->mamaPluginShutdownHook != NULL)

+            {

+                status = gPlugins[plugin]->mamaPluginShutdownHook (gPlugins[plugin]->mPluginInfo);

+

+                if (MAMA_STATUS_OK != status)

+                {

+                     mama_log (MAMA_LOG_LEVEL_WARN,

+                                "mamaPlugin_fireShutdownHook(): Shutdown hook failed for mama plugin [%s]",

+                                gPlugins[plugin]->mPluginName);

+                }

+            }

+        }

+    }

+    return status;

+}

+

+mamaPluginImpl*

+mamaPlugin_findPlugin (const char* name)

+{

+    int plugin = 0;

+

+    for (plugin = 0; plugin <= gPluginNo; plugin++)

+    {

+        if (gPlugins[plugin])

+        {

+            if ((strncmp(gPlugins[plugin]->mPluginName, name, MAX_PLUGIN_STRING) == 0))

+            {

+                return gPlugins[plugin];

+            }

+        }

+    }

+    return NULL;

+}

diff --git a/mama/c_cpp/src/c/plugin.h b/mama/c_cpp/src/c/plugin.h

new file mode 100644

index 0000000..df43b27

--- /dev/null

+++ b/mama/c_cpp/src/c/plugin.h

@@ -0,0 +1,59 @@

+/* $Id$

+ *

+ * OpenMAMA: The open middleware agnostic messaging API

+ * Copyright (C) 2011 NYSE Technologies, Inc.

+ *

+ * This library is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU Lesser General Public

+ * License as published by the Free Software Foundation; either

+ * version 2.1 of the License, or (at your option) any later version.

+ *

+ * This library is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

+ * Lesser General Public License for more details.

+ *

+ * You should have received a copy of the GNU Lesser General Public

+ * License along with this library; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

+ * 02110-1301 USA

+ */

+

+#ifndef PluginH__

+#define PluginH__

+

+

+/**

+ * @brief Containers used within the mama plugin

+ */

+typedef mama_status (*mamaPlugin_publisherPreSendHook) (mamaPluginInfo pluginInfo, mamaPublisher publisher, mamaMsg message);

+typedef mama_status (*mamaPlugin_transportPostCreateHook) (mamaPluginInfo pluginInfo, mamaTransport transport);

+typedef mama_status (*mamaPlugin_shutdownHook) (mamaPluginInfo pluginInfo);

+typedef mama_status (*mamaPlugin_initHook) (mamaPluginInfo* pluginInfo);

+

+/**

+ * Initialize the internal plugin interface

+ *

+ * @return mama status code

+ */

+extern mama_status

+mama_initPlugins (void);

+

+/**

+ * Shutdown the internal plugin interface

+ *

+ * @return mama status code

+ */

+extern mama_status

+mama_shutdownPlugins (void);

+

+extern mama_status

+mamaPlugin_firePublisherPreSendHook (mamaPublisher publisher, mamaMsg message);

+

+extern mama_status

+mamaPlugin_fireTransportPostCreateHook (mamaTransport transport);

+

+extern mama_status

+mamaPlugin_fireShutdownHook (void);

+

+#endif /* PluginH__ */

diff --git a/mama/c_cpp/src/c/publisher.c b/mama/c_cpp/src/c/publisher.c

index 4612d17..6a7f92d 100644

--- a/mama/c_cpp/src/c/publisher.c

+++ b/mama/c_cpp/src/c/publisher.c

@@ -23,6 +23,7 @@

#include "mama/publisher.h"

 

 #include "bridge.h"

+#include "plugin.h"

#include "throttle.h"

#include "transportimpl.h"

 

@@ -245,6 +246,15 @@ mamaPublisher_send (mamaPublisher publisher,

     if (!impl->mMamaPublisherBridgeImpl) return MAMA_STATUS_INVALID_ARG;

     if (!impl->mBridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL;

 

+    /* Calling plugin hook */

+    status = mamaPlugin_firePublisherPreSendHook (publisher, msg);

+    if (MAMA_STATUS_OK != status)

+    {

+        mama_log (MAMA_LOG_LEVEL_ERROR,

+                  "mamaPublisher_send(): PublisherPreSendHook failed. Not sending message.");

+        return status;

+    }

+

     status = impl->mBridgeImpl->bridgeMamaPublisherSend

         (impl->mMamaPublisherBridgeImpl,

          msg);

diff --git a/mama/c_cpp/src/c/transport.c b/mama/c_cpp/src/c/transport.c

index 339dbc0..622f47d 100644

--- a/mama/c_cpp/src/c/transport.c

+++ b/mama/c_cpp/src/c/transport.c

@@ -25,6 +25,7 @@

 

 #include "mama/mama.h"

#include "throttle.h"

+#include "plugin.h"

#include "list.h"

#include "transportimpl.h"

#include "bridge.h"

@@ -876,10 +877,22 @@ mamaTransport_create (mamaTransport transport,

 

     if ((!self->mDisableRefresh) && (!mamaTransportInternal_disableRefreshes(name)))

     {

-        return refreshTransport_create (&self->mRefreshTransport,

-                                    (mamaTransport)self,

-                                    self->mListeners,

-                                    self->mBridgeImpl);

+        status = refreshTransport_create (&self->mRefreshTransport,

+                                          (mamaTransport)self,

+                                          self->mListeners,

+                                          self->mBridgeImpl);

+

+        if (MAMA_STATUS_OK != status)

+            return status;

+    }

+

+    /* Calling plugin hook*/

+    status = mamaPlugin_fireTransportPostCreateHook (transport);

+    if (MAMA_STATUS_OK != status)

+    {

+        mama_log (MAMA_LOG_LEVEL_ERROR,

+                  "mamaTransport_create(): TransportPostCreateHook failed with a status of %s",

+                   mamaStatus_stringForStatus(status));

     }

 

     return MAMA_STATUS_OK;

--

1.7.1

 

 

 

 

Gary Molloy – SR Labs

Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD

g.molloy@...

 



---
This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.

Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures and to http://www.db.com/unitedkingdom/content/privacy.htm for information about privacy.