diff --git a/README b/README index 96d84f052..797c0899b 100644 --- a/README +++ b/README @@ -1,7 +1,8 @@ OpenMAMA Client Library ============================ -Change Log: http://git.openmama.org/?p=OpenMAMA.git;a=shortlog;h=refs/tags/OpenMAMA-2.3.2-release +Release: 2.3.3 +Change Log: http://git.openmama.org/?p=OpenMAMA.git;a=shortlog;h=refs/heads/OpenMAMA-2.3.3-release Project Page ------------ diff --git a/common/c_cpp/src/c/linux/wInterlocked.h b/common/c_cpp/src/c/linux/wInterlocked.h index 6ee00db02..720e54dc5 100644 --- a/common/c_cpp/src/c/linux/wInterlocked.h +++ b/common/c_cpp/src/c/linux/wInterlocked.h @@ -131,12 +131,11 @@ WCOMMONINLINE int wInterlocked_read(wInterlockedInt *value) * * @param[in] newValue The new value to set. * @param[in] value Pointer to the value to be set. - * @return The updated integer. + * @return The original integer in value. */ WCOMMONINLINE int wInterlocked_set(int newValue, wInterlockedInt *value) { - axchg32(value, (uint32_t)newValue); - return (int)*value; + return axchg32(value, (uint32_t)newValue); } #endif /* _WOMBAT_WINTERLOCKED_H */ diff --git a/common/c_cpp/src/c/properties.l b/common/c_cpp/src/c/properties.l index d5594befa..8d0df9ff3 100644 --- a/common/c_cpp/src/c/properties.l +++ b/common/c_cpp/src/c/properties.l @@ -160,6 +160,18 @@ WS [ \t] /* value string */ if ( curKey && curValue ) { + replaceValue = + propertiesImpl_ReplaceEnvironmentVariable(curValue); + if(replaceValue != NULL) + { + /* Delete the original value */ + free(curValue); + + /* Copy the replace value into the + * current value pointer. */ + curValue = replaceValue; + } + propertiesImpl_AddProperty( properties, curKey, curValue ); if( gPropertyDebug ) diff --git a/common/c_cpp/src/c/queue.c b/common/c_cpp/src/c/queue.c index d955b2b3e..c2ef48f2f 100644 --- a/common/c_cpp/src/c/queue.c +++ b/common/c_cpp/src/c/queue.c @@ -164,14 +164,27 @@ wombatQueue_destroy (wombatQueue queue) result = WOMBAT_QUEUE_SEM_ERR; } - wInterlocked_destroy (&impl->mUnblocking); - wthread_mutex_destroy( &impl->mLock); + + if (WOMBAT_QUEUE_OK == result) + { + return wombatQueue_deallocate(queue); + } + else + { + return result; + } +} + +wombatQueueStatus +wombatQueue_deallocate (wombatQueue queue) +{ + wombatQueueImpl *impl = (wombatQueueImpl*)queue; + wInterlocked_destroy (&impl->mUnblocking); free (impl); return WOMBAT_QUEUE_OK; } - wombatQueueStatus wombatQueue_setMaxSize (wombatQueue queue, unsigned int value) { diff --git a/common/c_cpp/src/c/windows/wombat/wInterlocked.h b/common/c_cpp/src/c/windows/wombat/wInterlocked.h index f5da11ac6..f93e0885b 100644 --- a/common/c_cpp/src/c/windows/wombat/wInterlocked.h +++ b/common/c_cpp/src/c/windows/wombat/wInterlocked.h @@ -87,7 +87,7 @@ WCOMMONINLINE int wInterlocked_read(wInterlockedInt *value) * * @param[in] newValue The new value to set. * @param[in] value Pointer to the value to be set. - * @return The updated integer. + * @return The original integer in value. */ WCOMMONINLINE int wInterlocked_set(int newValue, wInterlockedInt *value) { diff --git a/common/c_cpp/src/c/wombat/queue.h b/common/c_cpp/src/c/wombat/queue.h index 79b75e97e..caafddb0f 100644 --- a/common/c_cpp/src/c/wombat/queue.h +++ b/common/c_cpp/src/c/wombat/queue.h @@ -73,11 +73,24 @@ wombatQueue_create (wombatQueue queue, uint32_t maxSize, uint32_t initialSize, uint32_t growBySize); /** - * Destroy the Queue. + * Destroy the Queue, and free any memory associated + * with the Queue. + * + * wombatQueue_create() must have been successfully called + * before calling this method. */ COMMONExpDLL wombatQueueStatus wombatQueue_destroy (wombatQueue queue); +/** + * Free any memory associated with the Queue. + * + * Unless wombatQueue_create() failed, prefer calling + * wombatQueue_destroy(). + */ +COMMONExpDLL wombatQueueStatus +wombatQueue_deallocate(wombatQueue queue); + /** * Set the maximum size of the queue. WOMBAT_QUEUE_MAX_SIZE is the maximum * queue size permitted and the default value. This value should be a multiple diff --git a/mama/VERSION.scons b/mama/VERSION.scons index ecc5afa36..b150afcb3 100644 --- a/mama/VERSION.scons +++ b/mama/VERSION.scons @@ -1 +1 @@ -mama 2.3.2 +mama 2.3.3 diff --git a/mama/c_cpp/SConscript.win b/mama/c_cpp/SConscript.win index 77e3157ff..ece07102a 100644 --- a/mama/c_cpp/SConscript.win +++ b/mama/c_cpp/SConscript.win @@ -121,14 +121,13 @@ if env['with_testtools'] == True and 'dynamic' in env['build']: if ( not Media.has_key('mama/c_cpp/docs') and env['build'] == 'dynamic' and not env.GetOption('clean') + and env['product'] == 'mama' and env['with_docs'] == True ): cdoc = env.Doxygen('doxyconfig-c.in') cppdoc = env.Doxygen('doxyconfig-cpp.in') - env.Command( '$prefix/doc/mama/images', cdoc, 'mkdir $TARGET && cp -rf %s\mama\c_cpp\doc\images\* $TARGET' % ( env['TOPLEVEL'] ) ) - env.Command( '$prefix/doc/mama/c/html', cdoc, 'mkdir $TARGET && cp -rf %s\mama\c_cpp\doc\c\html\* $TARGET' % ( env['TOPLEVEL'] ) ) - env.Command( '$prefix/doc/mama/cpp/html', cppdoc, 'mkdir $TARGET && cp -rf %s\mama\c_cpp\doc\cpp\html\* $TARGET' % ( env['TOPLEVEL'] ) ) + env.Command( '$prefix/doc/mama', '', 'mkdir $TARGET && xcopy /q /s /e /y %s\mama\c_cpp\doc\* $TARGET' % ( env['TOPLEVEL'] ) ) env.Clean( cdoc, '%s/mama/c_cpp/doc/c' % (env['TOPLEVEL']) ) env.Clean( cppdoc, '%s/mama/c_cpp/doc/cpp' % (env['TOPLEVEL']) ) diff --git a/mama/c_cpp/configure.ac b/mama/c_cpp/configure.ac index 1741472dc..3cc558b34 100644 --- a/mama/c_cpp/configure.ac +++ b/mama/c_cpp/configure.ac @@ -25,8 +25,8 @@ # ################################################## m4_define([product_version_major], [2]) -m4_define([product_version_minor], [2]) -m4_define([product_version_release], [1.1]) +m4_define([product_version_minor], [3]) +m4_define([product_version_release], [3]) m4_define([product_full_version],[product_version_major.product_version_minor.product_version_release]) diff --git a/mama/c_cpp/doxyconfig-c.in b/mama/c_cpp/doxyconfig-c.in index 9e0351862..f6560c8e9 100644 --- a/mama/c_cpp/doxyconfig-c.in +++ b/mama/c_cpp/doxyconfig-c.in @@ -754,7 +754,7 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = ./src/c/mama ./src/enterprise/c/mama +INPUT = ./src/c/mama # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/mama/c_cpp/doxyconfig-cpp.in b/mama/c_cpp/doxyconfig-cpp.in index 47ad587cf..3b57bb5d6 100644 --- a/mama/c_cpp/doxyconfig-cpp.in +++ b/mama/c_cpp/doxyconfig-cpp.in @@ -754,7 +754,7 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = ./src/cpp/mama ./src/enterprise/cpp/mama +INPUT = ./src/cpp/mama # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/mama/c_cpp/src/c/Makefile.am b/mama/c_cpp/src/c/Makefile.am index c831ce4bb..318c353de 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 4362f5090..f47e18c97 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 cbae5b157..9a6ff0599 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 @@ -75,9 +76,7 @@ playback/playbackcapture.c playback/playbackFileParser.c playback/playbackpublisher.c fieldcache/fieldcachefield.c -fieldcache/fieldcachemapbinary.c fieldcache/fieldcachemaparray.c -fieldcache/fieldcachemapmonitor.c fieldcache/fieldcacheimpl.c fieldcache/fieldcachemap.c fieldcache/fieldcacheiterator.c diff --git a/mama/c_cpp/src/c/bridge.c b/mama/c_cpp/src/c/bridge.c index 01cbcc52f..d7325af0b 100644 --- a/mama/c_cpp/src/c/bridge.c +++ b/mama/c_cpp/src/c/bridge.c @@ -20,8 +20,12 @@ */ #include +#include #include "bridge.h" +#define MAX_PROP_STRING 1000 +#define PROP_NAME_ENTITLEMENTS_DEFERRED "entitlements.deferred" + int mamaBridgeImpl_getDefaultQueueTimeout(void) { /* Returns. */ @@ -143,3 +147,65 @@ mamaBridgeImpl_stopInternalEventQueue (mamaBridge bridgeImpl) return MAMA_STATUS_OK; } + +mama_status +mamaBridgeImpl_setReadOnlyProperty (mamaBridge bridgeImpl, const char* property, const char* value) +{ + 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]; + + mamaBridgeImpl* impl = (mamaBridgeImpl*)bridgeImpl; + + /* Check for mama.middleware.entitlements_deferred first */ + 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 c079819ca..7a66d97e2 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); + +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 4ab74c79d..4955bcae4 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"); } mama_status diff --git a/mama/c_cpp/src/c/bridge/qpid/qpiddefs.h b/mama/c_cpp/src/c/bridge/qpid/qpiddefs.h index cd52e96ae..79ddbc4b9 100644 --- a/mama/c_cpp/src/c/bridge/qpid/qpiddefs.h +++ b/mama/c_cpp/src/c/bridge/qpid/qpiddefs.h @@ -32,7 +32,6 @@ #include /* Qpid include files */ -#include #include #include @@ -87,6 +86,10 @@ typedef enum qpidMsgType_ #if (PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR <= 7) #include #endif +#if (PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR <= 8) +/* The proton header driver.h was removed in version 0.9 */ +#include +#endif /* Place other version specific macros here */ diff --git a/mama/c_cpp/src/c/bridge/qpid/queue.c b/mama/c_cpp/src/c/bridge/qpid/queue.c index 5618b27aa..f12b0cff4 100644 --- a/mama/c_cpp/src/c/bridge/qpid/queue.c +++ b/mama/c_cpp/src/c/bridge/qpid/queue.c @@ -137,7 +137,7 @@ qpidBridgeMamaQueue_create (queueBridge* queue, mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaQueue_create (): " "Failed to create underlying queue."); - wombatQueue_destroy (impl->mQueue); + wombatQueue_deallocate (impl->mQueue); free (impl); return MAMA_STATUS_PLATFORM; } diff --git a/mama/c_cpp/src/c/bridge/qpid/transport.c b/mama/c_cpp/src/c/bridge/qpid/transport.c index 8ca9550e5..aa84fd72f 100644 --- a/mama/c_cpp/src/c/bridge/qpid/transport.c +++ b/mama/c_cpp/src/c/bridge/qpid/transport.c @@ -1433,7 +1433,7 @@ void* qpidBridgeMamaTransportImpl_dispatchThread (void* closure) case QPID_MSG_SUB_REQUEST: { pn_data_t* data = pn_message_body (msgNode->mMsg); - char* topic = NULL; + const char* topic = NULL; const char* replyTo = NULL; /* Move to the content which will contain the topic */ diff --git a/mama/c_cpp/src/c/conflation/manager.c b/mama/c_cpp/src/c/conflation/manager.c index db6b4093d..476db0919 100644 --- a/mama/c_cpp/src/c/conflation/manager.c +++ b/mama/c_cpp/src/c/conflation/manager.c @@ -78,7 +78,12 @@ mamaConflationManager_create (mamaConflationManager mgr) return MAMA_STATUS_NOMEM; if (wombatQueue_create (impl->mMsgQueue, 0, 0, 0) != WOMBAT_QUEUE_OK) + { + wombatQueue_deallocate(impl->mMsgQueue); + impl->mMsgQueue = NULL; + return MAMA_STATUS_CONFLATE_ERROR; + } status = mamaMsg_create (&impl->mMsg); diff --git a/mama/c_cpp/src/c/dictionary.c b/mama/c_cpp/src/c/dictionary.c index 7f7d605e8..33f1d524b 100644 --- a/mama/c_cpp/src/c/dictionary.c +++ b/mama/c_cpp/src/c/dictionary.c @@ -495,6 +495,21 @@ mamaDictionary_getDictionaryMessage ( return MAMA_STATUS_OK; } +mama_status + mamaDictionary_fillDictionaryMessage ( + mamaDictionary dictionary, + mamaMsg* msg) +{ + mamaDictionaryImpl* impl = (mamaDictionaryImpl*)dictionary; + + if (!impl) return MAMA_STATUS_NULL_ARG; + if (!msg) return MAMA_STATUS_INVALID_ARG; + + populateMessageFromDictionary (impl, *msg); + + return MAMA_STATUS_OK; +} + mama_status mamaDictionary_createFieldDescriptor ( mamaDictionary dictionary, @@ -952,6 +967,8 @@ void populateMessageFromDictionary (mamaDictionaryImpl* impl, int i = 0; mama_status status = MAMA_STATUS_OK; + const mama_bool_t bool_vector[] = {0}; + const char char_vector[] = {' '}; const mama_i8_t i8_vector[] = {1}; const mama_u8_t u8_vector[] = {1}; const mama_i16_t i16_vector[] = {1}; @@ -1048,6 +1065,12 @@ void populateMessageFromDictionary (mamaDictionaryImpl* impl, case MAMA_FIELD_TYPE_PRICE: ADD_TO_DICT (Price, price); break; + case MAMA_FIELD_TYPE_VECTOR_BOOL: + ADD_VECTOR_TO_DICT (Bool, bool_vector); + break; + case MAMA_FIELD_TYPE_VECTOR_CHAR: + ADD_VECTOR_TO_DICT (Char, char_vector); + break; case MAMA_FIELD_TYPE_VECTOR_I8: ADD_VECTOR_TO_DICT (I8, i8_vector); break; diff --git a/mama/c_cpp/src/c/fieldcache/fieldcachefield.c b/mama/c_cpp/src/c/fieldcache/fieldcachefield.c index 43a3c05f2..89389fd29 100644 --- a/mama/c_cpp/src/c/fieldcache/fieldcachefield.c +++ b/mama/c_cpp/src/c/fieldcache/fieldcachefield.c @@ -273,6 +273,22 @@ mamaFieldCacheField_copy(const mamaFieldCacheField field, mamaFieldCacheField co mamaFieldCacheField_setDateTime(copy, value); break; } + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + const mama_bool_t* values = NULL; + mama_size_t size; + mamaFieldCacheField_getBoolVector(field, &values, &size); + mamaFieldCacheField_setBoolVector(copy, values, size); + break; + } + case MAMA_FIELD_TYPE_VECTOR_CHAR: + { + const char* values = NULL; + mama_size_t size; + mamaFieldCacheField_getCharVector(field, &values, &size); + mamaFieldCacheField_setCharVector(copy, values, size); + break; + } case MAMA_FIELD_TYPE_VECTOR_I8: { const mama_i8_t* values = NULL; @@ -728,6 +744,40 @@ mama_status mamaFieldCacheField_getDateTime(const mamaFieldCacheField field, return MAMA_STATUS_OK; } +mama_status mamaFieldCacheField_getBoolVector(const mamaFieldCacheField field, + const mama_bool_t** values, + mama_size_t* size) +{ + if (!field || !values || !size) + { + return MAMA_STATUS_NULL_ARG; + } + if (field->mType != MAMA_FIELD_TYPE_VECTOR_BOOL) + { + return MAMA_STATUS_INVALID_ARG; + } + *values = (mama_bool_t*)field->mData.data; /* NOT COPYING */ + *size = field->mVectorSize; + return MAMA_STATUS_OK; +} + +mama_status mamaFieldCacheField_getCharVector(const mamaFieldCacheField field, + const char** values, + mama_size_t* size) +{ + if (!field || !values || !size) + { + return MAMA_STATUS_NULL_ARG; + } + if (field->mType != MAMA_FIELD_TYPE_VECTOR_CHAR) + { + return MAMA_STATUS_INVALID_ARG; + } + *values = (char*)field->mData.data; /* NOT COPYING */ + *size = field->mVectorSize; + return MAMA_STATUS_OK; +} + mama_status mamaFieldCacheField_getI8Vector(const mamaFieldCacheField field, const mama_i8_t** values, mama_size_t* size) @@ -1223,6 +1273,38 @@ mama_status mamaFieldCacheField_setDateTime(const mamaFieldCacheField field, return MAMA_STATUS_OK; } +mama_status mamaFieldCacheField_setBoolVector(const mamaFieldCacheField field, + const mama_bool_t* values, + mama_size_t size) +{ + if (!field || !values) + { + return MAMA_STATUS_NULL_ARG; + } + if (field->mType != MAMA_FIELD_TYPE_VECTOR_BOOL) + { + return MAMA_STATUS_INVALID_ARG; + } + field->mVectorSize = size; + return mamaFieldCacheField_setDataValue(field, values, size * sizeof(mama_bool_t)); +} + +mama_status mamaFieldCacheField_setCharVector(const mamaFieldCacheField field, + const char* values, + mama_size_t size) +{ + if (!field || !values) + { + return MAMA_STATUS_NULL_ARG; + } + if (field->mType != MAMA_FIELD_TYPE_VECTOR_CHAR) + { + return MAMA_STATUS_INVALID_ARG; + } + field->mVectorSize = size; + return mamaFieldCacheField_setDataValue(field, values, size * sizeof(char)); +} + mama_status mamaFieldCacheField_setI8Vector(const mamaFieldCacheField field, const mama_i8_t* values, mama_size_t size) diff --git a/mama/c_cpp/src/c/fieldcache/fieldcacheimpl.c b/mama/c_cpp/src/c/fieldcache/fieldcacheimpl.c index 48cbf2060..1d7d7a9d9 100644 --- a/mama/c_cpp/src/c/fieldcache/fieldcacheimpl.c +++ b/mama/c_cpp/src/c/fieldcache/fieldcacheimpl.c @@ -183,6 +183,22 @@ mama_status mamaFieldCache_updateCacheFromMsgField(mamaFieldCache fieldCache, mamaFieldCacheField_setDateTime(field, fieldCache->mReusableDateTime); break; } + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + const mama_bool_t* values = NULL; + mama_size_t size = 0; + mamaMsgField_getVectorBool(messageField, &values, &size); + mamaFieldCacheField_setBoolVector(field, values, size); + break; + } + case MAMA_FIELD_TYPE_VECTOR_CHAR: + { + const char* values = NULL; + mama_size_t size = 0; + mamaMsgField_getVectorChar(messageField, &values, &size); + mamaFieldCacheField_setCharVector(field, values, size); + break; + } case MAMA_FIELD_TYPE_VECTOR_I8: { const mama_i8_t* values = NULL; @@ -502,6 +518,32 @@ mama_status mamaFieldCache_updateMsgField(mamaFieldCache fieldCache, : mamaMsg_addDateTime(message, name, fid, value); break; } + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + const mama_bool_t* values = NULL; + mama_size_t size = 0; + mamaFieldCacheField_getBoolVector(field, &values, &size); + if (!values) + { + return MAMA_STATUS_INVALID_ARG; + } + status = useUpdate ? mamaMsg_updateVectorBool(message, name, fid, values, size) + : mamaMsg_addVectorBool(message, name, fid, values, size); + break; + } + case MAMA_FIELD_TYPE_VECTOR_CHAR: + { + const char* values = NULL; + mama_size_t size = 0; + mamaFieldCacheField_getCharVector(field, &values, &size); + if (!values) + { + return MAMA_STATUS_INVALID_ARG; + } + status = useUpdate ? mamaMsg_updateVectorChar(message, name, fid, values, size) + : mamaMsg_addVectorChar(message, name, fid, values, size); + break; + } case MAMA_FIELD_TYPE_VECTOR_I8: { const mama_i8_t* values = NULL; diff --git a/mama/c_cpp/src/c/fielddesc.c b/mama/c_cpp/src/c/fielddesc.c index a94856769..1f08e01df 100644 --- a/mama/c_cpp/src/c/fielddesc.c +++ b/mama/c_cpp/src/c/fielddesc.c @@ -196,6 +196,10 @@ mamaFieldTypeToString (mamaFieldType type) return "TIME"; case MAMA_FIELD_TYPE_PRICE: return "PRICE"; + case MAMA_FIELD_TYPE_VECTOR_BOOL: + return "VECTOR_BOOL"; + case MAMA_FIELD_TYPE_VECTOR_CHAR: + return "VECTOR_CHAR"; case MAMA_FIELD_TYPE_VECTOR_I8: return "VECTOR_I8"; case MAMA_FIELD_TYPE_VECTOR_U8: @@ -270,6 +274,10 @@ stringToMamaFieldType (const char* str) return MAMA_FIELD_TYPE_TIME; if (strcmp(str, "PRICE") == 0) return MAMA_FIELD_TYPE_PRICE; + if (strcmp(str, "VECTOR_BOOL") == 0) + return MAMA_FIELD_TYPE_VECTOR_BOOL; + if (strcmp(str, "VECTOR_CHAR") == 0) + return MAMA_FIELD_TYPE_VECTOR_CHAR; if (strcmp(str, "VECTOR_I8") == 0) return MAMA_FIELD_TYPE_VECTOR_I8; if (strcmp(str, "VECTOR_U8") == 0) diff --git a/mama/c_cpp/src/c/generateMamaVersion.bat b/mama/c_cpp/src/c/generateMamaVersion.bat index 70e6aa820..dd6f075eb 100644 --- a/mama/c_cpp/src/c/generateMamaVersion.bat +++ b/mama/c_cpp/src/c/generateMamaVersion.bat @@ -1,7 +1,7 @@ set BUILD_DIR=%1 set VERSION_MAJOR=2 set VERSION_MINOR=3 -set VERSION_RELEASE=2 +set VERSION_RELEASE=3 set RC_VERSION_NUMERICAL=1 set RC_VERSION_STRING=1 set MAMACDLL=libmamacmdd.dll diff --git a/mama/c_cpp/src/c/listenermsgcallback.c b/mama/c_cpp/src/c/listenermsgcallback.c index 85c3bf246..caeaa56f5 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 33a0768f8..1815bc05f 100644 --- a/mama/c_cpp/src/c/mama.c +++ b/mama/c_cpp/src/c/mama.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "fileutils.h" #include "reservedfieldsimpl.h" @@ -42,7 +43,6 @@ #include #include #include -#include #include #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) { @@ -1701,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) @@ -1709,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/mama/dictionary.h b/mama/c_cpp/src/c/mama/dictionary.h index 0eda95869..73b3dc1b8 100644 --- a/mama/c_cpp/src/c/mama/dictionary.h +++ b/mama/c_cpp/src/c/mama/dictionary.h @@ -267,6 +267,22 @@ mamaDictionary_getDictionaryMessage ( mamaDictionary dictionary, mamaMsg* msg); +/** + * Fill a message with the data dictionary. + * + * An existing mama message is populated fromt he data dictionary + * This allows the caller to create the message on a specifc payload + * + * @param dictionary The Dictionary + * @param msg The address of the mamaMsg where the result is to be written + */ +MAMAExpDLL +extern mama_status +mamaDictionary_fillDictionaryMessage ( + mamaDictionary dictionary, + mamaMsg* msg); + + /** * Create a new field descriptor and add it to the dictionary. * New fields can be added to an existing dictionary obtained diff --git a/mama/c_cpp/src/c/mama/fieldcache/fieldcachefield.h b/mama/c_cpp/src/c/mama/fieldcache/fieldcachefield.h index 55dbd9b3a..a9ca40fad 100644 --- a/mama/c_cpp/src/c/mama/fieldcache/fieldcachefield.h +++ b/mama/c_cpp/src/c/mama/fieldcache/fieldcachefield.h @@ -441,6 +441,40 @@ extern mama_status mamaFieldCacheField_getDateTime(const mamaFieldCacheField field, const mamaDateTime* result); +/** + * This function will get the values a mamaFieldCacheField of type Bool vector. + * + * @param field (in) The field. + * @param values (out) The array of values of the field. + * @param size (out) The number of values. + * @return Resulting status of the call which can be + * MAMA_STATUS_NULL_ARG + * MAMA_STATUS_INVALID_ARG + * MAMA_STATUS_OK + */ +MAMAExpDLL +extern mama_status +mamaFieldCacheField_getBoolVector(const mamaFieldCacheField field, + const mama_bool_t** values, + mama_size_t* size); +/** + * This function will get the values a mamaFieldCacheField of type Char vector. + * + * @param field (in) The field. + * @param values (out) The array of values of the field. + * @param size (out) The number of values. + * @return Resulting status of the call which can be + * MAMA_STATUS_NULL_ARG + * MAMA_STATUS_INVALID_ARG + * MAMA_STATUS_OK + */ +MAMAExpDLL +extern mama_status +mamaFieldCacheField_getCharVector(const mamaFieldCacheField field, + const char** values, + mama_size_t* size); + + /** * This function will get the values a mamaFieldCacheField of type I8 vector. * @@ -878,6 +912,37 @@ extern mama_status mamaFieldCacheField_setDateTime(const mamaFieldCacheField field, const mamaDateTime value); +/** + * This function will set the values of a mamaFieldCacheField of type Bool vector. + * + * @param field (in) The field to set the value to. + * @param value (in) The new value of the field. + * @return Resulting status of the call which can be + * MAMA_STATUS_NULL_ARG + * MAMA_STATUS_INVALID_ARG + * MAMA_STATUS_OK + */ +MAMAExpDLL +extern mama_status +mamaFieldCacheField_setBoolVector(const mamaFieldCacheField field, + const mama_bool_t* values, + mama_size_t size); +/** + * This function will set the values of a mamaFieldCacheField of type Char vector. + * + * @param field (in) The field to set the value to. + * @param value (in) The new value of the field. + * @return Resulting status of the call which can be + * MAMA_STATUS_NULL_ARG + * MAMA_STATUS_INVALID_ARG + * MAMA_STATUS_OK + */ +MAMAExpDLL +extern mama_status +mamaFieldCacheField_setCharVector(const mamaFieldCacheField field, + const char* values, + mama_size_t size); + /** * This function will set the values of a mamaFieldCacheField of type I8 vector. * diff --git a/mama/c_cpp/src/c/mama/fielddesc.h b/mama/c_cpp/src/c/mama/fielddesc.h index e3af6e130..a374489f4 100644 --- a/mama/c_cpp/src/c/mama/fielddesc.h +++ b/mama/c_cpp/src/c/mama/fielddesc.h @@ -90,6 +90,8 @@ typedef enum mamaFieldType_ MAMA_FIELD_TYPE_PRICE = 27, /** Array type support */ + MAMA_FIELD_TYPE_VECTOR_BOOL = 29, + MAMA_FIELD_TYPE_VECTOR_CHAR = 30, MAMA_FIELD_TYPE_VECTOR_I8 = 34, MAMA_FIELD_TYPE_VECTOR_U8 = 35, MAMA_FIELD_TYPE_VECTOR_I16 = 36, diff --git a/mama/c_cpp/src/c/mama/middleware.h b/mama/c_cpp/src/c/mama/middleware.h index 05307f714..51225a2de 100644 --- a/mama/c_cpp/src/c/mama/middleware.h +++ b/mama/c_cpp/src/c/mama/middleware.h @@ -49,7 +49,8 @@ typedef enum mamaMiddleware_ MAMA_MIDDLEWARE_VULCAN = 13, MAMA_MIDDLEWARE_INRUSH = 14, MAMA_MIDDLEWARE_LBMKOMODO = 15, - MAMA_MIDDLEWARE_MAX = 16, + MAMA_MIDDLEWARE_UMDSKOMODO = 16, + MAMA_MIDDLEWARE_MAX = 17, MAMA_MIDDLEWARE_UNKNOWN = 99 } mamaMiddleware; diff --git a/mama/c_cpp/src/c/mama/types.h b/mama/c_cpp/src/c/mama/types.h index 50d660890..03f6da8c7 100644 --- a/mama/c_cpp/src/c/mama/types.h +++ b/mama/c_cpp/src/c/mama/types.h @@ -73,6 +73,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 */ diff --git a/mama/c_cpp/src/c/middleware.c b/mama/c_cpp/src/c/middleware.c index 7109493cf..f966491aa 100644 --- a/mama/c_cpp/src/c/middleware.c +++ b/mama/c_cpp/src/c/middleware.c @@ -77,6 +77,9 @@ mamaMiddleware_convertFromString (const char* str) if (strcasecmp (str, "lbmkomodo") == 0) return MAMA_MIDDLEWARE_LBMKOMODO; + if (strcasecmp (str, "umdskomodo") == 0) + return MAMA_MIDDLEWARE_UMDSKOMODO; + return MAMA_MIDDLEWARE_UNKNOWN; } @@ -118,6 +121,8 @@ mamaMiddleware_convertToString (mamaMiddleware middleware) return "inrush"; case MAMA_MIDDLEWARE_LBMKOMODO: return "lbmkomodo"; + case MAMA_MIDDLEWARE_UMDSKOMODO: + return "umdskomodo"; default: return "unknown"; } diff --git a/mama/c_cpp/src/c/msgfield.c b/mama/c_cpp/src/c/msgfield.c index 904a365b0..52fda4fd8 100644 --- a/mama/c_cpp/src/c/msgfield.c +++ b/mama/c_cpp/src/c/msgfield.c @@ -485,6 +485,24 @@ mamaMsgField_getMsg ( return MAMA_STATUS_NULL_ARG; } +mama_status +mamaMsgField_getVectorBool ( + const mamaMsgField msgField, + const mama_bool_t** result, + size_t* size) +{ + mamaMsgFieldImpl* impl = + (mamaMsgFieldImpl*)(msgField); + if (!impl) return MAMA_STATUS_INVALID_ARG; + + if (impl->myPayloadBridge) + { + return impl->myPayloadBridge->msgFieldPayloadGetVectorBool ( + impl->myPayload, result, size); + } + return MAMA_STATUS_NULL_ARG; +} + mama_status mamaMsgField_getVectorChar ( const mamaMsgField msgField, diff --git a/mama/c_cpp/src/c/payload/qpidmsg/field.c b/mama/c_cpp/src/c/payload/qpidmsg/field.c index ae988e951..49ac087bd 100644 --- a/mama/c_cpp/src/c/payload/qpidmsg/field.c +++ b/mama/c_cpp/src/c/payload/qpidmsg/field.c @@ -919,7 +919,7 @@ qpidmsgFieldPayload_getVectorBool (const msgFieldPayload field, const mama_bool_t** result, mama_size_t* size) { - return MAMA_STATUS_NOT_IMPLEMENTED; + GET_VECTOR_FIELD (_bool, mama_bool_t); } mama_status @@ -1264,6 +1264,16 @@ qpidmsgFieldPayload_getAsString (const msgFieldPayload field, long long unsigned); break; } + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + EXPAND_PRINT_VECTOR_MACROS (mama_bool_t, Bool, "%u", mama_bool_t); + break; + } + case MAMA_FIELD_TYPE_VECTOR_CHAR: + { + EXPAND_PRINT_VECTOR_MACROS (char, Char, "%c", char); + break; + } case MAMA_FIELD_TYPE_VECTOR_I8: { EXPAND_PRINT_VECTOR_MACROS (mama_i8_t, I8, "%d", mama_i8_t); diff --git a/mama/c_cpp/src/c/payload/qpidmsg/payload.c b/mama/c_cpp/src/c/payload/qpidmsg/payload.c index 09daab461..2e697697c 100644 --- a/mama/c_cpp/src/c/payload/qpidmsg/payload.c +++ b/mama/c_cpp/src/c/payload/qpidmsg/payload.c @@ -1166,6 +1166,16 @@ qpidmsgPayload_apply (msgPayload dest, UPDATE_VECTOR_FIELD (U8, mama_u8_t); break; } + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + UPDATE_VECTOR_FIELD (Bool, mama_bool_t); + break; + } + case MAMA_FIELD_TYPE_VECTOR_CHAR: + { + UPDATE_VECTOR_FIELD (Char, char); + break; + } case MAMA_FIELD_TYPE_VECTOR_I8: { UPDATE_VECTOR_FIELD (I8, mama_i8_t); @@ -3733,6 +3743,12 @@ qpidmsgPayloadImpl_addFieldToPayload (msgPayload msg, return status; break; } + case MAMA_FIELD_TYPE_VECTOR_BOOL: + ADD_VECTOR_FIELD_VALUE_TO_MESSAGE(Bool, mama_bool_t); + break; + case MAMA_FIELD_TYPE_VECTOR_CHAR: + ADD_VECTOR_FIELD_VALUE_TO_MESSAGE(Char, char); + break; case MAMA_FIELD_TYPE_VECTOR_I8: ADD_VECTOR_FIELD_VALUE_TO_MESSAGE(I8, mama_i8_t); break; @@ -3912,14 +3928,14 @@ qpidmsgPayloadImpl_arrayToMamaType (pn_type_t type) switch(type) { case PN_NULL: return MAMA_FIELD_TYPE_UNKNOWN; - case PN_BOOL: return MAMA_FIELD_TYPE_VECTOR_U8; + case PN_BOOL: return MAMA_FIELD_TYPE_VECTOR_BOOL; case PN_UBYTE: return MAMA_FIELD_TYPE_VECTOR_U8; case PN_BYTE: return MAMA_FIELD_TYPE_VECTOR_I8; case PN_USHORT: return MAMA_FIELD_TYPE_VECTOR_U16; case PN_SHORT: return MAMA_FIELD_TYPE_VECTOR_I16; case PN_UINT: return MAMA_FIELD_TYPE_VECTOR_U32; case PN_INT: return MAMA_FIELD_TYPE_VECTOR_I32; - case PN_CHAR: return MAMA_FIELD_TYPE_VECTOR_U8; + case PN_CHAR: return MAMA_FIELD_TYPE_VECTOR_CHAR; case PN_ULONG: return MAMA_FIELD_TYPE_VECTOR_U64; case PN_LONG: return MAMA_FIELD_TYPE_VECTOR_I64; case PN_TIMESTAMP: return MAMA_FIELD_TYPE_VECTOR_TIME; diff --git a/mama/c_cpp/src/c/payload/qpidmsg/qpidcommon.c b/mama/c_cpp/src/c/payload/qpidmsg/qpidcommon.c index 8e91c2dad..78d5123ef 100644 --- a/mama/c_cpp/src/c/payload/qpidmsg/qpidcommon.c +++ b/mama/c_cpp/src/c/payload/qpidmsg/qpidcommon.c @@ -210,7 +210,7 @@ qpidmsgPayloadInternal_elementToString (pn_data_t* payload, case PN_BINARY: { mama_size_t i = 0; - char* bytePos = NULL; + const char* bytePos = NULL; pn_bytes_t bytes; bytes = atom.u.as_bytes; diff --git a/mama/c_cpp/src/c/plugin.c b/mama/c_cpp/src/c/plugin.c new file mode 100644 index 000000000..303ab9f5e --- /dev/null +++ b/mama/c_cpp/src/c/plugin.c @@ -0,0 +1,467 @@ +/* $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 +#include +#include + +#include "wombat/port.h" +#include "wombat/environment.h" +#include "wombat/strutils.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +#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); + } + } + + 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 */ + 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] != NULL) + { + 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 000000000..df43b2723 --- /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 4612d1733..2efd88d92 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); @@ -590,4 +600,11 @@ mama_status mamaPublisherImpl_clearTransport (mamaPublisher publisher) return mamaPublisherImpl_destroy((mamaPublisherImpl *)publisher); } +mamaTransport +mamaPublisherImpl_getTransportImpl (mamaPublisher publisher) +{ + mamaPublisherImpl* impl = (mamaPublisherImpl*)publisher; + if (!impl) return NULL; + return impl->mTport; +} diff --git a/mama/c_cpp/src/c/publisherimpl.h b/mama/c_cpp/src/c/publisherimpl.h index f336fd8c8..b9b9c43d0 100644 --- a/mama/c_cpp/src/c/publisherimpl.h +++ b/mama/c_cpp/src/c/publisherimpl.h @@ -44,6 +44,9 @@ mamaPublisher_sendFromInboxByIndex (mamaPublisher publisher, mama_status mamaPublisherImpl_clearTransport (mamaPublisher publisher); +extern mamaTransport +mamaPublisherImpl_getTransportImpl (mamaPublisher publisher); + #if defined(__cplusplus) } #endif diff --git a/mama/c_cpp/src/c/subscription.c b/mama/c_cpp/src/c/subscription.c index c80925727..42ad347f4 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; } @@ -2616,7 +2636,19 @@ mama_status mamaSubscription_deactivate(mamaSubscription subscription) ret = mamaSubscription_deactivate_internal(impl); if (impl->mSubscMsgType == MAMA_SUBSC_DDICT_SNAPSHOT || impl->mSubscMsgType == MAMA_SUBSC_SNAPSHOT) + { + /* Snapshot subscriptions don't have a bridge and are transitioned to deactivated + * immediately after deactivating. + * Also, since there is no bridge subscription callback to be called later with + * mamaSubscriptionImpl_onSubscriptionDestroyed, the necessary actions for deactivated + * state are performed here. Namely the queue object count is decremented. + */ + if(NULL != impl->mQueue) + { + mamaQueue_decrementObjectCount(&impl->mLockHandle, impl->mQueue); + } mamaSubscriptionImpl_setState(impl, MAMA_SUBSCRIPTION_DEACTIVATED); + } break; case MAMA_SUBSCRIPTION_DEACTIVATING: diff --git a/mama/c_cpp/src/c/transport.c b/mama/c_cpp/src/c/transport.c index 339dbc03b..622f47d03 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; diff --git a/mama/c_cpp/src/cpp/MamaMsgField.cpp b/mama/c_cpp/src/cpp/MamaMsgField.cpp index 08988256d..f2f287ced 100644 --- a/mama/c_cpp/src/cpp/MamaMsgField.cpp +++ b/mama/c_cpp/src/cpp/MamaMsgField.cpp @@ -242,6 +242,12 @@ namespace Wombat mamaTry (mamaMsgField_getDateTime (mField, result.getCValue())); } + void MamaMsgField::getVectorBool (const mama_bool_t*& result, + size_t& resultLen) const + { + mamaTry (mamaMsgField_getVectorBool (mField, &result, &resultLen)); + } + void MamaMsgField::getVectorChar (const char*& result, size_t& resultLen) const { diff --git a/mama/c_cpp/src/cpp/fieldcache/MamaFieldCacheField.cpp b/mama/c_cpp/src/cpp/fieldcache/MamaFieldCacheField.cpp index ee785f7c7..69d5de94f 100644 --- a/mama/c_cpp/src/cpp/fieldcache/MamaFieldCacheField.cpp +++ b/mama/c_cpp/src/cpp/fieldcache/MamaFieldCacheField.cpp @@ -198,6 +198,8 @@ bool MamaFieldCacheField::isVector() const { switch (getType()) { + case MAMA_FIELD_TYPE_VECTOR_BOOL: + case MAMA_FIELD_TYPE_VECTOR_CHAR: case MAMA_FIELD_TYPE_VECTOR_I8: case MAMA_FIELD_TYPE_VECTOR_U8: case MAMA_FIELD_TYPE_VECTOR_I16: diff --git a/mama/c_cpp/src/cpp/fieldcache/MamaFieldCacheFieldTypes.cpp b/mama/c_cpp/src/cpp/fieldcache/MamaFieldCacheFieldTypes.cpp index 0a0261362..c1a64d726 100644 --- a/mama/c_cpp/src/cpp/fieldcache/MamaFieldCacheFieldTypes.cpp +++ b/mama/c_cpp/src/cpp/fieldcache/MamaFieldCacheFieldTypes.cpp @@ -273,6 +273,66 @@ const MamaDateTime& MamaFieldCacheFieldDateTime::get(const MamaFieldCacheField& return mDateTime; } +// MAMA_FIELD_TYPE_VECTOR_BOOL +template <> +void MamaFieldCacheFieldBoolVector::set(MamaFieldCacheField& field, + const mama_bool_t* values, + mama_size_t size) +{ + checkType(field); + mamaFieldCacheField_setBoolVector(field.getCValue(), values, size); +} +template <> +void MamaFieldCacheFieldBoolVector::get(const MamaFieldCacheField& field, + const mama_bool_t*& values, + mama_size_t& size) const +{ + checkType(field); + mamaFieldCacheField_getBoolVector(field.getCValue(), &values, &size); +} +template <> +const mama_bool_t& MamaFieldCacheFieldBoolVector::get(const MamaFieldCacheField& field, + mama_size_t index) const +{ + checkType(field); + const mama_bool_t* values = NULL; + mama_size_t size = 0; + mamaFieldCacheField_getBoolVector(field.getCValue(), &values, &size); + if (index < size) + return values[index]; + throw std::out_of_range("MamaFieldCacheFieldBoolVector::get"); +} + +// MAMA_FIELD_TYPE_VECTOR_CHAR +template <> +void MamaFieldCacheFieldCharVector::set(MamaFieldCacheField& field, + const char* values, + mama_size_t size) +{ + checkType(field); + mamaFieldCacheField_setCharVector(field.getCValue(), values, size); +} +template <> +void MamaFieldCacheFieldCharVector::get(const MamaFieldCacheField& field, + const char*& values, + mama_size_t& size) const +{ + checkType(field); + mamaFieldCacheField_getCharVector(field.getCValue(), &values, &size); +} +template <> +const char& MamaFieldCacheFieldCharVector::get(const MamaFieldCacheField& field, + mama_size_t index) const +{ + checkType(field); + const char* values = NULL; + mama_size_t size = 0; + mamaFieldCacheField_getCharVector(field.getCValue(), &values, &size); + if (index < size) + return values[index]; + throw std::out_of_range("MamaFieldCacheFieldCharVector::get"); +} + // MAMA_FIELD_TYPE_VECTOR_I8 template <> void MamaFieldCacheFieldI8Vector::set(MamaFieldCacheField& field, diff --git a/mama/c_cpp/src/cpp/mama/MamaMsgField.h b/mama/c_cpp/src/cpp/mama/MamaMsgField.h index b81a84493..f763dcac7 100644 --- a/mama/c_cpp/src/cpp/mama/MamaMsgField.h +++ b/mama/c_cpp/src/cpp/mama/MamaMsgField.h @@ -200,6 +200,15 @@ namespace Wombat void getMsg ( MamaMsg& result) const; + /** + * Get a vector of boolean. + * @param result (out) the vector. + * @param resultLen (out) the size of the vector. + */ + void getVectorBool ( + const mama_bool_t*& result, + mama_size_t& resultLen) const; + /** * Get a vector of characters. * @param result (out) the vector. diff --git a/mama/c_cpp/src/cpp/mama/fieldcache/MamaFieldCacheFieldTypes.h b/mama/c_cpp/src/cpp/mama/fieldcache/MamaFieldCacheFieldTypes.h index 79c871356..fe164dfa1 100644 --- a/mama/c_cpp/src/cpp/mama/fieldcache/MamaFieldCacheFieldTypes.h +++ b/mama/c_cpp/src/cpp/mama/fieldcache/MamaFieldCacheFieldTypes.h @@ -277,6 +277,18 @@ class MAMACPPExpDLL MamaFieldCacheFieldVectorBasic : public MamaFieldCacheFieldB } }; +/** + * MamaFieldCacheFieldBoolVector. + * Class used to set and get the value of a mama_bool_t vector MamaFieldCacheField. + */ +typedef MamaFieldCacheFieldVectorBasic + MamaFieldCacheFieldBoolVector; +/** + * MamaFieldCacheFieldCharVector. + * Class used to set and get the value of a char vector MamaFieldCacheField. + */ +typedef MamaFieldCacheFieldVectorBasic + MamaFieldCacheFieldCharVector; /** * MamaFieldCacheFieldI8Vector. * Class used to set and get the value of a mama_i8_t vector MamaFieldCacheField. @@ -887,6 +899,18 @@ void setFieldValue(MamaFieldCacheField& field, const T* values, mama_size_t size { switch(field.getType()) { + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + MamaFieldCacheFieldBoolVector getField; + getField.set(field, (const mama_bool_t*)values, size); + break; + } + case MAMA_FIELD_TYPE_VECTOR_CHAR: + { + MamaFieldCacheFieldCharVector getField; + getField.set(field, (const char*)values, size); + break; + } case MAMA_FIELD_TYPE_VECTOR_I8: { MamaFieldCacheFieldI8Vector getField; @@ -999,6 +1023,18 @@ void getFieldValue(const MamaFieldCacheField& field, const T*& values, mama_size { switch(field.getType()) { + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + MamaFieldCacheFieldBoolVector getField; + getField.get(field, (const mama_bool_t*&)values, size); + break; + } + case MAMA_FIELD_TYPE_VECTOR_CHAR: + { + MamaFieldCacheFieldCharVector getField; + getField.get(field, (const char*&)values, size); + break; + } case MAMA_FIELD_TYPE_VECTOR_I8: { MamaFieldCacheFieldI8Vector getField; diff --git a/mama/c_cpp/src/examples/c/mamalistencachedc.c b/mama/c_cpp/src/examples/c/mamalistencachedc.c index db6d3ee1d..6d8ccf4f2 100644 --- a/mama/c_cpp/src/examples/c/mamalistencachedc.c +++ b/mama/c_cpp/src/examples/c/mamalistencachedc.c @@ -2630,6 +2630,32 @@ void printField(mamaFieldCacheField field) printf ("%s\n", priceString); break; } + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + const mama_bool_t* result = NULL; + mama_size_t size = 0; + mama_size_t i =0; + mamaFieldCacheField_getBoolVector(field,&result,&size); + printf("\n"); + for (i=0;imsgPayloadGetField (m_msg, NULL, 1, &m_field); m_status = m_payloadBridge->msgFieldPayloadGetVectorBool(m_field, &m_out, &m_size); - ASSERT_EQ (MAMA_STATUS_NOT_IMPLEMENTED, m_status); + ASSERT_EQ (MAMA_STATUS_OK, m_status); + ASSERT_EQ (1, m_out[0]); + ASSERT_EQ (0, m_out[1]); + ASSERT_EQ ((mama_size_t) VECTOR_SIZE * sizeof(mama_bool_t), m_size); } TEST_F(FieldVectorBoolTests, GetVectorBoolNullOut) { m_status = m_payloadBridge->msgFieldPayloadGetVectorBool(m_field, NULL, &m_size); - ASSERT_EQ (MAMA_STATUS_NOT_IMPLEMENTED, m_status); + ASSERT_EQ (MAMA_STATUS_NULL_ARG, m_status); } TEST_F(FieldVectorBoolTests, GetVectorBoolNullSize) { m_status = m_payloadBridge->msgFieldPayloadGetVectorBool(m_field, &m_out, NULL); - ASSERT_EQ (MAMA_STATUS_NOT_IMPLEMENTED, m_status); + ASSERT_EQ (MAMA_STATUS_NULL_ARG, m_status); } /** diff --git a/mama/c_cpp/src/gunittest/cpp/fieldcache/MamaFieldCacheFieldTypesTest.cpp b/mama/c_cpp/src/gunittest/cpp/fieldcache/MamaFieldCacheFieldTypesTest.cpp index ee4c6b1e0..15065960c 100644 --- a/mama/c_cpp/src/gunittest/cpp/fieldcache/MamaFieldCacheFieldTypesTest.cpp +++ b/mama/c_cpp/src/gunittest/cpp/fieldcache/MamaFieldCacheFieldTypesTest.cpp @@ -499,6 +499,86 @@ TEST_F(MamaFieldCacheFieldTypesTest, testDateTime) ASSERT_DOUBLE_EQ(2500, value.getEpochTimeSeconds()); } +TEST_F(MamaFieldCacheFieldTypesTest, testBoolVector) +{ + MamaFieldCacheField fieldBase; + fieldBase.create(1, MAMA_FIELD_TYPE_VECTOR_BOOL, ""); + MamaFieldCacheFieldBoolVector field; + + mama_bool_t values[5] = { 0, 1, 0, 1, 1 }; + field.set(fieldBase, values, 5); + ASSERT_EQ(0, field.get(fieldBase, 0)); + ASSERT_EQ(1, field.get(fieldBase, 1)); + ASSERT_EQ(0, field.get(fieldBase, 2)); + ASSERT_EQ(1, field.get(fieldBase, 3)); + ASSERT_EQ(1, field.get(fieldBase, 4)); + + const mama_bool_t* result = NULL; + mama_size_t size; + field.get(fieldBase, result, size); + ASSERT_EQ(5, size); + ASSERT_EQ(0, result[0]); + ASSERT_EQ(1, result[1]); + ASSERT_EQ(0, result[2]); + ASSERT_EQ(1, result[3]); + ASSERT_EQ(1, result[4]); + getFieldValue(fieldBase, result, size); + ASSERT_EQ(5, size); + ASSERT_EQ(0, result[0]); + ASSERT_EQ(1, result[1]); + ASSERT_EQ(0, result[2]); + ASSERT_EQ(1, result[3]); + ASSERT_EQ(1, result[4]); + + values[2] = 1; + setFieldValue(fieldBase, values, 5); + ASSERT_EQ(0, field.get(fieldBase, 0)); + ASSERT_EQ(1, field.get(fieldBase, 1)); + ASSERT_EQ(1, field.get(fieldBase, 2)); + ASSERT_EQ(1, field.get(fieldBase, 3)); + ASSERT_EQ(1, field.get(fieldBase, 4)); +} + +TEST_F(MamaFieldCacheFieldTypesTest, testCharVector) +{ + MamaFieldCacheField fieldBase; + fieldBase.create(1, MAMA_FIELD_TYPE_VECTOR_CHAR, ""); + MamaFieldCacheFieldCharVector field; + + char values[5] = { 'E', 'F', 'V', 'H', 'I' }; + field.set(fieldBase, values, 5); + ASSERT_EQ('E', field.get(fieldBase, 0)); + ASSERT_EQ('F', field.get(fieldBase, 1)); + ASSERT_EQ('V', field.get(fieldBase, 2)); + ASSERT_EQ('H', field.get(fieldBase, 3)); + ASSERT_EQ('I', field.get(fieldBase, 4)); + + const char* result = NULL; + mama_size_t size; + field.get(fieldBase, result, size); + ASSERT_EQ(5, size); + ASSERT_EQ('E', result[0]); + ASSERT_EQ('F', result[1]); + ASSERT_EQ('V', result[2]); + ASSERT_EQ('H', result[3]); + ASSERT_EQ('I', result[4]); + getFieldValue(fieldBase, result, size); + ASSERT_EQ(5, size); + ASSERT_EQ('E', result[0]); + ASSERT_EQ('F', result[1]); + ASSERT_EQ('V', result[2]); + ASSERT_EQ('H', result[3]); + ASSERT_EQ('I', result[4]); + + values[2] = 'G'; + setFieldValue(fieldBase, values, 5); + ASSERT_EQ('E', field.get(fieldBase, 0)); + ASSERT_EQ('F', field.get(fieldBase, 1)); + ASSERT_EQ('G', field.get(fieldBase, 2)); + ASSERT_EQ('H', field.get(fieldBase, 3)); + ASSERT_EQ('I', field.get(fieldBase, 4)); +} + TEST_F(MamaFieldCacheFieldTypesTest, testI8Vector) { MamaFieldCacheField fieldBase; diff --git a/mama/c_cpp/src/testtools/capturereplay/c/captureconvert.c b/mama/c_cpp/src/testtools/capturereplay/c/captureconvert.c index 4181219c6..16b23b7bf 100644 --- a/mama/c_cpp/src/testtools/capturereplay/c/captureconvert.c +++ b/mama/c_cpp/src/testtools/capturereplay/c/captureconvert.c @@ -538,7 +538,17 @@ static void copyMamaMsg (mamaMsg sourceMessage, mamaMsg_destroy (internalTarget); break; } - case MAMA_FIELD_TYPE_VECTOR_I8: + case MAMA_FIELD_TYPE_VECTOR_BOOL: + { + MAMA_VECTOR_FIELD_COPY (Bool, mama_bool_t); + break; + } + case MAMA_FIELD_TYPE_VECTOR_CHAR: + { + MAMA_VECTOR_FIELD_COPY (Char, char); + break; + } + case MAMA_FIELD_TYPE_VECTOR_I8: { MAMA_VECTOR_FIELD_COPY (I8, mama_i8_t); break; diff --git a/mama/jni/SConscript b/mama/jni/SConscript index 6d4173dbc..61a35701f 100644 --- a/mama/jni/SConscript +++ b/mama/jni/SConscript @@ -20,6 +20,9 @@ testtools_source = Split(""" testtools = [] +unittest_source = Glob('src/junittests') +unittest = [] + jExamples = Glob('src/com/wombat/mama/examples/*java') version = env['versions']['mama']['releaseString'] @@ -43,14 +46,20 @@ if env['with_testtools'] == True: for t in testtools_source: testtools.append( env.Java( 'classes', t ) ) +if env['with_unittest'] == True: + for t in unittest_source: + unittest.append( env.Java( 'classes', t ) ) + env.Append(JAVACLASSPATH = ('$junit_home/junit.jar')) + env.Depends( mama_classes, common_classes ) env.Depends( testtools, mama_classes ) +env.Depends( unittest, mama_classes ) # Builds all of the header files which is unnecessary but no reason not to # do this headers = env.JavaH(target=Dir('src/c/mamajni').abspath,source= [ mama_classes, common_classes ]) -env.Depends( headers, [ mama_classes, common_classes, testtools ] ) +env.Depends( headers, [ mama_classes, common_classes, testtools, unittest ] ) jar = env.Jar(target='mamajni.jar', source='classes', JARCHDIR = Dir('classes').abspath ) diff --git a/mama/jni/src/c/mamadatetimejni.c b/mama/jni/src/c/mamadatetimejni.c index 8664df980..eb36ba027 100644 --- a/mama/jni/src/c/mamadatetimejni.c +++ b/mama/jni/src/c/mamadatetimejni.c @@ -712,6 +712,59 @@ JNIEXPORT jstring JNICALL Java_com_wombat_mama_MamaDateTime_getAsString return (*env)->NewStringUTF (env, ret_c); } +/* + * Class: com_wombat_mama_MamaDateTime + * Method: getAsFormattedString + * Signature: ()Ljava/lang/String + */ +JNIEXPORT jstring JNICALL Java_com_wombat_mama_MamaDateTime_getAsFormattedString + (JNIEnv* env, jobject this, jstring str, jstring timeZone) +{ + jlong pDateTime = 0; + jlong pTimeZone = 0; + const char* c_Str = NULL; + mama_status status = MAMA_STATUS_OK; + char ret_c [MAX_DATE_TIME_STR_LEN+1]; + char errorString [UTILS_MAX_ERROR_STRING_LENGTH]; + + pDateTime = (*env)->GetLongField (env,this,dateTimePointerFieldId_g); + MAMA_THROW_NULL_PARAMETER_RETURN_VALUE(pDateTime, + "Null parameter, MamaDateTime may have already been destroyed.", NULL) ; + + if (NULL != timeZone) + { + pTimeZone = (*env)->GetLongField (env,this,tzFieldObjectFieldId_g); + if (0 == pTimeZone) + { + pTimeZone = createTimeZone (env, this); + assert (0!=pTimeZone); + } + timeZone_set (env, pTimeZone, timeZone); + } + + c_Str = (*env)->GetStringUTFChars(env,str,0); + + if (!c_Str || + MAMA_STATUS_OK!=(status=mamaDateTime_getAsFormattedStringWithTz( + CAST_JLONG_TO_POINTER(mamaDateTime,pDateTime), + ret_c, + MAX_DATE_TIME_STR_LEN, + c_Str, + timeZone + ? CAST_JLONG_TO_POINTER (mamaTimeZone, pTimeZone) + : NULL))) + { + utils_buildErrorStringForStatus( + errorString, + UTILS_MAX_ERROR_STRING_LENGTH, + "Error calling MamaDateTime.getAsStringWithTz().", + status); + utils_throwExceptionForMamaStatus (env,status,errorString); + return 0; + } + return (*env)->NewStringUTF (env, ret_c); +} + /* * Class: com_wombat_mama_MamaDateTime * Method: getTimeAsString diff --git a/mama/jni/src/c/mamapublisherjni.c b/mama/jni/src/c/mamapublisherjni.c index 518bacf25..aa1c4c6aa 100644 --- a/mama/jni/src/c/mamapublisherjni.c +++ b/mama/jni/src/c/mamapublisherjni.c @@ -76,40 +76,47 @@ static void MAMACALLTYPE sendCompleteCB (mamaPublisher publisher, /* * Class: com_wombat_mama_MamaPublisher * Method: _create - * Signature: (Lcom/wombat/mama/Transport;Ljava/lang/String;)V + * Signature: (Lcom/wombat/mama/MamaTransport;Ljava/lang/String;Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_wombat_mama_MamaPublisher__1create - (JNIEnv* env, jobject this, jobject transport, jstring topic) + (JNIEnv* env, jobject this, jobject transport, jstring topic, jstring source) { - mamaPublisher cPublisher = NULL; + mamaPublisher cPublisher = NULL; mamaTransport cTransport = NULL; - const char* cTopic = NULL; + const char* cSource = NULL; + const char* cTopic = NULL; jlong transportPointer = 0; mama_status status = MAMA_STATUS_OK; char errorString[UTILS_MAX_ERROR_STRING_LENGTH]; - /*Get the transport pointer*/ assert(transport!=NULL); transportPointer = (*env)->GetLongField(env, transport, transportPointerFieldId_g); + cTransport = CAST_JLONG_TO_POINTER(mamaTransport, transportPointer); - assert(transportPointer!=0); + assert(transportPointer!=0); /*Get the char* from the jstring*/ if(NULL!=topic) { cTopic = (*env)->GetStringUTFChars(env,topic,0); if(!cTopic)return; } - + if(NULL!=source) + { + cSource = (*env)->GetStringUTFChars(env,source,0); + if(!cSource)return; + } + if(MAMA_STATUS_OK!=(mamaPublisher_create( &cPublisher, cTransport, cTopic, - NULL, + cSource, NULL))) { - if(cTopic)(*env)->ReleaseStringUTFChars(env,topic, cTopic); + if(cTopic)(*env)->ReleaseStringUTFChars(env,topic, cTopic); + if(cSource)(*env)->ReleaseStringUTFChars(env,source, cSource); utils_buildErrorStringForStatus( errorString, UTILS_MAX_ERROR_STRING_LENGTH, "Failed to create publisher.", status); @@ -121,6 +128,7 @@ JNIEXPORT void JNICALL Java_com_wombat_mama_MamaPublisher__1create CAST_POINTER_TO_JLONG(cPublisher)); if(cTopic)(*env)->ReleaseStringUTFChars(env,topic, cTopic); + if(cSource)(*env)->ReleaseStringUTFChars(env,source, cSource); return; } diff --git a/mama/jni/src/com/wombat/mama/MamaDateTime.java b/mama/jni/src/com/wombat/mama/MamaDateTime.java index c46ae600f..010b77bde 100644 --- a/mama/jni/src/com/wombat/mama/MamaDateTime.java +++ b/mama/jni/src/com/wombat/mama/MamaDateTime.java @@ -100,8 +100,14 @@ public String toString () return getAsString (); } + public String formatString (String str, + MamaTimeZone tz) + { + return getAsFormattedString (str, (tz!=null ? tz.tz():null)); + } + public int compareTo (Object obj) - { + { // If comparison is not possible this will throw a ClassCastException // which is what the Comparable spec requires. MamaDateTime time = (MamaDateTime) obj; @@ -283,6 +289,9 @@ public double getEpochTimeSeconds (MamaTimeZone tz) public native String getAsString (); + private native String getAsFormattedString (String format, + String tz); + public native String getTimeAsString (); public native String getDateAsString (); diff --git a/mama/jni/src/com/wombat/mama/MamaPublisher.java b/mama/jni/src/com/wombat/mama/MamaPublisher.java index 014694550..ccd39fb9a 100644 --- a/mama/jni/src/com/wombat/mama/MamaPublisher.java +++ b/mama/jni/src/com/wombat/mama/MamaPublisher.java @@ -35,9 +35,14 @@ public class MamaPublisher /*A long value containing a pointer to the underlying C publisher structure*/ private long publisherPointer_i = 0; - public void create (MamaTransport transport, String topic) + public void create (MamaTransport transport, String topic) { - _create(transport,topic); + _create(transport,topic,null); + } + + public void create (MamaTransport transport, String topic, String source) + { + _create(transport,topic,source); } public void send (MamaMsg msg) @@ -76,7 +81,7 @@ public void sendFromInbox (MamaInbox inbox, MamaMsg msg) _sendFromInbox(inbox,msg); } - private native void _create (MamaTransport transport, String topic); + private native void _create (MamaTransport transport, String topic, String source); private native void _send (MamaMsg msg); diff --git a/mama/jni/src/com/wombat/mama/MamaSubscription.java b/mama/jni/src/com/wombat/mama/MamaSubscription.java index 691643492..fc7bbe67c 100644 --- a/mama/jni/src/com/wombat/mama/MamaSubscription.java +++ b/mama/jni/src/com/wombat/mama/MamaSubscription.java @@ -292,13 +292,16 @@ public void setupSubscription( // Save the source in the Java layer to prevent a context switch to C mySource = source; + // Save the closure + myClosure = closure; + // Create the native subscription setupNativeSubscription( callback, queue, source, symbol, - closure); + null); } public void setAppDataType (MamaMdDataType type) diff --git a/mama/jni/src/junittests/Main.java b/mama/jni/src/junittests/Main.java index a12b3a1f9..73e33d920 100644 --- a/mama/jni/src/junittests/Main.java +++ b/mama/jni/src/junittests/Main.java @@ -53,6 +53,7 @@ public static Test suite() suite.addTestSuite(MamaPriceGetRoundedPrice.class); suite.addTestSuite(MamaSetLogCallback.class); suite.addTestSuite(MamaTimerCallbacks.class); + suite.addTestSuite(MamaPublisherTest.class); return suite; } diff --git a/mamda/VERSION.scons b/mamda/VERSION.scons index 52cad72de..822822991 100644 --- a/mamda/VERSION.scons +++ b/mamda/VERSION.scons @@ -1 +1 @@ -mamda 2.3.2 +mamda 2.3.3 diff --git a/mamda/c_cpp/SConscript.win b/mamda/c_cpp/SConscript.win index 4c63b51b2..0a67d4887 100644 --- a/mamda/c_cpp/SConscript.win +++ b/mamda/c_cpp/SConscript.win @@ -113,7 +113,7 @@ if env['with_unittest'] == True: if ( env['with_docs'] == True and not Media.has_key('mamda/c_cpp/docs') and env['build'] == 'dynamic' and not env.GetOption('clean') ): cppdoc = env.Doxygen('doxyconfig-cpp.in') - env.Command( '$prefix/doc/mamda/cpp/html', cppdoc, 'mkdir $TARGET && cp -rf %s\mamda\c_cpp\doc\cpp\html\* $TARGET' % ( env['TOPLEVEL'] ) ) + env.Command( '$prefix/doc/mamda', cppdoc, 'mkdir $TARGET && xcopy /q /s /e /y %s\mamda\c_cpp\doc\* $TARGET' % ( env['TOPLEVEL'] ) ) env.Clean( cppdoc, '%s/mamda/c_cpp/doc/cpp' % (env['TOPLEVEL']) ) diff --git a/mamda/c_cpp/configure.ac b/mamda/c_cpp/configure.ac index 2ec0da01e..58a992adc 100644 --- a/mamda/c_cpp/configure.ac +++ b/mamda/c_cpp/configure.ac @@ -25,8 +25,8 @@ # ################################################## m4_define([product_version_major], [2]) -m4_define([product_version_minor], [2]) -m4_define([product_version_release], [1.1]) +m4_define([product_version_minor], [3]) +m4_define([product_version_release], [3]) m4_define([product_full_version],[product_version_major.product_version_minor.product_version_release]) diff --git a/mamda/c_cpp/src/cpp/generateMamdaVersion.bat b/mamda/c_cpp/src/cpp/generateMamdaVersion.bat index aeb8a88c1..835d4aab5 100644 --- a/mamda/c_cpp/src/cpp/generateMamdaVersion.bat +++ b/mamda/c_cpp/src/cpp/generateMamdaVersion.bat @@ -1,7 +1,7 @@ set BUILD_DIR=%1 set VERSION_MAJOR=2 set VERSION_MINOR=3 -set VERSION_RELEASE=2 +set VERSION_RELEASE=3 echo "generating version files.." diff --git a/mamda/c_cpp/src/cpp/version.c b/mamda/c_cpp/src/cpp/version.c index 822b62068..01008b929 100644 --- a/mamda/c_cpp/src/cpp/version.c +++ b/mamda/c_cpp/src/cpp/version.c @@ -1,2 +1,2 @@ -/* This file was automatically generated */ -const char* mamda_version = "mamda 2.3.2"; +/* This file was automatically generated */ +const char* mamda_version = "mamda 2.3.3"; diff --git a/release/helper-functions.sh b/release_scripts/helper-functions.sh similarity index 100% rename from release/helper-functions.sh rename to release_scripts/helper-functions.sh diff --git a/release/openmama-rpm.sh b/release_scripts/openmama-rpm.sh similarity index 91% rename from release/openmama-rpm.sh rename to release_scripts/openmama-rpm.sh index 191678c9c..96054f886 100755 --- a/release/openmama-rpm.sh +++ b/release_scripts/openmama-rpm.sh @@ -260,8 +260,9 @@ if [ $MOCK_BUILD -eq 1 ] && [ $RETURN_CODE -eq 0 ]; then try cd ${BUILD_DIR}/SRPMS try /usr/bin/mock -r epel-6-i386 --define 'BUILD_VERSION '${VERSION} --define 'BUILD_NUMBER '${BUILD_NUMBER} openmama-${VERSION}-${BUILD_NUMBER}.*.src.rpm > ${BUILD_DIR}/mock-el6-i386.log 2>&1 try /usr/bin/mock -r epel-6-x86_64 --define 'BUILD_VERSION '${VERSION} --define 'BUILD_NUMBER '${BUILD_NUMBER} openmama-${VERSION}-${BUILD_NUMBER}.*.src.rpm > ${BUILD_DIR}/mock-el6-x64.log 2>&1 - try /usr/bin/mock -r fedora-19-x86_64 --define 'BUILD_VERSION '${VERSION} --define 'BUILD_NUMBER '${BUILD_NUMBER} openmama-${VERSION}-${BUILD_NUMBER}.*.src.rpm > ${BUILD_DIR}/mock-f19-x64.log 2>&1 - try /usr/bin/mock -r fedora-20-x86_64 --define 'BUILD_VERSION '${VERSION} --define 'BUILD_NUMBER '${BUILD_NUMBER} openmama-${VERSION}-${BUILD_NUMBER}.*.src.rpm > ${BUILD_DIR}/mock-f20-x64.log 2>&1 + try /usr/bin/mock -r epel-7-x86_64 --define 'BUILD_VERSION '${VERSION} --define 'BUILD_NUMBER '${BUILD_NUMBER} openmama-${VERSION}-${BUILD_NUMBER}.*.src.rpm > ${BUILD_DIR}/mock-el7-x64.log 2>&1 + try /usr/bin/mock -r fedora-21-x86_64 --define 'BUILD_VERSION '${VERSION} --define 'BUILD_NUMBER '${BUILD_NUMBER} openmama-${VERSION}-${BUILD_NUMBER}.*.src.rpm > ${BUILD_DIR}/mock-f21-x64.log 2>&1 + try /usr/bin/mock -r fedora-22-x86_64 --define 'BUILD_VERSION '${VERSION} --define 'BUILD_NUMBER '${BUILD_NUMBER} openmama-${VERSION}-${BUILD_NUMBER}.*.src.rpm > ${BUILD_DIR}/mock-f22-x64.log 2>&1 next RETURN_CODE=$? fi @@ -281,13 +282,13 @@ if [ $PACKAGE_RELEASE -eq 1 ] && [ $RETURN_CODE -eq 0 ]; then # Copy in the Source RPM try cp ${BUILD_DIR}/SRPMS/openmama-${VERSION}-${BUILD_NUMBER}.*.src.rpm ${RELEASE_DIR} - # These paths are hard coded, since they should always remain there. We may - # want to update them periodically, especially with EL7, and newer Fedora - # versions. + # These paths are hard coded, since they should always remain there. We need + # to update these periodically. try cp /var/lib/mock/epel-6-i386/result/openmama-${VERSION}-${BUILD_NUMBER}.el6.i686.rpm ${RELEASE_DIR} try cp /var/lib/mock/epel-6-x86_64/result/openmama-${VERSION}-${BUILD_NUMBER}.el6.x86_64.rpm ${RELEASE_DIR} - try cp /var/lib/mock/fedora-19-x86_64/result/openmama-${VERSION}-${BUILD_NUMBER}.fc19.x86_64.rpm ${RELEASE_DIR} - try cp /var/lib/mock/fedora-20-x86_64/result/openmama-${VERSION}-${BUILD_NUMBER}.fc20.x86_64.rpm ${RELEASE_DIR} + try cp /var/lib/mock/epel-7-x86_64/result/openmama-${VERSION}-${BUILD_NUMBER}.el7.*.x86_64.rpm ${RELEASE_DIR} + try cp /var/lib/mock/fedora-21-x86_64/result/openmama-${VERSION}-${BUILD_NUMBER}.fc21.x86_64.rpm ${RELEASE_DIR} + try cp /var/lib/mock/fedora-22-x86_64/result/openmama-${VERSION}-${BUILD_NUMBER}.fc22.x86_64.rpm ${RELEASE_DIR} # Build and tar the binary release if [ -d ${BUILD_DIR}/binary ]; then diff --git a/release/openmama.spec b/release_scripts/openmama.spec similarity index 96% rename from release/openmama.spec rename to release_scripts/openmama.spec index d5ec35d8a..40ae53bbd 100644 --- a/release/openmama.spec +++ b/release_scripts/openmama.spec @@ -12,8 +12,8 @@ BuildRequires: libtool autoconf automake ant libuuid-devel flex doxygen qpid-pro Requires: libuuid qpid-proton-c libevent ncurses %if 0%{?fedora} -BuildRequires: java-1.7.0-openjdk-devel -Requires: java-1.7.0-openjdk +BuildRequires: java-1.8.0-openjdk-devel +Requires: java-1.8.0-openjdk %define java_home /usr/lib/jvm/java/ %endif diff --git a/site_scons/community/command_line.py b/site_scons/community/command_line.py index e1791e275..1f7f278a0 100644 --- a/site_scons/community/command_line.py +++ b/site_scons/community/command_line.py @@ -26,6 +26,7 @@ def get_command_line_opts( host, products, VERSIONS ): BoolVariable('with_examples','Build with test tools',True), BoolVariable('entitled','Whether the build is entitled or unentitled',False), PathVariable('gtest_home','Path to Google Test home',None, PathVariable.PathIsDir), + PathVariable('junit_home','Path to Junit home',None, PathVariable.PathIsDir), ListVariable('middleware','Middleware(s) to be compiled in', 'avis', names = ['avis', 'qpid'] ), ('jobs', 'Number of scons threads to spawn, if n is passed the number of availabe cores is calculated and used', '1'), @@ -39,7 +40,7 @@ def get_command_line_opts( host, products, VERSIONS ): PathVariable('qpid_home', 'Path to QPID Proton Libraries', 'c:\\proton', PathVariable.PathAccept), EnumVariable('vsver','Visual Studio Version to use', '10.0', - allowed_values=('8.0','9.0','10.0')), + allowed_values=('8.0','9.0','10.0','11.0','12.0')), EnumVariable('product', 'Product to be built', 'mamda', allowed_values=( products )), EnumVariable('dotnet_version', 'Dotnet Version used to determine framework directory', '2.0', @@ -63,6 +64,8 @@ def get_command_line_opts( host, products, VERSIONS ): EnumVariable('product', 'Product to be built', 'mamda', #mamda all is a windows only build allowed_values=( [ x for x in products if x != "mamdaall" ] )), + EnumVariable('target_arch', 'Specifies if the build should target 32 or 64 bit architectures.', + host['arch'], allowed_values=['i386', 'i586', 'i686', 'x86', 'x86_64']), EnumVariable( 'compiler', 'Compiler to use for building OpenMAMA', 'default', allowed_values=('default', 'gcc', 'clang', 'clang-analyzer')), ) diff --git a/site_scons/community/windows.py b/site_scons/community/windows.py index 362f69773..80c241d71 100644 --- a/site_scons/community/windows.py +++ b/site_scons/community/windows.py @@ -64,8 +64,10 @@ def create( selv, opts ): env = Environment(ENV={ 'JAVA_HOME': '%s' % (optsEnv['java_home']), 'PATH': '%s:%s\\bin' % (os.environ['PATH'], optsEnv['java_home']), - 'MSVC_VERSION' : '%s' %(optsEnv['vsver'])}, + }, tools = tools, + MSVC_VERSION = optsEnv['vsver'], + MSVS_VERSION = optsEnv['vsver'], TARGET_ARCH = optsEnv['target_arch']) #ConfigureJNI searches os.env for java_home not env['ENV']['JAVA_HOME'] @@ -78,7 +80,7 @@ def create( selv, opts ): env['JAVAH'] = 'javah' else: - env = Environment(ENV={'PATH': '%s' % (os.environ['PATH'])}, MSVC_VERSION = optsEnv['vsver'], tools = tools, TARGET_ARCH = optsEnv['target_arch']) + env = Environment(ENV={'PATH': '%s' % (os.environ['PATH'])}, MSVC_VERSION = optsEnv['vsver'], MSVS_VERSION = optsEnv['vsver'], tools = tools, TARGET_ARCH = optsEnv['target_arch']) env['SPAWN'] = logger.log_output env['PRINT_CMD_LINE_FUNC'] = logger.log_command @@ -196,7 +198,7 @@ def build(self, env, modules): # Configures all of the appropriate environment variables for windows. def configure(self, env ): env.Append( CPPDEFINES = ['WIN32'] ) - env.Append( CCFLAGS = ['-EHsc','/GR','/FIwombat\\targetsxs.h'] ) + env.Append( CCFLAGS = ['/EHsc','/GR','/FIwombat\\targetsxs.h'] ) env.Append( LINKFLAGS =['/MANIFEST'] ) env.Append( CCPDBFLAGS = '/Fd${TARGET}.pdb' ) env.Append( PDB = '${TARGET.base}.pdb') diff --git a/site_scons/logger.py b/site_scons/logger.py index acb5123f9..59e857f9e 100644 --- a/site_scons/logger.py +++ b/site_scons/logger.py @@ -36,6 +36,13 @@ def log_output( self, sh, escape, cmd, args, env ): if self.opts['verbose'] == True: sys.stderr.write('WARNING:: %s' % (stderr)) self.fd.write('%s\n' % (stderr)) + # Include stdout logs if there are any. This is especially + # helpful in Windows builds where MSVS CL command-line sends + # useful errors/warnings to stdout instead of stderr. + if len(stdout) > 0: + if self.opts['verbose'] == True: + sys.stdout.write('WARNING::stdout: %s' % (stdout)) + self.fd.write('stdout: %s\n' % (stdout)) return p.returncode def log_command(self, s, target, src, env):