Нам нужно иметь возможность вызывать внутреннюю веб-службу из кода COBOL, работающего на LPAR iSeries (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 (например, deviceID и т. Д.).
Я также попытался оставить 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.