[PATCH 2/3] [MAMAC] Add ability to turn on/off entitlements on a per bridge basis
Testing Strategy:-
Not middleware or O/S specific.
This will require an entitled build and an entitlement server.
There are 4 tests that you can run using a standard mamalistenc.
For each test you will have to add/modify the following within your middleware bridge code (when you create your bridge):
1) mamaBridgeImpl_setReadOnlyProperty ((mamaBridge)impl, "mama.<middleware>.entitlements.deferred", "true", 1);
- Deferred true, will run will addition entitlement logging.
2) mamaBridgeImpl_setReadOnlyProperty ((mamaBridge)impl, "mama.<middleware>.entitlements.deferred", "false", 1); <------default now in <middleware> bridge (This will be the standard setting)
- Deferred false, will connect to the normal entitlement server.
3) mamaBridgeImpl_setReadOnlyProperty ((mamaBridge)impl, "mama.TEST.entitlements.deferred", "true", 1); <---- Invalid property string (will not matter if deferred or not, will log error at very top & fail to connect to entitlements)
- This will fail whether set to deferred or not, logging seen at top is will look like this:-
mamaBridgeImpl_setProperty(): Unknown property string [mama.TEST.entitlements.deferred] entered.
4) mamaBridgeImpl_setReadOnlyProperty ((mamaBridge)impl, "mama.<middleware>.entitlements.deferred", "true", 1);
mamaBridgeImpl_setReadOnlyProperty ((mamaBridge)impl, "mama.<middleware>.entitlements.deferred", "false", 1); <-----property called twice (true/false, or false/true).
With false/true -
Should follow the standard logic of it not being deferred - logging at top will read
“mamaBridgeImpl_setProperty(): Bridge property is read only, property can not be set. “
But this should connect to the normal entitlement server.
With true/false -
Should follow the standard logic if deferred is true - logging at top will look like this:
“mamaBridgeImpl_setProperty(): Bridge property is read only, property can not be set. “
But will continue.
Further documentation on the this feature will be available shortly which will provide more details on the feature which will include the various logging you can expect etc...
=========================================================================================================
From d016afce1b1cc4ffb6d65c1d032ddea41d56b62e Mon Sep 17 00:00:00 2001
From: Gary Molloy <g.molloy@...>
Date: Tue, 21 Apr 2015 09:56:52 -0400
Subject: [PATCH 2/3] [MAMAC] Add ability to turn on/off entitlements on a per bridge basis
Signed-off-by: Gary Molloy <g.molloy@...>
---
mama/c_cpp/src/c/bridge.c | 67 ++++++++++++++++++++++++++++++++
mama/c_cpp/src/c/bridge.h | 20 +++++++++
mama/c_cpp/src/c/bridge/qpid/bridge.c | 2 +
mama/c_cpp/src/c/listenermsgcallback.c | 15 ++++++-
mama/c_cpp/src/c/mama.c | 26 ++++++++++++
mama/c_cpp/src/c/subscription.c | 38 ++++++++++++++----
6 files changed, 157 insertions(+), 11 deletions(-)
diff --git a/mama/c_cpp/src/c/bridge.c b/mama/c_cpp/src/c/bridge.c
index 01cbcc5..dd42a55 100644
--- a/mama/c_cpp/src/c/bridge.c
+++ b/mama/c_cpp/src/c/bridge.c
@@ -20,8 +20,12 @@
*/
#include <mama/mama.h>
+#include <wombat/strutils.h>
#include "bridge.h"
+#define MAX_PROP_STRING 1000
+#define PROP_NAME_ENTITLEMENTS_DEFERRED "entitlements.deferred"
+
int mamaBridgeImpl_getDefaultQueueTimeout(void)
{
/* Returns. */
@@ -143,3 +147,66 @@ mamaBridgeImpl_stopInternalEventQueue (mamaBridge bridgeImpl)
return MAMA_STATUS_OK;
}
+
+mama_status
+mamaBridgeImpl_setReadOnlyProperty (mamaBridge bridgeImpl, const char* property, const char* value, mama_bool_t readOnly)
+{
+ mamaBridgeImpl_setProperty(bridgeImpl, property, value);
+ bridgeImpl->mEntitleReadOnly = 1;
+ return MAMA_STATUS_OK;
+}
+
+mama_status
+mamaBridgeImpl_setProperty (mamaBridge bridgeImpl, const char* property, const char* value)
+{
+ char propString[MAX_PROP_STRING];
+ int retVal;
+
+ mamaBridgeImpl* impl = (mamaBridgeImpl*)bridgeImpl;
+
+ /* Check for mama.middleware.entitlements_deferred first */
+ retVal = snprintf(propString, MAX_PROP_STRING,
+ "mama.%s.%s",
+ impl->bridgeGetName(),
+ PROP_NAME_ENTITLEMENTS_DEFERRED);
+
+ if(0 == strcmp(property, propString))
+ {
+ if (1 == bridgeImpl->mEntitleReadOnly)
+ {
+ mama_log (MAMA_LOG_LEVEL_WARN, "mamaBridgeImpl_setProperty(): "
+ "Bridge is read only, property can not be set.");
+ return MAMA_STATUS_INVALID_ARG;
+ }
+ else
+ {
+ if (strtobool(value))
+ bridgeImpl->mEntitleDeferred = 1;
+ else
+ bridgeImpl->mEntitleDeferred = 0;
+ }
+ }
+ else
+ {
+ mama_log (MAMA_LOG_LEVEL_WARN, "mamaBridgeImpl_setProperty(): "
+ "Unknown property string [%s] entered.", property);
+ return MAMA_STATUS_INVALID_ARG;
+ }
+ return MAMA_STATUS_OK;
+}
+
+const char*
+mamaBridgeImpl_getProperty (mamaBridge bridgeImpl, const char* property)
+{
+ return NULL;
+}
+
+mama_bool_t
+mamaBridgeImpl_areEntitlementsDeferred (mamaBridge bridgeImpl)
+{
+ if (bridgeImpl)
+ {
+ return bridgeImpl->mEntitleDeferred;
+ }
+ return 0;
+}
diff --git a/mama/c_cpp/src/c/bridge.h b/mama/c_cpp/src/c/bridge.h
index c079819..9bcd204 100644
--- a/mama/c_cpp/src/c/bridge.h
+++ b/mama/c_cpp/src/c/bridge.h
@@ -715,6 +715,10 @@ typedef struct mamaBridgeImpl_
used when getting the default queue */
void* mCppCallback;
+ /*Used in bridge.c*/
+ mama_bool_t mEntitleDeferred;
+ mama_bool_t mEntitleReadOnly;
+
/*Used in mama.c*/
bridge_open bridgeOpen;
bridge_close bridgeClose;
@@ -873,6 +877,22 @@ MAMAExpDLL
mama_status
mamaBridgeImpl_stopInternalEventQueue (mamaBridge bridgeImpl);
+MAMAExpDLL
+extern mama_status
+mamaBridgeImpl_setReadOnlyProperty (mamaBridge bridgeImpl, const char* property, const char* value, mama_bool_t readOnly);
+
+MAMAExpDLL
+extern mama_status
+mamaBridgeImpl_setProperty (mamaBridge bridgeImpl, const char* property, const char* value);
+
+MAMAExpDLL
+extern const char*
+mamaBridgeImpl_getProperty (mamaBridge bridgeImpl, const char* property);
+
+MAMAExpDLL
+extern mama_bool_t
+mamaBridgeImpl_areEntitlementsDeferred (mamaBridge bridgeImpl);
+
#if defined(__cplusplus)
}
#endif
diff --git a/mama/c_cpp/src/c/bridge/qpid/bridge.c b/mama/c_cpp/src/c/bridge/qpid/bridge.c
index 4ab74c7..233c8ec 100644
--- a/mama/c_cpp/src/c/bridge/qpid/bridge.c
+++ b/mama/c_cpp/src/c/bridge/qpid/bridge.c
@@ -85,6 +85,8 @@ void qpidBridge_createImpl (mamaBridge* result)
/* Return the newly created bridge */
*result = (mamaBridge) bridge;
+
+ mamaBridgeImpl_setReadOnlyProperty ((mamaBridge)bridge, "mama.qpid.entitlements.deferred", "false", 1);
}
mama_status
diff --git a/mama/c_cpp/src/c/listenermsgcallback.c b/mama/c_cpp/src/c/listenermsgcallback.c
index 85c3bf2..caeaa56 100644
--- a/mama/c_cpp/src/c/listenermsgcallback.c
+++ b/mama/c_cpp/src/c/listenermsgcallback.c
@@ -86,7 +86,8 @@ listenerMsgCallback_create( listenerMsgCallback *result,
msgCallback* callback = (msgCallback*)calloc( 1, sizeof( msgCallback ) );
#ifdef WITH_ENTITLEMENTS /* No listener creation without a client. */
- if( gEntitlementClient == 0 )
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(subscription);
+ if( gEntitlementClient == 0 && !(mamaBridgeImpl_areEntitlementsDeferred(bridge)))
{
return MAMA_ENTITLE_NO_SERVERS_SPECIFIED;
}
@@ -625,7 +626,6 @@ static void handleNoSubscribers (msgCallback *callback,
static int
checkEntitlement( msgCallback *callback, mamaMsg msg, SubjectContext* ctx )
{
-
#ifdef WITH_ENTITLEMENTS
int result = 0;
int32_t value;
@@ -634,6 +634,17 @@ checkEntitlement( msgCallback *callback, mamaMsg msg, SubjectContext* ctx )
return 1;
}
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(self->mSubscription);
+
+ if (bridge && (mamaBridgeImpl_areEntitlementsDeferred(bridge)))
+ {
+ mama_log (MAMA_LOG_LEVEL_FINER,
+ "Deferred checking injected entitlement to %s bridge [%p]",
+ bridge->bridgeGetName(), bridge);
+ ctx->mEntitlementAlreadyVerified = 1;
+ return 1;
+ }
+
if( MAMA_STATUS_OK == mamaMsg_getEntitleCode( msg,
&value ) )
{
diff --git a/mama/c_cpp/src/c/mama.c b/mama/c_cpp/src/c/mama.c
index 5e31856..1815bc0 100644
--- a/mama/c_cpp/src/c/mama.c
+++ b/mama/c_cpp/src/c/mama.c
@@ -1707,6 +1707,8 @@ enableEntitlements (const char **servers)
const char* altUserId;
const char* altIp;
const char* site;
+ mamaMiddleware middleware = 0;
+ int entitlementsRequired = 0; /*boolean*/
if (gEntitlementClient != 0)
@@ -1715,6 +1717,30 @@ enableEntitlements (const char **servers)
gEntitlementClient = 0;
}
+ for (middleware=0; middleware != MAMA_MIDDLEWARE_MAX; ++middleware)
+ {
+ mamaBridgeImpl* impl = (mamaBridgeImpl*) gImpl.myBridges [middleware];
+ if (impl)
+ {
+ /* Check if entitlements are deferred to bridge */
+ if (mamaBridgeImpl_areEntitlementsDeferred(impl) == 1)
+ {
+ mama_log (MAMA_LOG_LEVEL_WARN,
+ "Entitlements deferred on %s bridge.",
+ mamaMiddleware_convertToString (middleware));
+ }
+ else
+ {
+ /* Entitlements are not deferred, continue with entitlement checking */
+ entitlementsRequired = 1;
+ }
+ }
+ }
+
+ /* Entitlements are deferred, do not continue with entitlement checking */
+ if (entitlementsRequired==0)
+ return MAMA_STATUS_OK;
+
if (servers == NULL)
{
if (NULL == (servers = mdrvImpl_ParseServersProperty()))
diff --git a/mama/c_cpp/src/c/subscription.c b/mama/c_cpp/src/c/subscription.c
index 1f78746..42ad347 100644
--- a/mama/c_cpp/src/c/subscription.c
+++ b/mama/c_cpp/src/c/subscription.c
@@ -450,11 +450,19 @@ mamaSubscription_setupBasic (
"Could not get bridge impl from transport.");
return MAMA_STATUS_NO_BRIDGE_IMPL;
}
-
+
#ifdef WITH_ENTITLEMENTS
- self->mSubjectContext.mOeaSubscription = oeaClient_newSubscription (&entitlementStatus, gEntitlementClient);
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(subscription);
+ if (gEntitlementClient == 0 || mamaBridgeImpl_areEntitlementsDeferred(bridge))
+ {
+ mama_log (MAMA_LOG_LEVEL_FINER,
+ "Entitlements checking at subscription creation deferred to %s bridge [%p]",
+ bridge->bridgeGetName(), bridge);
+ }
+ else
+ self->mSubjectContext.mOeaSubscription = oeaClient_newSubscription (&entitlementStatus, gEntitlementClient);
#endif
-
+
/*Up from entitlement check based on string compare on symbol*/
if (!isEntitledToSymbol (source, symbol, self))
{
@@ -476,7 +484,9 @@ mamaSubscription_setupBasic (
if (!self->mRequiresInitial) return MAMA_STATUS_INVALID_ARG;
subscMsgType = MAMA_SUBSC_SNAPSHOT;
#ifdef WITH_ENTITLEMENTS
- oeaSubscription_setIsSnapshot (self->mSubjectContext.mOeaSubscription, 1);
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(subscription);
+ if (!(gEntitlementClient == 0 || mamaBridgeImpl_areEntitlementsDeferred(bridge)))
+ oeaSubscription_setIsSnapshot (self->mSubjectContext.mOeaSubscription, 1);
#endif
break;
case MAMA_SERVICE_LEVEL_CONFLATED:/*fall through*/
@@ -1184,7 +1194,9 @@ mamaSubscription_getSubjectContext (mamaSubscription subscription,
msgUtils_getIssueSymbol (msg, &issueSymbol);
context->mSymbol = copyString (issueSymbol);
#ifdef WITH_ENTITLEMENTS
- context->mOeaSubscription = oeaClient_newSubscription (&entitlementStatus, gEntitlementClient);
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(subscription);
+ if (!(gEntitlementClient == 0 || mamaBridgeImpl_areEntitlementsDeferred(bridge)))
+ context->mOeaSubscription = oeaClient_newSubscription (&entitlementStatus, gEntitlementClient);
#endif
wtable_insert (self->mSubjects, (char*)sendSubject, (void*)context);
@@ -2048,7 +2060,9 @@ mamaSubscription_processTportMsg( mamaSubscription subscription,
}
#ifdef WITH_ENTITLEMENTS
- mamaMsg_getEntitleCode (msg, &entitleCode);
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(subscription);
+ if (!(gEntitlementClient == 0 || mamaBridgeImpl_areEntitlementsDeferred(bridge)))
+ mamaMsg_getEntitleCode (msg, &entitleCode);
#endif
if (entitleCode == 0)
{
@@ -2100,7 +2114,9 @@ mamaSubscription_processWildCardMsg( mamaSubscription subscription,
}
#ifdef WITH_ENTITLEMENTS
- mamaMsg_getEntitleCode (msg, &entitleCode);
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(subscription);
+ if (!(gEntitlementClient == 0 || mamaBridgeImpl_areEntitlementsDeferred(bridge)))
+ mamaMsg_getEntitleCode (msg, &entitleCode);
#endif
if (entitleCode == 0)
{
@@ -2173,7 +2189,9 @@ mamaSubscription_processMsg (mamaSubscription subscription, mamaMsg msg)
{
int32_t entitleCode = 0;
#ifdef WITH_ENTITLEMENTS
- mamaMsg_getEntitleCode (msg, &entitleCode);
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(subscription);
+ if (!(gEntitlementClient == 0 || mamaBridgeImpl_areEntitlementsDeferred(bridge)))
+ mamaMsg_getEntitleCode (msg, &entitleCode);
#endif
if (entitleCode == 0)
{
@@ -2412,7 +2430,9 @@ isEntitledToSymbol (const char *source, const char*symbol, mamaSubscription subs
snprintf (subject, WOMBAT_SUBJECT_MAX, "%s.%s", source, symbol);
- if (gEntitlementClient == 0) /* Not enforcing entitlements. */
+ mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl(subscription);
+
+ if (gEntitlementClient == 0 || mamaBridgeImpl_areEntitlementsDeferred(bridge)) /* Not enforcing entitlements. */
{
return 1;
}
--
1.7.1
Gary Molloy – SR Labs
Adelaide Exchange | 24-26 Adelaide Street | Belfast | BT2 8GD