Опубликован: 14.12.2004 | Уровень: для всех | Доступ: платный | ВУЗ: Компания IBM
Лекция 12:

Дополнительные особенности программирования для WebSphere MQ

< Лекция 11 || Лекция 12: 1234 || Лекция 13 >
Аннотация: В лекции даются примеры работы с функциями MQINQ и MQSET, предназначенными для определения и модификации характеристик объектов WebSphere MQ. Аргументируется факт, что работа с MsgId и CorrelId крайне важна, когда речь идет о контроле за доставкой сообщений. Демонстрируется на программном уровне работа с группами сообщений и сегментацией сообщений. Рассмотрен пример написания Channel-exit программы в виде DLL (Dynamic Link Library) для Windows.

Модификация объектов

Характеристики объектов WebSphere MQ определяются в момент создания, но иногда их необходимо модифицировать, например, изменив приоритет сообщений при помещении их в очередь (Default Priority) или максимально допустимое количество сообщений в очереди (Maximum Queue Depth). Модификация объектов WebSphere MQ требуется, в частности, при восстановлении опций очередей Put Messages и Get Messages в состояние Allowed, а также параметров триггеринга, извлечении статистических данных (Message Count и т.п.). Необходимость работы с функциями MQINQ и MQSET , предназначенными для этих целей, возникает не так часто, но без этого иногда трудно обойтись.

Функция MQINQ позволяет извлечь атрибуты любой очереди, процесса, менеджера или списка кластеров namelist. MQSET дает возможность изменить эти параметры, но только для очереди. Обе функции используют массивы идентификаторов (selectors), в которых указывается, какие характеристики объектов должны быть извлечены или изменены. Имена идентификаторов имеют префиксы: MQCA_ для символьных данных (например, имя очереди) и MQIA_ для числовых данных (например, Maximum Queue Depth).

Допустим, для некоторой очереди необходимо определить характеристики: количество сообщений в очереди, максимальное количество сообщений, имя очереди и ее описание.

Формат команды:

MQINQ (Hconn, Hobj, SelectorCount, Selectors,
      IntAttrCount, IntAttrs, CharAttrLength, 
      CharAttrs, CompCode, Reason)

Очередь должна быть открыта и Hconn, Hobj известны.

Пусть общее количество идентификаторов MQLONG SelectorCount = 4 ; они должны быть перечислены в массиве MQLONG Selectors[4] ;

Selectors [0] = MQIA_CURRENT_Q_DEPTH;
Selectors [1] = MQIA_MAX_Q_DEPTH;
Selectors [2] = MQCA_Q_NAME; 
Selectors [3] = MQCA_Q_DESC;

Число цифровых атрибутов задается в MQLONG IntAttrCount = 2 ; они должны вернуться в массив MQLONG IntAttrs [2] ; Длина затребованных символьных данных MQLONG CharAttrLength = 112 ; (48 для MQCA_Q_NAME и 64 для MQCA_Q_DESC ) и они должны вернуться в массив CHAR CharAttrs[112] = "" ; Теперь можно выполнять MQINQ . Не стоит забывать одно важное правило: цифровые и символьные характеристики следуют в массивах IntAttrs и CharAttrs в том порядке, как они перечислены в массиве Selectors.

В случае, когда программа rewriter (см. лекцию 8), запускается как триггер, при поступлении сообщения в очередь INPUT.Q, использовать ini-файл неудобно и гораздо проще задать необходимые параметры в свойствах очереди. Для этого в свойствах очереди INPUT.Q в закладке Triggering указывается:

Trigger Control = On
    Initiation Queue Name = INPUT_INIT.Q
    Process Name = rewriter

а для процесса rewriter определяется

PROCESS_USER_DATA = OUTPUT.Q    
    /* queue output */
PROCESS_APPL_ID = "C:\rewriter\rewriter.exe"
PROCESS_ENV_DATA = rewriter.log   
    /* имя лог-файла  не более 24 символов */

Теперь в программе легко можно извлечь все необходимые параметры с помощью MQINQ . После завершения работы программы очередь инициализации следует очистить. Это делает следующий фрагмент кода:

MQLONG   Select[1];              
    /* attribute selectors           */
MQLONG   SelectValue[1];         
    /* value attribute selectors     */
MQLONG   char_count;
char     queueinitname[48] = ""; 
int      queuenamelen;  

Select[0] = MQCA_INITIATION_Q_NAME;       
    /* attribute selectors  */        
queuenamelen = 0;
char_count = 48;
MQINQ(Hcon, Hobj, 1, Select, 0, NULL, 
      char_count, queueinitname, 
      &CompCode, &Reason);  
queuenamelen = strlen(queueinitname) - 1;
queueinitname[queuenamelen] = ' ';
strncpy(odI.ObjectName, queueinitname, 24);
O_options = MQOO_INPUT_SHARED + 
            MQOO_FAIL_IF_QUIESCING;
MQOPEN(Hcon, &odI, O_options, &Hinq, 
       &CompCode, &Reason); 
if (Reason != MQRC_NONE) { 
    printf("MQOPEN (input) ended with reason
            code %ld\n", Reason); }
if (CompCode == MQCC_FAILED) { 
    exit(Reason);  }
memcpy(md.MsgId, MQMI_NONE, 
       sizeof(md.MsgId));
memcpy(md.CorrelId, MQMI_NONE, 
       sizeof(md.CorrelId));
while (CompCode == MQCC_OK)
    {         
    gmo.Options = MQGMO_ACCEPT_TRUNCATED_MSG +
                  MQGMO_WAIT;        
    gmo.WaitInterval = 1;     
    memcpy(md.MsgId, MQMI_NONE, 
           sizeof(md.MsgId));
    memcpy(md.CorrelId, MQMI_NONE, 
           sizeof(md.CorrelId));
    buflen = sizeof(buffer) - 1;
    MQGET(Hcon, Hinq, &md, &gmo, buflen, 
          buffer, &messlen, &CompCode, 
          &Reason); 
    // printf("Inituation queue clear with 
    // reason code %ld and CompCode %ld\n",  
    // Reason, CompCode);
     }
CompCode = MQCC_OK ;

В этом фрагменте MQINQ используется для извлечения только одного параметра: имени очереди инициализации. Очистка этой очереди делается командой MQGET до тех пор, пока очередь не будет пуста.

Функция MQSET по формату полностью аналогична MQINQ , разница между ними заключается только в направлении потоков данных. В качестве примера можно рассмотреть работу триггера с условиями Trigger Type = First и Trigger Depth = 1. При срабатывании триггера флажок из состояния Trigger Control = On переходит в состояние Trigger Control = Off и его надо восстанавливать. Это делает следующий фрагмент кода:

Select[0] = MQIA_TRIGGER_CONTROL;       
    /* attribute selectors  */        
SelectValue[0] = 1 ;
MQSET(Hcon, Hobj, 1, Select, 1, SelectValue,
      0, NULL, &CompCode, &Reason);

Заключительный вывод по разделу: функция MQINQ позволяет извлечь атрибуты любой очереди, процесса, менеджера или списка кластеров namelist, а функция MQSET - изменить эти параметры, но только для очереди.

< Лекция 11 || Лекция 12: 1234 || Лекция 13 >
Вадим Горячев
Вадим Горячев
Россия
Artem Bardakov
Artem Bardakov
Россия