[PATCH] AVIS: Make subject construction compatible with QPid and data dictionaries.


Lee Skillen <lskillen@...>
 

Repurposed the QPid subject construction code and utilised it within
Avis to make it compatible. It does seem like this would serve a
better purpose as common code between all middleware that want to use
it, especially with the workaround for data dictionary topics being
rooted at _MDDD.SOURCE.DATA_DICT instead of _MDDD.SOURCE.

Signed-off-by: Lee Skillen <lskillen@vulcanft.com>
---
mama/c_cpp/src/c/bridge/avis/publisher.c | 37 ++++++++--------
mama/c_cpp/src/c/bridge/avis/sub.c | 75 ++++++++++++++++++++++----------
2 files changed, 71 insertions(+), 41 deletions(-)

diff --git a/mama/c_cpp/src/c/bridge/avis/publisher.c b/mama/c_cpp/src/c/bridge/avis/publisher.c
index e1d3e40..2e25524 100644
--- a/mama/c_cpp/src/c/bridge/avis/publisher.c
+++ b/mama/c_cpp/src/c/bridge/avis/publisher.c
@@ -33,6 +33,7 @@
#include "transportbridge.h"
#include "msgimpl.h"
#include "avisdefs.h"
+#include "sub.h"

typedef struct avisPublisherBridge
{
@@ -284,29 +285,27 @@ avisBridgeMamaPublisher_create (publisherBridge* result,
static mama_status
avisBridgeMamaPublisherImpl_buildSendSubject (avisPublisherBridge* impl)
{
- char lSubject[256];
-
- if (!impl) return MAMA_STATUS_NULL_ARG;
-
- if (impl->mRoot != NULL && impl->mSource != NULL )
- {
- snprintf (lSubject, sizeof(lSubject),"%s.%s",
- impl->mRoot, impl->mSource);
- }
- else if (impl->mSource != NULL && impl->mTopic != NULL)
+ mama_status status = MAMA_STATUS_OK;
+ char* keyTarget = NULL;
+ const char* root = impl->mRoot;
+ const char* source = impl->mSource;
+ const char* topic = impl->mTopic;
+
+ /* If this is a special _MD publisher, lose the topic unless dictionary */
+ if (root != NULL && 0 != strcmp (root, "_MDDD"))
{
- snprintf (lSubject, sizeof(lSubject), "%s.%s",
- impl->mSource, impl->mTopic);
- }
- else if (impl->mTopic != NULL)
- {
- snprintf (lSubject, sizeof(lSubject), "%s",
- impl->mTopic);
+ topic = NULL;
}

- impl->mSubject = strdup(lSubject);
+ status = avisBridgeMamaSubscriptionImpl_generateSubjectKey (root,
+ source,
+ topic,
+ &keyTarget);

- return MAMA_STATUS_OK;
+ /* Set the subject for publishing here */
+ impl->mSubject = keyTarget;
+
+ return status;
}

/*Send a message.*/
diff --git a/mama/c_cpp/src/c/bridge/avis/sub.c b/mama/c_cpp/src/c/bridge/avis/sub.c
index ec25185..4a3a60d 100644
--- a/mama/c_cpp/src/c/bridge/avis/sub.c
+++ b/mama/c_cpp/src/c/bridge/avis/sub.c
@@ -32,6 +32,7 @@
#include "transportbridge.h"
#include "avisdefs.h"
#include "subinitial.h"
+#include "sub.h"

typedef struct avisSubscription
{
@@ -45,7 +46,7 @@ typedef struct avisSubscription

const char* mSource;
const char* mSymbol;
- char mSubject[256];
+ char* mSubject;
void* mClosure;

int mIsNotMuted;
@@ -329,27 +330,11 @@ avisBridgeMamaSubscription_create (subscriptionBridge* subscriber,
if (!avisTransport)
return MAMA_STATUS_INVALID_ARG;

- if (source != NULL && source[0])
- {
- impl->mSource = source;
- }
- else
- {
- impl->mSource = "";
- }
-
- if (symbol != NULL && symbol[0])
- {
- impl->mSymbol = symbol;
- snprintf (impl->mSubject, sizeof(impl->mSubject), "%s.%s",
- impl->mSource, impl->mSymbol);
- }
- else
- {
- impl->mSymbol = "";
- snprintf (impl->mSubject, sizeof(impl->mSubject), "%s",
- impl->mSource );
- }
+ /* Use a standard centralized method to determine a topic key */
+ avisBridgeMamaSubscriptionImpl_generateSubjectKey (NULL,
+ source,
+ symbol,
+ &impl->mSubject);

impl->mMamaCallback = callback;
impl->mMamaSubscription = subscription;
@@ -434,6 +419,7 @@ avisBridgeMamaSubscription_destroy (subscriptionBridge subscriber)

wsem_destroy(&avisSub(subscriber)->mCreateDestroySem);

+ free(avisSub(subscriber)->mSubject);
free(avisSub(subscriber));

return status;
@@ -490,3 +476,48 @@ avisBridgeMamaSubscription_isTportDisconnected (subscriptionBridge subscriber)
CHECK_SUBSCRIBER(subscriber);
return elvin_is_open(avisSub(subscriber)->mAvis) ? 0 : 1;
}
+
+#define COPY_TOKEN_AND_SLIDE(dst, src, remaining, first)\
+do {\
+ if (src) {\
+ size_t written = snprintf (dst, remaining, (first?"%s":".%s"), src);\
+ dst += written;\
+ remaining -= written;\
+ }\
+} while(0);
+
+/*
+ * Internal function to ensure that the topic names are always calculated
+ * in a particular way
+ */
+mama_status
+avisBridgeMamaSubscriptionImpl_generateSubjectKey (const char* root,
+ const char* source,
+ const char* topic,
+ char** keyTarget)
+{
+ char subject_[MAX_SUBJECT_LENGTH];
+ char* subject = subject_;
+ size_t remaining = MAX_SUBJECT_LENGTH;
+
+ COPY_TOKEN_AND_SLIDE(subject, root, remaining, (subject_==subject));
+ COPY_TOKEN_AND_SLIDE(subject, source, remaining, (subject_==subject));
+ COPY_TOKEN_AND_SLIDE(subject, topic, remaining, (subject_==subject));
+
+ mama_log (MAMA_LOG_LEVEL_FINEST,
+ "avisBridgeMamaSubscriptionImpl_generateSubjectKey(): %s", subject_);
+
+ /*
+ * Allocate the memory for copying the string. Caller is responsible for
+ * destroying.
+ */
+ *keyTarget = strdup (subject_);
+ if (NULL == *keyTarget)
+ {
+ return MAMA_STATUS_NOMEM;
+ }
+ else
+ {
+ return MAMA_STATUS_OK;
+ }
+}
--
1.9.0


Damian Maguire <DMaguire@...>
 

Hey Lee,

Added this to Bugzilla for tracking, ticket number:
http://bugs.openmama.org/show_bug.cgi?id=81

Cheers,

D



On 3/3/14 5:49 PM, "Lee Skillen" <lskillen@vulcanft.com> wrote:

Repurposed the QPid subject construction code and utilised it within
Avis to make it compatible. It does seem like this would serve a
better purpose as common code between all middleware that want to use
it, especially with the workaround for data dictionary topics being
rooted at _MDDD.SOURCE.DATA_DICT instead of _MDDD.SOURCE.

Signed-off-by: Lee Skillen <lskillen@vulcanft.com>
---
mama/c_cpp/src/c/bridge/avis/publisher.c | 37 ++++++++--------
mama/c_cpp/src/c/bridge/avis/sub.c | 75
++++++++++++++++++++++----------
2 files changed, 71 insertions(+), 41 deletions(-)

diff --git a/mama/c_cpp/src/c/bridge/avis/publisher.c
b/mama/c_cpp/src/c/bridge/avis/publisher.c
index e1d3e40..2e25524 100644
--- a/mama/c_cpp/src/c/bridge/avis/publisher.c
+++ b/mama/c_cpp/src/c/bridge/avis/publisher.c
@@ -33,6 +33,7 @@
#include "transportbridge.h"
#include "msgimpl.h"
#include "avisdefs.h"
+#include "sub.h"

typedef struct avisPublisherBridge
{
@@ -284,29 +285,27 @@ avisBridgeMamaPublisher_create (publisherBridge*
result,
static mama_status
avisBridgeMamaPublisherImpl_buildSendSubject (avisPublisherBridge* impl)
{
- char lSubject[256];
-
- if (!impl) return MAMA_STATUS_NULL_ARG;
-
- if (impl->mRoot != NULL && impl->mSource != NULL )
- {
- snprintf (lSubject, sizeof(lSubject),"%s.%s",
- impl->mRoot, impl->mSource);
- }
- else if (impl->mSource != NULL && impl->mTopic != NULL)
+ mama_status status = MAMA_STATUS_OK;
+ char* keyTarget = NULL;
+ const char* root = impl->mRoot;
+ const char* source = impl->mSource;
+ const char* topic = impl->mTopic;
+
+ /* If this is a special _MD publisher, lose the topic unless
dictionary */
+ if (root != NULL && 0 != strcmp (root, "_MDDD"))
{
- snprintf (lSubject, sizeof(lSubject), "%s.%s",
- impl->mSource, impl->mTopic);
- }
- else if (impl->mTopic != NULL)
- {
- snprintf (lSubject, sizeof(lSubject), "%s",
- impl->mTopic);
+ topic = NULL;
}

- impl->mSubject = strdup(lSubject);
+ status = avisBridgeMamaSubscriptionImpl_generateSubjectKey (root,
+ source,
+ topic,
+
&keyTarget);

- return MAMA_STATUS_OK;
+ /* Set the subject for publishing here */
+ impl->mSubject = keyTarget;
+
+ return status;
}

/*Send a message.*/
diff --git a/mama/c_cpp/src/c/bridge/avis/sub.c
b/mama/c_cpp/src/c/bridge/avis/sub.c
index ec25185..4a3a60d 100644
--- a/mama/c_cpp/src/c/bridge/avis/sub.c
+++ b/mama/c_cpp/src/c/bridge/avis/sub.c
@@ -32,6 +32,7 @@
#include "transportbridge.h"
#include "avisdefs.h"
#include "subinitial.h"
+#include "sub.h"

typedef struct avisSubscription
{
@@ -45,7 +46,7 @@ typedef struct avisSubscription

const char* mSource;
const char* mSymbol;
- char mSubject[256];
+ char* mSubject;
void* mClosure;

int mIsNotMuted;
@@ -329,27 +330,11 @@ avisBridgeMamaSubscription_create
(subscriptionBridge* subscriber,
if (!avisTransport)
return MAMA_STATUS_INVALID_ARG;

- if (source != NULL && source[0])
- {
- impl->mSource = source;
- }
- else
- {
- impl->mSource = "";
- }
-
- if (symbol != NULL && symbol[0])
- {
- impl->mSymbol = symbol;
- snprintf (impl->mSubject, sizeof(impl->mSubject), "%s.%s",
- impl->mSource, impl->mSymbol);
- }
- else
- {
- impl->mSymbol = "";
- snprintf (impl->mSubject, sizeof(impl->mSubject), "%s",
- impl->mSource );
- }
+ /* Use a standard centralized method to determine a topic key */
+ avisBridgeMamaSubscriptionImpl_generateSubjectKey (NULL,
+ source,
+ symbol,
+ &impl->mSubject);

impl->mMamaCallback = callback;
impl->mMamaSubscription = subscription;
@@ -434,6 +419,7 @@ avisBridgeMamaSubscription_destroy
(subscriptionBridge subscriber)

wsem_destroy(&avisSub(subscriber)->mCreateDestroySem);

+ free(avisSub(subscriber)->mSubject);
free(avisSub(subscriber));

return status;
@@ -490,3 +476,48 @@ avisBridgeMamaSubscription_isTportDisconnected
(subscriptionBridge subscriber)
CHECK_SUBSCRIBER(subscriber);
return elvin_is_open(avisSub(subscriber)->mAvis) ? 0 : 1;
}
+
+#define COPY_TOKEN_AND_SLIDE(dst, src, remaining, first)\
+do {\
+ if (src) {\
+ size_t written = snprintf (dst, remaining, (first?"%s":".%s"),
src);\
+ dst += written;\
+ remaining -= written;\
+ }\
+} while(0);
+
+/*
+ * Internal function to ensure that the topic names are always calculated
+ * in a particular way
+ */
+mama_status
+avisBridgeMamaSubscriptionImpl_generateSubjectKey (const char* root,
+ const char* source,
+ const char* topic,
+ char** keyTarget)
+{
+ char subject_[MAX_SUBJECT_LENGTH];
+ char* subject = subject_;
+ size_t remaining = MAX_SUBJECT_LENGTH;
+
+ COPY_TOKEN_AND_SLIDE(subject, root, remaining,
(subject_==subject));
+ COPY_TOKEN_AND_SLIDE(subject, source, remaining,
(subject_==subject));
+ COPY_TOKEN_AND_SLIDE(subject, topic, remaining,
(subject_==subject));
+
+ mama_log (MAMA_LOG_LEVEL_FINEST,
+ "avisBridgeMamaSubscriptionImpl_generateSubjectKey(): %s",
subject_);
+
+ /*
+ * Allocate the memory for copying the string. Caller is responsible
for
+ * destroying.
+ */
+ *keyTarget = strdup (subject_);
+ if (NULL == *keyTarget)
+ {
+ return MAMA_STATUS_NOMEM;
+ }
+ else
+ {
+ return MAMA_STATUS_OK;
+ }
+}
--
1.9.0
________________________________________________________

This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange Group, Inc. (ICE), NYSE Euronext or any of their subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.
________________________________________________________


Damian Maguire <DMaguire@...>
 

Hey Lee, 

Cheers for that one, looked good to me. Merged the changes and pushed to next. Commit ID: b8a7bcce60a20531b18591cc4e8638a626052a3e

Cheers, 

D

Damian Maguire – Senior R&D and OpenMAMA Specialist
IntercontinentalExchange | NYSE Technologies
24-26 Adelaide Exchange | Belfast, BT2 8GD
Tel: +44 2890 822 282 (ext: 452161) | Mob: +44 7540 204 077

From: Lee Skillen <lskillen@...>
Date: Monday, March 3, 2014 5:49 PM
To: "openmama-dev@..." <openmama-dev@...>
Subject: [Openmama-dev] [PATCH] AVIS: Make subject construction compatible with QPid and data dictionaries.
Repurposed the QPid subject construction code and utilised it within
Avis to make it compatible.  It does seem like this would serve a
better purpose as common code between all middleware that want to use
it, especially with the workaround for data dictionary topics being
rooted at _MDDD.SOURCE.DATA_DICT instead of _MDDD.SOURCE.

Signed-off-by: Lee Skillen <lskillen@...>
---
 mama/c_cpp/src/c/bridge/avis/publisher.c | 37 ++++++++--------
 mama/c_cpp/src/c/bridge/avis/sub.c   

This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange Group, Inc. (ICE), NYSE Euronext or any of their subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.