mama_status zmqBridgeMamaMsgImpl_deserialize (msgBridge msg, const void* source, mama_size_t size, mamaMsg target) { zmqBridgeMsgImpl* impl = (zmqBridgeMsgImpl*) msg; uint8_t* bufferPos = (uint8_t*)source; // Skip past the subject - don't care about that here bufferPos += strlen((char*)source) + 1; // Leave 8 bytes empty - receive side will be thankful for them memset ((void*)bufferPos, 0, 8); bufferPos += 8; // Set the message type impl->mMsgType = (zmqMsgType) *bufferPos; bufferPos++; switch (impl->mMsgType) { case ZMQ_MSG_INBOX_REQUEST: zmqBridgeMamaMsgImpl_setStringValue (impl->mReplyHandle.mInboxName, (const char*)bufferPos); bufferPos += strlen (impl->mReplyHandle.mInboxName) + 1; break; case ZMQ_MSG_INBOX_RESPONSE: zmqBridgeMamaMsgImpl_setStringValue (impl->mTargetSubject, (const char*)bufferPos); bufferPos += strlen (impl->mTargetSubject) + 1; break; case ZMQ_MSG_SUB_REQUEST: case ZMQ_MSG_PUB_SUB: default: break; } // Parse the payload into a MAMA Message size_t payloadSize = size - (bufferPos - (uint8_t*)source); mama_log (MAMA_LOG_LEVEL_FINER, "zmqBridgeMamaMsgImpl_deserialize(): " "Received %lu bytes [payload=%lu; type=%d]", size, payloadSize, impl->mMsgType); mama_status status = mamaMsgImpl_setMsgBuffer (target, (void*) bufferPos, payloadSize, *bufferPos); return status; }
/** * Called when message removed from queue by dispatch thread * * @param data The Avis Attributes* clone (must be freed) * @param closure The subscriber */ static void MAMACALLTYPE avis_queue_callback (void* data, void* closure) { mama_status status; mamaMsg tmpMsg; msgBridge bridgeMsg; /* cant do anything without a subscriber */ if (!avisSub(closure)) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): called with NULL subscriber!"); return; } /*Make sure that the subscription is processing messages*/ if ((!avisSub(closure)->mIsNotMuted) || (!avisSub(closure)->mIsValid)) return; /*This is the reuseable message stored on the associated MamaQueue*/ tmpMsg = mamaQueueImpl_getMsg(avisSub(closure)->mQueue); if (!tmpMsg) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): " "Could not get cached mamaMsg from event queue."); return; } /*Get the bridge message from the mamaMsg*/ if (MAMA_STATUS_OK!=(status=mamaMsgImpl_getBridgeMsg (tmpMsg, &bridgeMsg))) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): " "Could not get bridge message from cached" " queue mamaMsg [%d]", status); return; } /*Set the buffer and the reply handle on the bridge message structure*/ avisBridgeMamaMsgImpl_setAttributesAndSecure (bridgeMsg, data, 0); if (MAMA_STATUS_OK!=(status=mamaMsgImpl_setMsgBuffer (tmpMsg, data, 0, MAMA_PAYLOAD_AVIS))) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): mamaMsgImpl_setMsgBuffer() failed. [%d]", status); return; } /*Process the message as normal*/ if (MAMA_STATUS_OK != (status=mamaSubscription_processMsg (avisSub(closure)->mMamaSubscription, tmpMsg))) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): " "mamaSubscription_processMsg() failed. [%d]", status); } attributes_free ((Attributes*)data); free ((Attributes*)data); }
mama_status qpidBridgeMsgCodec_unpack (msgBridge bridgeMessage, mamaMsg target, pn_message_t* protonMessage) { pn_data_t* properties = NULL; pn_data_t* body = NULL; mama_status status = MAMA_STATUS_OK; qpidMsgType type = QPID_MSG_PUB_SUB; pn_bytes_t prop; pn_atom_t firstAtom; if (NULL == bridgeMessage || NULL == protonMessage) { return MAMA_STATUS_NULL_ARG; } /* grab the body */ body = pn_message_body (protonMessage); /* Ensure position is at the start */ pn_data_rewind (body); /* Skip over the initial null atom */ pn_data_next (body); /* Grab the first atom and see what it is - PN_LIST = qpid */ firstAtom = pn_data_get_atom (body); /* If this is a proton message */ if (PN_LIST == firstAtom.type) { status = mamaMsgImpl_setMsgBuffer (target, (void*) protonMessage, sizeof (pn_message_t*), MAMA_PAYLOAD_QPID); } /* If this looks like another MAMA payload type */ else if (PN_BINARY == firstAtom.type) { mamaPayloadType payloadType = MAMA_PAYLOAD_UNKNOWN; if (firstAtom.u.as_bytes.size == 0) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Binary blob of zero length found - not processing"); return MAMA_STATUS_INVALID_ARG; } /* The payload type is the first character */ payloadType = (mamaPayloadType) firstAtom.u.as_bytes.start[0]; /* Use byte buffer to populate MAMA message */ status = mamaMsgImpl_setMsgBuffer ( target, (void*) firstAtom.u.as_bytes.start, (mama_size_t) firstAtom.u.as_bytes.size, payloadType); if (MAMA_STATUS_OK != status) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Could not set msg buffer. Cannot unpack (%s).", mamaStatus_stringForStatus (status)); return status; } } /* If this looks like something we cannot handle */ else { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Unable to unpack data received: incompatible format %s", pn_type_name (firstAtom.type)); } /* Get the properties */ properties = pn_message_properties (protonMessage); /* Ensure position is at the start */ pn_data_rewind (properties); /* Skip over the initial null atom */ pn_data_next (properties); /* Main container should be a list to allow expansion */ pn_data_get_list (properties); pn_data_enter (properties); /* Get the message type out */ pn_data_next (properties); type = (qpidMsgType) pn_data_get_ubyte (properties); qpidBridgeMamaMsgImpl_setMsgType (bridgeMessage, type); switch (type) { case QPID_MSG_INBOX_REQUEST: /* Move onto inbox name and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setInboxName (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } /* Move onto reply to url and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setReplyTo (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } break; case QPID_MSG_INBOX_RESPONSE: /* Move onto target subject and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setTargetSubject (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } break; /* The following message types require no further meta data */ case QPID_MSG_TERMINATE: case QPID_MSG_SUB_REQUEST: case QPID_MSG_PUB_SUB: default: break; } pn_data_exit (properties); return status; }
/** * Called when message removed from queue by dispatch thread * * @param data The Avis Attributes* clone (must be freed) * @param closure The subscriber */ static void MAMACALLTYPE avis_queue_callback (mamaQueue queue, void* closure) { mama_status status = MAMA_STATUS_OK; mamaMsg tmpMsg = NULL; msgBridge bridgeMsg = NULL; const void* buf = NULL; mama_size_t bufSize = 0; avisCallbackContext* ctx = (avisCallbackContext*) closure; void* data = ctx->attributes; void* subscriber = ctx->subscriber; /* cant do anything without a subscriber */ if (!subscriber) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): called with NULL subscriber!"); attributes_destroy (data); free (ctx); return; } /*Make sure that the subscription is processing messages*/ if ((!avisSub(subscriber)->mIsNotMuted) || (!avisSub(subscriber)->mIsValid)) { attributes_destroy (data); free (ctx); return; } /*This is the reuseable message stored on the associated MamaQueue*/ tmpMsg = mamaQueueImpl_getMsg(avisSub(subscriber)->mQueue); if (!tmpMsg) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): " "Could not get cached mamaMsg from event queue."); attributes_destroy (data); free (ctx); return; } /*Get the bridge message from the mamaMsg*/ if (MAMA_STATUS_OK!=(status=mamaMsgImpl_getBridgeMsg (tmpMsg, &bridgeMsg))) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): " "Could not get bridge message from cached" " queue mamaMsg [%d]", status); attributes_destroy (data); free (ctx); return; } /*Set the buffer and the reply handle on the bridge message structure*/ if (MAMA_STATUS_OK!=(status=mamaMsgImpl_setMsgBuffer (tmpMsg, data, 0, MAMA_PAYLOAD_AVIS))) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): mamaMsgImpl_setMsgBuffer() failed. [%d]", status); attributes_destroy (data); free (ctx); return; } if (MAMA_STATUS_OK == mamaMsg_getOpaque ( tmpMsg, ENCLOSED_MSG_FIELD_NAME, 0, &buf, &bufSize) && bufSize > 0) { mamaMsg encMsg = NULL; mamaBridgeImpl* bridge = mamaSubscription_getBridgeImpl (avisSub(subscriber)->mMamaSubscription); status = mamaMsg_createFromByteBuffer (&encMsg, buf, bufSize); if (MAMA_STATUS_OK != status) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): " "Could not create message from enclosed byte buffer. [%d]", status); attributes_destroy (data); free (ctx); return; } mamaMsgImpl_useBridgePayload (encMsg, bridge); mamaMsgImpl_getBridgeMsg (encMsg, &bridgeMsg); /*Set the buffer and the reply handle on the bridge message structure*/ avisBridgeMamaMsgImpl_setAttributesAndSecure (bridgeMsg, data, 0); if (gMamaLogLevel >= MAMA_LOG_LEVEL_FINEST) { mama_log (MAMA_LOG_LEVEL_FINEST, "avis_callback(): " "Received enclosed message: %s", mamaMsg_toString (encMsg)); } if (MAMA_STATUS_OK != (status=mamaSubscription_processMsg (avisSub(subscriber)->mMamaSubscription, encMsg))) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): " "mamaSubscription_processMsg() failed. [%d]", status); } mamaMsg_destroy (encMsg); } else { avisBridgeMamaMsgImpl_setAttributesAndSecure (bridgeMsg, data, 0); if (gMamaLogLevel >= MAMA_LOG_LEVEL_FINEST) { mama_log (MAMA_LOG_LEVEL_FINEST, "avis_callback(): " "Received message: %s", mamaMsg_toString (tmpMsg)); } /*Process the message as normal*/ if (MAMA_STATUS_OK != (status=mamaSubscription_processMsg (avisSub(subscriber)->mMamaSubscription, tmpMsg))) { mama_log (MAMA_LOG_LEVEL_ERROR, "avis_callback(): " "mamaSubscription_processMsg() failed. [%d]", status); } } free (ctx); }