Как вызвать веб-службу из iSeries COBOL?

Нам нужно иметь возможность вызывать внутреннюю веб-службу из кода COBOL, запущенного на iSeries LPAR (V6R1). Я проработал один полный пример, который мне удалось найти в Интернете здесь. Итак, моим следующим шагом была попытка повторить процесс и вызвать одну из наших существующих веб-служб.

Я использовал команду WSDL2WS из QSH для создания клиентских заглушек на языке C. Я изменил пример клиентской программы COBOL и попытался вызвать мою веб-службу. Проблема, с которой я столкнулся, похоже, связана с тем, что методы примера клиента на языке C возвращают указатели, а код COBOL присваивает их указателям. Я подозреваю, что ошибка в коде COBOL является корнем моей проблемы, потому что метод C, который WSDL2WS создал для метода моего веб-сервиса, возвращает простую xsdc_string, а не указатель на пользовательский тип результата:

xsdc__string TestUnsuccessfulMessage(AXISCHANDLE stub)
{
    AXISCHANDLE call = axiscStubGetCall(stub);
    xsdc__string Ret = NULL;

    axiscCallSetSoapFaultNamespace(call, "http://myserver/PSItemMaintenance/ItemMaintenanceService.svc");


    // ======================================================================
    // Initialize client engine, set SOAP version, SOAPAction, operation, etc.
    // ======================================================================

    if (AXISC_SUCCESS != axiscCallInitialize(call, C_DOC_PROVIDER ))
        return Ret;

    if (NULL==axiscCallGetTransportProperty(call,"SOAPAction",0))
        axiscCallSetTransportProperty(call,AXISC_SOAPACTION_HEADER , "http://tempuri.org/IItemMaintenanceService/TestUnsuccessfulMessage");

    axiscCallSetSOAPVersion(call, SOAP_VER_1_1);
    axiscCallSetOperation(call, "TestUnsuccessfulMessage", "http://tempuri.org/");

    // ======================================================================
    // Apply SSL configuration properties and user-set SOAP headers.
    // ======================================================================

    axiscStubIncludeSecure(stub);
    axiscStubApplyUserPreferences(stub);


    // ======================================================================
    // Invoke web service, send/receive operation. Handle output parameters, if any.
    // ======================================================================

    if (AXISC_SUCCESS == axiscCallSendAndReceive(call))
    {
        if(AXISC_SUCCESS == axiscCallValidateMessage(call, "TestUnsuccessfulMessageResponse", "http://tempuri.org/", true_))
        {
            Ret = axiscCallGetElementAsString(call, "TestUnsuccessfulMessageResult", 0);
        }

        axiscStubCheckForExtraneousElements(stub);
    }
    axiscCallUnInitialize(call);
    return Ret;
}

Я могу настроить веб-сервис в режиме отладки и могу видеть вызов с iSeries, когда я запускаю программу, которая вызывает модули COBOL и C. Я также вижу, что возвращаю простое строковое значение.

Проблема возникает, когда программа COBOL пытается взять возвращаемое значение и использовать его. Я полагаю, что соответствующие биты кода COBOL следующие:

LINKAGE PROCEDURE FOR "TestSuccessfulMessage"
                 USING ALL DESCRIBED    

LINKAGE SECTION.                     
 01 LookupResult         PIC X(1000).  

CALL PROCEDURE "TestSuccessfulMessage"
 USING BY VALUE STUB              
 RETURNING LookupResult.          

Я получаю MCH3601, когда он закодирован таким образом. Если я возвращаю в указатель, а затем устанавливаю адрес в LookupResult, я получаю нулевое значение.

Я надеюсь, что я просто упускаю где-то маленькую деталь. У меня очень мало опыта работы с COBOL. Я просто пытаюсь создать эталонное приложение в качестве доказательства концепции для другой команды в нашей компании. Любая помощь или предложения о том, что можно попробовать, будут приняты с благодарностью. Я могу предоставить больше кода.

Обновление: Я попробовал просто переместить объявление LookupResult в рабочее хранилище. Хотя это устранило ошибку MCH3601, я просто получил кучу мусорных данных на своем дисплее. Я могу видеть части информации о моей сессии iSeries (т.е. идентификатор устройства и т.д.) в этих данных.

Я также попробовал оставить LookupResult в секции связывания и создать указатель в рабочем хранилище. Затем я добавил "SET Address of LookupResult TO ResultPointer". И снова вызов завершился без ошибок, но когда я отображаю LookupResult, я получаю мусорные данные. Однако они отличаются от тех данных, которые возвращаются, если я возвращаюсь прямо в LookupResult. В этих данных я вижу фрагменты конверта SOAP.

Final: Все изменения, которые мне пришлось сделать, были внесены в код COBOL. Вот соответствующие фрагменты:

WORKING-STORAGE SECTION.              
01 Endpoint             PIC X(100).   
01 STUB                 USAGE POINTER.
01 ResultPointer        USAGE POINTER.

LINKAGE SECTION.                      
01 pszEndpoint          PIC X(100).   
01 LookupResult         PIC X(7).   

CALL PROCEDURE "TestSuccessfulMessage"       
     USING BY VALUE STUB                     
     RETURNING INTO ResultPointer.           

SET Address of LookupResult TO ResultPointer.

5
задан Paul G 20 December 2011 в 16:46
поделиться