/// <summary> /// Dequeues the next RAW message from the specified queue. /// </summary> /// <param name="queue"></param> /// <param name="options"></param> /// <param name="logger"></param> /// <returns></returns> public static async Task <OracleAQMessage> DequeueRawAsync( OracleAQQueue queue, OracleAQDequeueOptions options, OracleLogger logger, CancellationToken cancellationToken) { throw new NotImplementedException(); }
/// <summary> /// Dequeues the given number of XML messages. /// </summary> /// <param name="queue"></param> /// <param name="options"></param> /// <param name="count"></param> /// <param name="logger"></param> /// <returns></returns> public static async Task <OracleAQMessage[]> DequeueXmlArrayAsync( OracleAQQueue queue, OracleAQDequeueOptions options, int count, OracleLogger logger, CancellationToken cancellationToken) { throw new NotImplementedException(); }
/// <summary> /// This instance method dequeues multiple messages from a queue using the supplied dequeue options. /// </summary> /// <param name="count"></param> /// <param name="options"></param> public Task <OracleAQMessage[]> DequeueArrayAsync(int count, OracleAQDequeueOptions options, CancellationToken cancellationToken = default) { switch (MessageType) { case OracleAQMessageType.Raw: return(OracleAQQueueUtil.DequeueRawArrayAsync(this, options, count, log, cancellationToken)); case OracleAQMessageType.UDT: return(OracleAQQueueUtil.DequeueUdtArrayAsync(this, options, count, log, cancellationToken)); case OracleAQMessageType.Xml: return(OracleAQQueueUtil.DequeueXmlArrayAsync(this, options, count, log, cancellationToken)); default: throw new InvalidOperationException(); } }
/// <summary> /// This instance method dequeues multiple messages from a queue using the supplied dequeue options. /// </summary> /// <param name="count"></param> /// <param name="options"></param> public OracleAQMessage[] DequeueArray(int count, OracleAQDequeueOptions options, CancellationToken cancellationToken = default) { return(OracleAQQueueUtil.DequeueUdtArrayAsync(this, options, count, log, cancellationToken).Result); }
/// <summary> /// This instance method dequeues messages from a queue using the supplied dequeue options. /// </summary> /// <param name="options"></param> public OracleAQMessage Dequeue(OracleAQDequeueOptions options, CancellationToken cancellationToken = default) { return(DequeueAsync(options, cancellationToken).Result); }
/// <summary> /// Dequeues the next UDT message from the specified queue. /// </summary> /// <param name="connection"></param> /// <param name="queue"></param> /// <param name="options"></param> /// <param name="log"></param> /// <returns></returns> public static async Task <OracleAQMessage> DequeueUdtAsync( OracleAQQueue queue, OracleAQDequeueOptions options, OracleLogger log, CancellationToken cancellationToken) { if (queue == null) { throw new ArgumentNullException(nameof(queue)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } if (log == null) { throw new ArgumentNullException(nameof(log)); } // fetch UDT type information var payloadType = await queue.GetPayloadTypeAsync(); if (payloadType == null) { throw new NullReferenceException("Unable to fetch message payload type."); } using (var cmd = queue.Connection.CreateCommand()) { cmd.BindByName = true; cmd.CommandType = CommandType.Text; cmd.CommandText = $@" DECLARE dequeue_options DBMS_AQ.dequeue_options_t; message_id RAW(16); message_properties DBMS_AQ.message_properties_t; message_payload {payloadType}; no_messages exception; PRAGMA EXCEPTION_INIT (no_messages, -25228); BEGIN dequeue_options.consumer_name := :dequeue_options__consumer_name; dequeue_options.dequeue_mode := {FormatDequeueMode(options.DequeueMode)}; dequeue_options.navigation := {FormatNavigationMode(options.NavigationMode)}; dequeue_options.visibility := {FormatVisibility(options.Visibility)}; dequeue_options.wait := {FormatWait(options.Wait)}; dequeue_options.correlation := :dequeue_options__correlation; DBMS_AQ.DEQUEUE( queue_name => :queue_name, dequeue_options => dequeue_options, message_properties => message_properties, payload => message_payload, msgid => message_id); :message_count := 1; :message_id := message_id; SELECT XMLELEMENT(MESSAGE, XMLELEMENT(PRIORITY, message_properties.priority), XMLELEMENT(DELAY, message_properties.delay), XMLELEMENT(EXPIRATION, message_properties.expiration), XMLELEMENT(CORRELATION, message_properties.correlation), XMLELEMENT(ATTEMPTS, message_properties.attempts), -- XMLELEMENT(RECIPIENT_LIST, message_properties.recipient_list), XMLELEMENT(EXCEPTION_QUEUE, message_properties.exception_queue), XMLELEMENT(ENQUEUE_TIME, message_properties.enqueue_time), XMLELEMENT(STATE, message_properties.state), XMLELEMENT(SENDER_ID, message_properties.sender_id), XMLELEMENT(ORIGINAL_MSGID, message_properties.original_msgid), XMLELEMENT(SIGNATURE, message_properties.signature), XMLELEMENT(TRANSACTION_GROUP, message_properties.transaction_group), XMLELEMENT(USER_PROPERTY, message_properties.user_property), XMLELEMENT(DELIVERY_MODE, message_properties.delivery_mode)) INTO :message_properties FROM DUAL; IF message_payload IS NOT NULL THEN :message_payload := XMLTYPE(message_payload); ELSE :message_payload := NULL; END IF; EXCEPTION WHEN no_messages THEN :message_count := 0; END;"; var dequeueOptionsConsumerNameParameter = cmd.CreateParameter(); dequeueOptionsConsumerNameParameter.ParameterName = ":dequeue_options__consumer_name"; dequeueOptionsConsumerNameParameter.OracleDbType = OracleDbType.Varchar2; dequeueOptionsConsumerNameParameter.Direction = ParameterDirection.Input; dequeueOptionsConsumerNameParameter.Value = options.ConsumerName; cmd.Parameters.Add(dequeueOptionsConsumerNameParameter); var dequeueOptionsCorrelationParameter = cmd.CreateParameter(); dequeueOptionsCorrelationParameter.ParameterName = ":dequeue_options__correlation"; dequeueOptionsCorrelationParameter.OracleDbType = OracleDbType.Varchar2; dequeueOptionsCorrelationParameter.Direction = ParameterDirection.Input; dequeueOptionsCorrelationParameter.Value = options.Correlation; cmd.Parameters.Add(dequeueOptionsCorrelationParameter); var queueNameParameter = cmd.CreateParameter(); queueNameParameter.ParameterName = ":queue_name"; queueNameParameter.OracleDbType = OracleDbType.Varchar2; queueNameParameter.Direction = ParameterDirection.Input; queueNameParameter.Value = queue.Name; cmd.Parameters.Add(queueNameParameter); var messageIdParameter = cmd.CreateParameter(); messageIdParameter.ParameterName = ":message_id"; messageIdParameter.Direction = ParameterDirection.Output; messageIdParameter.Size = 16; messageIdParameter.OracleDbType = OracleDbType.Raw; cmd.Parameters.Add(messageIdParameter); var messagePropertiesParameter = cmd.CreateParameter(); messagePropertiesParameter.ParameterName = ":message_properties"; messagePropertiesParameter.Direction = ParameterDirection.Output; messagePropertiesParameter.OracleDbType = OracleDbType.XmlType; cmd.Parameters.Add(messagePropertiesParameter); var messagePayloadParameter = cmd.CreateParameter(); messagePayloadParameter.ParameterName = ":message_payload"; messagePayloadParameter.Direction = ParameterDirection.Output; messagePayloadParameter.OracleDbType = OracleDbType.XmlType; cmd.Parameters.Add(messagePayloadParameter); var messageCountParameter = cmd.CreateParameter(); messageCountParameter.ParameterName = ":message_count"; messageCountParameter.Direction = ParameterDirection.Output; messageCountParameter.OracleDbType = OracleDbType.Decimal; cmd.Parameters.Add(messageCountParameter); log.Debug(cmd.CommandText); await cmd.ExecuteNonQueryAsync(cancellationToken); // parses the result into the set of messages return(((OracleDecimal)messageCountParameter.Value).ToInt32() == 1 ? ReadUdtMessage( payloadType, ((OracleBinary)messageIdParameter.Value).Value, ((OracleXmlType)messagePropertiesParameter.Value).Value, ((OracleXmlType)messagePayloadParameter.Value).Value) : null); } }
/// <summary> /// Dequeues the given number of UDT messages. /// </summary> /// <param name="connection"></param> /// <param name="queue"></param> /// <param name="options"></param> /// <param name="log"></param> /// <returns></returns> public static async Task <OracleAQMessage[]> DequeueUdtArrayAsync( OracleAQQueue queue, OracleAQDequeueOptions options, int count, OracleLogger log, CancellationToken cancellationToken) { if (queue == null) { throw new ArgumentNullException(nameof(queue)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } if (log == null) { throw new ArgumentNullException(nameof(log)); } // fetch UDT type information var payloadType = await queue.GetPayloadTypeAsync(); if (payloadType == null) { throw new NullReferenceException("Unable to fetch message payload type."); } var payloadArrayType = await queue.GetPayloadArrayTypeAsync(); if (payloadArrayType == null) { throw new OracleAQException("Unable to find message payload array type. Required for batch sizes of more than one."); } using (var cmd = queue.Connection.CreateCommand()) { cmd.BindByName = true; cmd.CommandType = CommandType.Text; cmd.CommandText = $@" DECLARE dequeue_options DBMS_AQ.DEQUEUE_OPTIONS_T; message_id_array DBMS_AQ.MSGID_ARRAY_T; message_properties_array DBMS_AQ.MESSAGE_PROPERTIES_ARRAY_T; message_payload_array {payloadArrayType}; message_count PLS_INTEGER; message_id RAW(16); message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; message_payload {payloadType}; no_messages exception; PRAGMA EXCEPTION_INIT (no_messages, -25228); BEGIN message_id_array := DBMS_AQ.MSGID_ARRAY_T(); message_properties_array := DBMS_AQ.MESSAGE_PROPERTIES_ARRAY_T(); message_payload_array := {payloadArrayType}(); dequeue_options.consumer_name := :dequeue_options__consumer_name; dequeue_options.dequeue_mode := {FormatDequeueMode(options.DequeueMode)}; dequeue_options.navigation := {FormatNavigationMode(options.NavigationMode)}; dequeue_options.visibility := {FormatVisibility(options.Visibility)}; dequeue_options.wait := {FormatWait(options.Wait)}; dequeue_options.correlation := :dequeue_options__correlation; message_count := DBMS_AQ.DEQUEUE_ARRAY( queue_name => :queue_name, dequeue_options => dequeue_options, array_size => :count, message_properties_array => message_properties_array, payload_array => message_payload_array, msgid_array => message_id_array); -- return number of retrieved messages :message_count := message_count; -- copy data to output structures FOR idx IN 1..message_count LOOP message_id := message_id_array(idx); message_properties := message_properties_array(idx); message_payload := message_payload_array(idx); :message_id(idx) := message_id; SELECT XMLELEMENT(MESSAGE, XMLELEMENT(PRIORITY, message_properties.priority), XMLELEMENT(DELAY, message_properties.delay), XMLELEMENT(EXPIRATION, message_properties.expiration), XMLELEMENT(CORRELATION, message_properties.correlation), XMLELEMENT(ATTEMPTS, message_properties.attempts), -- XMLELEMENT(RECIPIENT_LIST, message_properties.recipient_list), XMLELEMENT(EXCEPTION_QUEUE, message_properties.exception_queue), XMLELEMENT(ENQUEUE_TIME, message_properties.enqueue_time), XMLELEMENT(STATE, message_properties.state), XMLELEMENT(SENDER_ID, message_properties.sender_id), XMLELEMENT(ORIGINAL_MSGID, message_properties.original_msgid), XMLELEMENT(SIGNATURE, message_properties.signature), XMLELEMENT(TRANSACTION_GROUP, message_properties.transaction_group), XMLELEMENT(USER_PROPERTY, message_properties.user_property), XMLELEMENT(DELIVERY_MODE, message_properties.delivery_mode)).getClobVal() INTO :message_properties(idx) FROM DUAL; IF message_payload IS NOT NULL THEN :message_payload(idx) := XMLTYPE(message_payload).getClobVal(); ELSE :message_payload(idx) := NULL; END IF; END LOOP; EXCEPTION WHEN no_messages THEN :message_count := 0; END;"; var dequeueOptionsConsumerNameParameter = cmd.CreateParameter(); dequeueOptionsConsumerNameParameter.ParameterName = ":dequeue_options__consumer_name"; dequeueOptionsConsumerNameParameter.OracleDbType = OracleDbType.Varchar2; dequeueOptionsConsumerNameParameter.Direction = ParameterDirection.Input; dequeueOptionsConsumerNameParameter.Value = options.ConsumerName; cmd.Parameters.Add(dequeueOptionsConsumerNameParameter); var dequeueOptionsCorrelationParameter = cmd.CreateParameter(); dequeueOptionsCorrelationParameter.ParameterName = ":dequeue_options__correlation"; dequeueOptionsCorrelationParameter.OracleDbType = OracleDbType.Varchar2; dequeueOptionsCorrelationParameter.Direction = ParameterDirection.Input; dequeueOptionsCorrelationParameter.Value = options.Correlation; cmd.Parameters.Add(dequeueOptionsCorrelationParameter); var queueNameParameter = cmd.CreateParameter(); queueNameParameter.ParameterName = ":queue_name"; queueNameParameter.OracleDbType = OracleDbType.Varchar2; queueNameParameter.Direction = ParameterDirection.Input; queueNameParameter.Value = queue.Name; cmd.Parameters.Add(queueNameParameter); var countParameter = cmd.CreateParameter(); countParameter.ParameterName = ":count"; countParameter.OracleDbType = OracleDbType.Int32; countParameter.Direction = ParameterDirection.Input; countParameter.Value = count; cmd.Parameters.Add(countParameter); var messageIdParameter = cmd.CreateParameter(); messageIdParameter.ParameterName = ":message_id"; messageIdParameter.Direction = ParameterDirection.Output; messageIdParameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray; messageIdParameter.Size = count; messageIdParameter.OracleDbType = OracleDbType.Raw; messageIdParameter.Value = new OracleBinary[count]; messageIdParameter.ArrayBindSize = Enumerable.Range(0, count).Select(i => 16).ToArray(); cmd.Parameters.Add(messageIdParameter); var messagePropertiesParameter = cmd.CreateParameter(); messagePropertiesParameter.ParameterName = ":message_properties"; messagePropertiesParameter.Direction = ParameterDirection.Output; messagePropertiesParameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray; messagePropertiesParameter.Size = count; messagePropertiesParameter.OracleDbType = OracleDbType.Varchar2; messagePropertiesParameter.Value = new OracleString[count]; messagePropertiesParameter.ArrayBindSize = Enumerable.Range(0, count).Select(i => 1024 * 64).ToArray(); cmd.Parameters.Add(messagePropertiesParameter); var messagePayloadParameter = cmd.CreateParameter(); messagePayloadParameter.ParameterName = ":message_payload"; messagePayloadParameter.Direction = ParameterDirection.Output; messagePayloadParameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray; messagePayloadParameter.Size = count; messagePayloadParameter.OracleDbType = OracleDbType.Varchar2; messagePayloadParameter.Value = new OracleString[count]; messagePayloadParameter.ArrayBindSize = Enumerable.Range(0, count).Select(i => 1024 * 64).ToArray(); cmd.Parameters.Add(messagePayloadParameter); var messageCountParameter = cmd.CreateParameter(); messageCountParameter.ParameterName = ":message_count"; messageCountParameter.Direction = ParameterDirection.Output; messageCountParameter.OracleDbType = OracleDbType.Decimal; cmd.Parameters.Add(messageCountParameter); log.Debug(cmd.CommandText); await cmd.ExecuteNonQueryAsync(cancellationToken); // parses the result set into the set of messages return(ReadUdtMessages( payloadType, ((OracleDecimal)messageCountParameter.Value).ToInt32(), ((OracleBinary[])messageIdParameter.Value)?.Select(i => i.Value)?.ToArray() ?? Array.Empty <byte[]>(), ((OracleString[])messagePropertiesParameter.Value)?.Select(i => i.Value)?.ToArray() ?? Array.Empty <string>(), ((OracleString[])messagePayloadParameter.Value)?.Select(i => !i.IsNull ? i.Value : null)?.ToArray() ?? Array.Empty <string>()) .ToArray()); } }