void process_flow(ldp_connection_t *conn, pn_event_t *event) { fprintf(stderr, "flow event %s\n", pn_event_type_name(pn_event_type(event))); pn_link_t *sender = pn_event_link(event); pn_message_t *message = pn_message(); pn_message_set_address(message, "amqp://foo/bar"); pn_data_t *body = pn_message_body(message); char *msgtext = "hello world!"; pn_data_put_string(body, pn_bytes(strlen(msgtext), msgtext)); pn_buffer_t *buffer = pn_buffer(1000); char *encoded = pn_buffer_bytes(buffer).start; size_t size = pn_buffer_capacity(buffer); int err = pn_message_encode(message, encoded, &size); if (err) { fprintf(stderr, "trouble encoding message\n"); } else { char tag[8]; static uint64_t next_tag; *((uint64_t*)tag) = ++next_tag; pn_delivery_t *d = pn_delivery(sender, pn_dtag(tag, 8)); pn_link_send(sender, encoded, size); pn_link_advance(sender); } pn_buffer_free(buffer); pn_message_free(message); }
void amqp::Sender::_serializeMessageMeta(pn_data_t *pndata, std::shared_ptr<amqp::IAMQPData> const &data) { switch (data->getDataType()) { case IAMQPData::AMQP_STRING: pn_data_put_string(pndata, (std::dynamic_pointer_cast<AMQPString const>(data))->getString()); break; case IAMQPData::AMQP_SYMBOL: pn_data_put_symbol(pndata, (std::dynamic_pointer_cast<AMQPSymbol const>(data))->getSymbol()); break; case IAMQPData::AMQP_UUID: pn_data_put_uuid(pndata, (std::dynamic_pointer_cast<AMQPuuid const>(data))->getUUID()); break; default: throw std::exception("ERROR: wrong data type"); } }
void qpidBridgePublisherImpl_setMessageType (pn_message_t* message, qpidMsgType type) { /* Get the properties */ pn_data_t* properties = pn_message_properties (message); /* Ensure position is at the start */ pn_data_rewind (properties); /* Container for application properties is a map */ pn_data_put_map(properties); pn_data_enter(properties); /* Add the type */ pn_data_put_string(properties,pn_bytes(strlen(QPID_KEY_MSGTYPE),QPID_KEY_MSGTYPE)); pn_data_put_ubyte(properties,type); pn_data_exit (properties); return; }
mama_status qpidBridgeMsgCodec_pack (msgBridge bridgeMessage, mamaMsg target, pn_message_t** protonMessage) { pn_data_t* properties = NULL; pn_data_t* body = NULL; mamaPayloadType payloadType = MAMA_PAYLOAD_UNKNOWN; const void* buffer = NULL; mama_size_t bufferLen = 0; char* subject = NULL; char* destination = NULL; char* inboxName = NULL; char* replyTo = NULL; char* targetSubject = NULL; mama_status status = MAMA_STATUS_OK; qpidMsgType type = QPID_MSG_PUB_SUB; if (NULL == bridgeMessage || NULL == target) { return MAMA_STATUS_NULL_ARG; } /* Get the underlying payload type */ mamaMsg_getPayloadType (target, &payloadType); /* If this is a qpid payload, we don't need to serialize */ if (MAMA_PAYLOAD_QPID == payloadType) { /* This will extract only the underlying handle */ mamaMsgImpl_getPayloadBuffer (target, &buffer, &bufferLen); /* Don't use function's proton message - use the one just extracted */ *protonMessage = (pn_message_t*) buffer; } else { const void* buffer = NULL; mama_size_t bufferLen = 0; /* This will extract a serialized version of the payload */ mamaMsg_getByteBuffer (target, &buffer, &bufferLen); /* Use the function's proton message if this is not a qpid payload */ body = pn_message_body (*protonMessage); pn_data_put_binary (body, pn_bytes(bufferLen, (char*)buffer)); } /* Set the subject for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getSendSubject (bridgeMessage, &subject); if (MAMA_STATUS_OK != status) { return status; } pn_message_set_subject (*protonMessage, subject); /* Set the URL destination for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getDestination (bridgeMessage, &destination); if (MAMA_STATUS_OK != status) { return status; } pn_message_set_address (*protonMessage, destination); /* Get the properties from the message */ properties = pn_message_properties (*protonMessage); /* Ensure position is at the start */ pn_data_rewind (properties); /* Main container for meta data should be a list to allow expansion */ pn_data_put_list (properties); /* Enter into the list for access to its elements */ pn_data_enter (properties); /* Set the message type for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getMsgType (bridgeMessage, &type); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_ubyte (properties, type); switch (type) { /* For inbox requests, set inbox name and reply to URLs */ case QPID_MSG_INBOX_REQUEST: status = qpidBridgeMamaMsgImpl_getInboxName (bridgeMessage, &inboxName); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(inboxName), inboxName)); status = qpidBridgeMamaMsgImpl_getReplyTo (bridgeMessage, &replyTo); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(replyTo), replyTo)); break; /* For inbox responses, set the target subject (e.g. initial for XX) */ case QPID_MSG_INBOX_RESPONSE: status = qpidBridgeMamaMsgImpl_getTargetSubject (bridgeMessage, &targetSubject); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(targetSubject), targetSubject)); 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; } /* Exit out of the list previously entered */ pn_data_exit (properties); return MAMA_STATUS_OK; }
int main(int argc, char** argv) { Options_t opts; int rc; pn_message_t *response_msg = pn_message(); check( response_msg, "Failed to allocate a Message"); pn_message_t *request_msg = pn_message(); check( request_msg, "Failed to allocate a Message"); pn_messenger_t *messenger = pn_messenger( 0 ); check( messenger, "Failed to allocate a Messenger"); parse_options( argc, argv, &opts ); // no need to track outstanding messages pn_messenger_set_outgoing_window( messenger, 0 ); pn_messenger_set_incoming_window( messenger, 0 ); pn_messenger_set_timeout( messenger, opts.timeout ); if (opts.gateway_addr) { LOG( "routing all messages via %s\n", opts.gateway_addr ); rc = pn_messenger_route( messenger, "*", opts.gateway_addr ); check( rc == 0, "pn_messenger_route() failed" ); } pn_messenger_start(messenger); char *reply_to = NULL; if (opts.reply_to) { LOG("subscribing to %s for replies\n", opts.reply_to); pn_messenger_subscribe(messenger, opts.reply_to); reply_to = _strdup(opts.reply_to); check( reply_to, "Out of memory" ); #if 1 // need to 'fix' the reply-to for use in the message itself: // no '~' is allowed in that case char *tilde = strstr( reply_to, "://~" ); if (tilde) { tilde += 3; // overwrite '~' memmove( tilde, tilde + 1, strlen( tilde + 1 ) + 1 ); } #endif } // Create a request message // const char *command = opts.new_fortune ? "set" : "get"; build_request_message( request_msg, opts.send_bad_msg ? "bad-command" : command, opts.address, reply_to, opts.new_fortune, opts.ttl ); // set a unique identifier for this message, so remote can // de-duplicate when we re-transmit uuid_t uuid; uuid_generate(uuid); char uuid_str[37]; uuid_unparse_upper(uuid, uuid_str); pn_data_put_string( pn_message_id( request_msg ), pn_bytes( sizeof(uuid_str), uuid_str )); // set the correlation id so we can ensure the response matches // our request. (re-use uuid just 'cause it's easy!) pn_data_put_string( pn_message_correlation_id( request_msg ), pn_bytes( sizeof(uuid_str), uuid_str )); int send_count = 0; bool done = false; // keep re-transmitting until something arrives do { LOG("sending request message...\n"); rc = pn_messenger_put( messenger, request_msg ); check(rc == 0, "pn_messenger_put() failed"); send_count++; if (opts.retry) opts.retry--; LOG("waiting for response...\n"); rc = pn_messenger_recv( messenger, -1 ); if (rc == PN_TIMEOUT) { LOG( "Timed-out waiting for a response, retransmitting...\n" ); pn_message_set_delivery_count( request_msg, send_count ); } else { check(rc == 0, "pn_messenger_recv() failed\n"); while (pn_messenger_incoming( messenger ) > 0) { rc = pn_messenger_get( messenger, response_msg ); check(rc == 0, "pn_messenger_get() failed"); LOG("response received!\n"); // validate the correlation id pn_bytes_t cid = pn_data_get_string( pn_message_correlation_id( response_msg ) ); if (cid.size == 0 || strncmp( uuid_str, cid.start, cid.size )) { LOG( "Correlation Id mismatch! Ignoring this response!\n" ); } else { process_reply( messenger, response_msg ); done = true; } } } } while (!done && opts.retry); if (!done) { fprintf( stderr, "Retries exhausted, no response received from server!\n" ); } rc = pn_messenger_stop(messenger); check(rc == 0, "pn_messenger_stop() failed"); pn_messenger_free(messenger); pn_message_free( response_msg ); pn_message_free( request_msg ); if (reply_to) free(reply_to); return 0; }
mama_status qpidBridgeMamaSubscription_create (subscriptionBridge* subscriber, const char* source, const char* symbol, mamaTransport tport, mamaQueue queue, mamaMsgCallbacks callback, mamaSubscription subscription, void* closure) { qpidSubscription* impl = NULL; qpidTransportBridge* transport = NULL; mama_status status = MAMA_STATUS_OK; pn_data_t* data = NULL; if ( NULL == subscriber || NULL == subscription || NULL == tport ) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaSubscription_create(): something NULL"); return MAMA_STATUS_NULL_ARG; } status = mamaTransport_getBridgeTransport (tport, (transportBridge*) &transport); if (MAMA_STATUS_OK != status || NULL == transport) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaSubscription_create(): something NULL"); return MAMA_STATUS_NULL_ARG; } /* Allocate memory for qpid subscription implementation */ impl = (qpidSubscription*) calloc (1, sizeof (qpidSubscription)); if (NULL == impl) { return MAMA_STATUS_NOMEM; } mamaQueue_getNativeHandle(queue, &impl->mQpidQueue); impl->mMamaCallback = callback; impl->mMamaSubscription = subscription; impl->mMamaQueue = queue; impl->mTransport = (mamaTransport)transport; impl->mSymbol = symbol; impl->mClosure = closure; impl->mIsNotMuted = 1; impl->mIsTportDisconnected = 1; impl->mSubjectKey = NULL; /* Use a standard centralized method to determine a topic key */ qpidBridgeMamaSubscriptionImpl_generateSubjectKey (NULL, source, symbol, &impl->mSubjectKey); /* Register the endpoint */ endpointPool_registerWithoutIdentifier (transport->mSubEndpoints, impl->mSubjectKey, &impl->mEndpointIdentifier, impl); /* Notify the publisher that you have an interest in this topic */ pn_message_clear (transport->mMsg); /* Set the message meta data to reflect a subscription request */ qpidBridgePublisherImpl_setMessageType (transport->mMsg, QPID_MSG_SUB_REQUEST); /* Set the outgoing address as provided by the transport configuration */ pn_message_set_address (transport->mMsg, transport->mOutgoingAddress); /* Set the reply address */ pn_message_set_reply_to (transport->mMsg, transport->mReplyAddress); /* Get the proton message's body data for writing */ data = pn_message_body (transport->mMsg); /* Add in the subject key as the only string inside */ pn_data_put_string (data, pn_bytes (strlen (impl->mSubjectKey), impl->mSubjectKey)); /* Send out the subscription registration of interest message */ if (NULL != transport->mOutgoingAddress) { pn_messenger_put (transport->mOutgoing, transport->mMsg); if (0 != PN_MESSENGER_SEND (transport->mOutgoing)) { const char* qpid_error = PN_MESSENGER_ERROR (transport->mOutgoing); mama_log (MAMA_LOG_LEVEL_SEVERE, "qpidBridgeMamaSubscription_create(): " "pn_messenger_send Error:[%s]", qpid_error); return MAMA_STATUS_PLATFORM; } } mama_log (MAMA_LOG_LEVEL_FINEST, "qpidBridgeMamaSubscription_create(): " "created interest for %s.", impl->mSubjectKey); /* Mark this subscription as valid */ impl->mIsValid = 1; *subscriber = (subscriptionBridge) impl; return MAMA_STATUS_OK; }