IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  WebSphere | SOA и Web-сервисы  >

IBM WebSphere Developer Technical Journal: Построение Enterprise Service Bus с WebSphere Application Server V6 - Часть 7

Переключение протоколов сообщений

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются

Исходные тексты примера


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: средний

Рэйчел Рейниц, старший специалист-консультант по информационным технологиям, IBM 
Андре Тост, старший сотрудник технической службы, IBM 

21.09.2005

В данной статье объединены идеи из первых шести частей серии по использованию нового механизма обмена сообщениями в IBM® WebSphere® Application Server V6 для построения Enterprise Service Bus, для того чтобы показать вам, как можно использовать ESB для реального переключения различных протоколов сообщений.

Введение

В первых шести частях данной серии статей мы рассмотрели, как установить собственную шину (Часть 2), настроить ее для использования JMS (Часть 3), Web-служб (Часть 5) и WebSphere MQ (Часть 6), а также рассмотрели, как выполнить преобразование сообщений с помощью объектов-посредников (Часть 4). Здесь, в седьмой части, мы сведем вместе эти идеи и рассмотрим вопросы использования поддержки Service Integration Bus (SIBus) для соединения с MQ-очередью сообщений, взаимодействующей с клиентскими приложениями через Web-службы, предлагающие реальные бизнес-функции. Другими словами, мы будем использовать ESB для переключения различных протоколов сообщений!

На данный момент наша серия состоит из следующих статей:



В начало


Обзор наших хитрых приемов

В данной статье мы воспользуемся множеством возможностей SIBus, которые мы предварительно рассмотрели во взаимодействии. Поэтому давайте вкратце вспомним их перед погружением в детали:

  1. В нашем решении мы определили WebSphere Application Server V6 SIBus в качестве Enterprise Service Bus. Одним из наших первых действий была настройка экземпляра шины и добавление к нему некоторых общих функций, таких как прослушивающие приложения, которые обслуживают различные входящие протоколы, поддерживаемые шиной (например, "оконечный прослушиватель" SOAP/HTTP).

  2. Мы также установили SDO Repository, который, среди прочего, помогает шине отслеживать структуру сообщений установленных Web-служб.

  3. Наконец, мы создали адресаты на шине, представляющие реальные пункты, куда могут быть переданы сообщения.

  4. Объекты-посредники связываются с адресатами и могут управлять и оперировать с переданными этим адресатам сообщениями. Они могут также изменить маршрут сообщения по мере прохождения его по шине.

  5. К шине подключены Web-службы через исходящие службы. Для каждой исходящей службы сгенерированы специальные адресаты, которые знают, как обмениваться сообщениями с Web-службой.

  6. К шине подключается WebSphere MQ при помощи функции MQLink, которая разрешает взаимодействие между шиной и любым существующим менеджером MQ-очередей WebSphere.

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



В начало


Бизнес-сценарий

Созданные нами предварительно службы и функциональность предназначены для соединения различных систем компании Posts-R-Us, для того чтобы дать возможность компании отслеживать доставку посылок. В пятой части данной серии статей мы рассматривали службу с названием PackageTrackingService, которая могла доставлять информацию о состоянии конкретной службы.

Одной из причин создания такой службы на ESB была возможность ее вызова клиентами, поддерживающими взаимодействие только с WebSphere MQ и не имеющими какой-либо SOAP-функциональности. Например, предположим, что компания Posts-R-Us использует собственную CRM-систему, выполняющуюся на iSeries и написанную в RPG. Эта система передает сообщение запроса в конкретную MQ-очередь и ожидает ответ на этот запрос в отдельной очереди ответов. Это позволяет системе передавать запросы о множестве посылок одновременно и затем проверять ответ последовательно для каждого из них. Иными словами, система использует синхронную службу асинхронным способом, отделяя передачу запроса от извлечения ответа. Не стоит беспокоиться о том, что происходит за кулисами, а именно – вызов Web-службы по SOAP/HTTP; ESB берет это на себя.



В начало


Архитектура решения

Для выполнения этой работы должны быть интегрированы несколько компонентов. Все они изображены на одном рисунке (рисунок 1), к которому мы будем обращаться на протяжении всей статьи:


Рисунок 1. Архитектура решения
Рисунок 1. Архитектура решения

Пройдем по этапам движения сообщения при передаче клиентом запроса; нумерация этих этапов соответствует нумерации на рисунке 1:

  1. Клиент передает сообщение запроса в очередь, определенную в WebSphere MQ. Для MQ-системы она является не локальной очередью, а очередью удаленных определений. Это означает, что MQ будет направлять приходящие в эту очередь сообщения в SIBus, а оттуда адресату PackageTrackingFromMqDestination (мы создали это удаленное определение и связанный с ним SIBus-адресат в шестой части). Сообщение является текстовым сообщением, содержащим XML.

  2. Объект-посредник PackageTrackingMQToSOAPMediation связан с адресатом и будет обрабатывать каждое сообщение, приходящее в него. Объект-посредник создает SOAP-сообщение и вставляет в него содержимое полученного XML-сообщения. Он также меняет обратный маршрут каждого сообщения, включая PackageTrackingResponseDestination. Мы подробно рассмотрим этот объект-посредник далее.

  3. После обработки сообщения объектом-посредником оно будет перенаправлено адресату PackageTrackingOutboundService путем настройки прямого маршрута адресата PackageTrackFromMqDestination.

  4. Из адресата исходящей службы вызывается реальная Web-служба (мы создали эту исходящую службу в шестой части) через дополнительный адресат с названием PackageTrackingOutboundPort. Поскольку он генерируется при создании исходящей службы, этот адресат не показан отдельно на рисунке 1.

  5. Ответ Web-службы направляется следующему адресату в соответствии с обратным маршрутом оригинального сообщения запроса. Поскольку для этого указан адресат PackageTrackingResponseDestination, сообщение с ответом направляется в него.

  6. Адресат ответов связан с еще одним объектом-посредником PackageTrackingSOAPToMQMediation, который преобразует ответное SOAP-сообщение, пришедшее из Web-службы, в текстовый формат, содержащий только реальное содержимое ответного сообщения.

  7. Мы создаем новый внешний адресат на SIBus, представляющий собой очередь ответов в WebSphere MQ. После преобразования ответного сообщения из SOAP-формата в текстовое сообщение мы можем перенаправить его в этот внешний адресат, который просто направит его обратно в MQ. С этого момента времени адресат клиента может извлечь его, используя обычные MQ-механизмы.

Теперь мы рассмотрим все настройки и исходный код, необходимый для работы всего этого на вашей машине. Вы, возможно, захотите вернуться к рисунку 1, для того чтобы увидеть, как все части работают вместе.



В начало


Объект-посредник: от текста к SOAP

Данный код объекта-посредника предназначен лишь для демонстрационных целей, а потому был разработан простым и легко читаемым. В нем отсутствует обработка ошибок и хорошая объектно-ориентированная структура, которые вы могли бы увидеть в реальном коде. Приведенный здесь код содержит также большое количество жестко закодированной информации, которая в нормальных условиях содержалась бы в параметрах. Вы можете определить свойства контекста (в основном пары "ключ-значение") для адресата через консоль администратора и затем легко извлечь их в обработчике объекта-посредника при помощи метода MessageContext.getProperty().

Как уже упоминалось, приходящее в шину от клиента сообщение является сообщением в XML-формате. Мы должны преобразовать его в SOAP-сообщение перед тем, как сможем перенаправить его Web-службе. Это делается посредством объекта-посредника, который мы должны разработать. Его исходный код (и весь другой представленный здесь исходный код) вы можете получить из загружаемого файла, включенного в данную статью.

PackageTrackingMQToSOAPMediation содержит один обработчик в классе с таким же названием.

Каждый обработчик объекта-посредника реализует метод handle(), который получает объект типа com.ibm.websphere.sib.mediation.messagecontext.SIMessageContext. Среди прочего этот параметр предоставляет доступ к реальному сообщению, которое само хранится в SDO DataGraph. При получении этого DataGraph мы должны указать тип сообщения; в данном случае это текстовое сообщение JMS.

String payload;

// извлечь сообщение из контекста
SIMessage message = ((SIMessageContext)context).getSIMessage();
		
// получить payload – предположим текстовое сообщение
DataGraph graph = 
message.getNewDataGraph(SIApiConstants.JMS_FORMAT_TEXT);
DataObject body = graph.getRootObject();
if (body.isSet("data")) {
	// представить содержимое сообщения в виде String
	payload = body.getString("data/value");
} else {
	// ошибка...
}

Каждый DataGraph содержит корневой DataObject. В данном случае с текстовым сообщением SIBus этот корневой объект имеет определенное в нем свойство data, которое в свою очередь имеет свойство value. Приведенный выше код копирует содержимое этого свойства (то есть реальное содержимое сообщения) в переменную payload.

Затем мы создаем новое сообщение. В коде нашего примера мы выбрали легкий путь жесткого кодирования SOAP-конверта, который должен быть передан Web-службе. Это, конечно же, не очень гибко. В реальной жизни можно было бы создать новое SOAP-сообщение более универсальным способом, читая значения для, например, пространства имен, операции, имени порта и т.д. из свойств контекста. Более подробная информация и примеры кода, показывающие как это сделать, приведены в разделе по структурам сообщений в WebSphere Application Server Information Center.

// вставка полученного сообщения в SOAP-конверт
// довольно неуклюже, но подойдет для демонстрационных целей
String soapEnvelope = "<soapenv:Envelope "  +
"xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "  +
"xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" "  +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "  +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"  +
"<soapenv:Header/><soapenv:Body>" + 
	payload +
"</soapenv:Body></soapenv:Envelope>";
			
body.setString("data/value", soapEnvelope);
			
// заменить содержимое сообщения новым графом
message.setDataGraph(graph,SIApiConstants.JMS_FORMAT_TEXT);

Как вы можете заметить, мы просто вставили XML-сообщение запроса в новый SOAP-конверт, который может быть обработан целевой Web-службой. Однако перед передачей его в эту Web-службу мы должны сказать системе, что это действительно SOAP-сообщение. Пока для SIBus оно есть не что иное, как текст (заметим, что мы вставили новый DataGraph в сообщение при помощи атрибута JMS_FORMAT_TEXT).

SIBus определяет нотацию строки формата, содержащей информацию о целевой Web-службе, куда должно уйти SOAP-сообщение. Строка формата для исходящей SOAP-службы имеет следующую структуру:

SOAP:dest:[busname]:[service destination name],[service namespace],[service name],[port name]

В случае с нашим PackageTrackingService это значит, что строка формата выглядит так:

SOAP:dest:TheBus:PackageTrackingOutboundService,http://service.postrus,
PackageTrackingServiceService,PackageTrackingService

Следуя передовому опыту разработки хороших обработчиков-посредников, мы читаем эту строку из свойства контекста и используем ее для генерирования нового сообщения:

// собрать настройки свойств контекста
String formatString = (String)context.getProperty("formatString");

DataGraph soap = message.getNewDataGraph(formatString);
message.setDataGraph(soap, formatString);

Здесь мы используем небольшой хитрый прием: извлекаем новый DataGraph из существующего сообщения, используя определенную SOAP-строку формата, затем вставляем этот новый DataGraph обратно в сообщение, эффективно заменяя существующее текстовое сообщение. В результате получаем сообщение, которое можно перенаправить адресату исходящей службы, откуда вызывается Web-служба.



В начало


Объект-посредник: от SOAP к тексту

Ответное сообщение является SOAP-конвертом, содержащим XML-информацию о состоянии конкретной посылки. Мы используем PackageTrackingSOAPToMQMediation для преобразования SOAP-сообщения в текстовый формат, который можем передать обратно нашему приложению-клиенту MQ. Подход аналогичен приведенному выше для сообщения запроса.

Во-первых, мы извлекаем содержимое сообщения из входящего сообщения. Отличием является то, что мы читаем информацию в массив байт, а не в строку String, поскольку это несколько облегчает анализ.

byte[] payload;

// извлечь сообщение из контекста
SIMessage message = ((SIMessageContext)context).getSIMessage();
		
// получить payload – извлекаем в виде массива байт, хотя мы и знаем, 
// что фактически это SOAP-сообщение – система выполнит 
// преобразование вместо нас
DataGraph graph = 
message.getNewDataGraph(SIApiConstants.JMS_FORMAT_BYTES);
DataObject body = graph.getRootObject();
if (body.isSet("data")) {
	// представить содержимое сообщения в виде массива байт
	payload = body.getBytes("data/value");
} else {
	// ошибка...
}

В нашем примере мы просто хотим извлечь содержимое SOAP-элемента body и передать его обратно нашим клиентам. Для этого мы используем вспомогательный класс, включенный в пакет XML-анализатора Apache Xerces (поставляется с WebSphere Application Server), называемый XMLSerializer:

// теперь мы анализируем сообщение и извлекаем все, что находится 
// внутри <Body>
Document doc = 
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new ByteArrayInputStream(payload));
Element result = (Element)doc.getElementsByTagName("getReturnStatus").item(0);
			
// сериализовать результат в String, которую мы можем передать в MQ
StringWriter sw = new StringWriter();
new XMLSerializer(sw, new OutputFormat()).serialize(result);

Теперь мы замещаем реальное сообщение так же, как делали это раньше. Новое сообщение является текстовым сообщением:

// заменить содержимое сообщения новым графом		
DataGraph newGraph = 
message.getNewDataGraph(SIApiConstants.JMS_FORMAT_TEXT);
newGraph.getRootObject().set("data/value", sw.getBuffer().toString());			
message.setDataGraph(newGraph, SIApiConstants.JMS_FORMAT_TEXT);

Как вы можете заметить, мы используем ту же хитрость, что и раньше: извлекли экземпляр DataGraph из сообщения, используя строку формата, затем заменили DataGraph в сообщении. В результате получили сообщение, которое может быть прочитано как текстовое сообщение из любого приложения-клиента MQ.



В начало


Маршрутизация

Глядя снова на рисунок 1, мы видим, что необходимо не только правильно преобразовать форматы сообщений при помощи объектов-посредников, но также нужно побеспокоиться о перенаправлении сообщений в нужное место. Существует несколько мест, для которых мы должны скорректировать маршрут прохождения сообщения:

  • Каждое сообщение, приходящее в PackageTrackingFromMqDestination, должно быть перенаправлено адресату PackageTrackingOutboundService. Это делается настройкой этого адресата в прямой маршрутный путь по умолчанию для PackageTrackingFromMqDestination при помощи консоли администратора (не беспокойтесь, мы сделаем это через минуту).

  • Каждое ответное сообщение должно быть обработано PackageTrackingResponseDestination перед отправкой клиенту. Для этого мы помещаем PackageResponseDestination на самый верх обратного маршрутного пути для каждого сообщения запроса в PackageTrackingMQToSOAPMediation при помощи следующего кода:

    // теперь вставим адресат ответов в обратный маршрутный 
    // путь, так чтобы мы смогли перехватить сообщение запроса.
    // Сначала создаем добавляемый replyAddress
    SIDestinationAddress replyAddress;
    replyAddress = SIDestinationAddressFactory.getInstance()
    	.createSIDestinationAddress("PackageTrackingResponseDestination", 
    false);
    
    // Получим копию текущего обратного маршрутного пути
    List rrp = message.getReverseRoutingPath();
    
    // Добавим адресат ответов в список (так чтобы
    // новый адресат был первым адресатом, который 
    // посетит ответное сообщение)
    rrp.add(0, replyAddress);
    
    // Изменим ответный маршрутный путь сообщения
    message.setReverseRoutingPath(rrp);

    Название адресата ответов здесь закодировано жестко, но в реальной жизни оно должно быть извлечено из свойства контекста, так чтобы его можно было поменять во время исполнения.

  • Из адресата ответов каждое ответное сообщение должно быть перенаправлено внешнему адресату с названием PackageTrackingToMQDestination, который служит в качестве прокси для реальной MQ-очереди на системе клиента. Мы опять это делаем установкой прямого маршрутного пути всех сообщений, приходящих через PackageTrackingResponseDestination в TheForeignBus:PackageTrackingToMQDestination@QM_atost (это имя также должно быть уже установлено клиентом как поле reply-to сообщения запроса; опять же, мы используем консоль администратора для установки этого значения).



В начало


Установка и настройка

Теперь мы можем установить и настроить все необходимые части. Здесь мы будем полагать, что вы выполнили настройки, рассмотренные в предыдущих статьях, и знакомы с основами настройки SIBus, поскольку вы уже делали большинство из этих операций.

  1. Начнем с установки кода объекта-посредника. Вы просто можете использовать загрузочный файл, который в справочных целях содержит весь исходный код объекта-посредника. Установите EAR-файл как новое корпоративное приложение. После установки приложения ваше окно корпоративного приложения будет выглядеть приблизительно так, как показано на рисунке 2.


    Рисунок 2. Установленные корпоративные приложения
    Рисунок 2. Установленные корпоративные приложения
  2. Определите только что установленные нами два новых объекта-посредника. Перейдите в Buses => TheBus => Mediations и настройте два новых объекта-посредника; установите поля "Mediation name" и "Handler list name" в одинаковые значения:

    • PackageTrackingMQToSOAPMediation
    • PackageTrackingSOAPToMQMediation.

    После завершения вы должны иметь объекты-посредники, определенные в соответствии с рисунком 3.


    Рисунок 3. Объекты-посредники
    Рисунок  3. Объекты-посредники
  3. Затем мы определяем дополнительные адресаты, необходимые для нашего решения. Если вы следили за последними статьями этой серии, то уже определили PackageTrackingFromMqDestination вместе с необходимой конфигурацией MQLink. Все, что нам еще необходимо, – компоненты, отвечающие за маршрут ответов нашего сценария. Нам нужны:

    • PackageTrackingResponseDestination: обычный адресат очереди.
    • PackageTrackingToMQDestination: внешний адресат, указывающий на MQ-очередь.
    • PackageTrackingToMQDestination: MQ-очередь, которую вы можете определить, используя программу MQ Explorer.
    1. Определите PackageTrackingResponseDestination. Как показано на рисунке 4, установите в консоли администратора прямой маршрутный путь в:

      TheForeignBus:PackageTrackingToMQDestination@[имя вашего менеджера очереди].


      Рисунок 4. Прямой маршрутный путь
      Рисунок 4. Прямой маршрутный путь
    2. С новым созданным адресатом определите PackageTrackingSOAPToMQMediation в качестве его объекта-посредника, используя кнопку Mediate на панели Mediations в консоли администратора.

    3. Создайте новый внешний адресат PackageTrackingToMQDestination@QM_nnn, где QM_nnn – имя вашего менеджера MQ-очереди, и укажите TheForeignBus в качестве значения Bus (рисунок 5).


      Рисунок 5. Новый внешний адресат
      Рисунок 5. Новый внешний адресат
    4. Создайте противоположную часть внешнего адресата в WebSphere MQ в виде обычной локальной очереди – PackageTrackingToMQDestination. Если вы используете MQ в Windows, диалоговое окно MQ Explorer для создания этой очереди будет выглядеть примерно так, как показано на рисунке 6.


      Рисунок 6. Создание новой MQ-очереди
      Рисунок 6. Создание новой MQ-очереди
    5. Все что осталось – небольшая дополнительная настройка PackageTrackingFromMqDestination. Установите его прямой маршрутный путь в TheBus:PackageTrackingOutboundService. Затем создайте новое свойство контекста под названием formatString типа String (рисунок 7) и установите его в:

      SOAP:dest:TheBus:PackageTrackingOutboundService,http://service.postrus,
      PackageTrackingServiceService,PackageTrackingService

      Вспомните, что мы используем это свойство контекста в объекте-посреднике PackageTrackingMQToSOAPMediation.


      Рисунок 7. Свойство контекста formatString
      Рисунок 7. Свойство контекста formatString
    6. Наконец, адресат PackageTrackingFromMqDestination свяжите с объектом-посредником PackageTrackingMQToSOAPMediation.

    После всех этих изменений вы увидите список адресатов, показанный на рисунке 8.


    Рисунок 8. Полный список адресатов
    Рисунок 8. Полный список адресатов

Сохраните все сделанные изменения и перезапустите сервер, если еще этого не сделали.



В начало


Тестирование решения

Как и в предыдущей статье для тестирования мы будем использовать программу MQ rfhutil. Запустите ее и загрузите файл packagetracking.xml при помощи кнопки Read File. Содержимое этого файла выглядит так:

<p843:getPackageStatus xmlns:p843="http://service.postrus"><trackingNumber>123
</trackingNumber></p843:getPackageStatus>

Передайте это сообщение в очередь PackageTrackingRequestRemoteQueue. Если все идет нормально, вы должны увидеть, что в файл System.out добавилось несколько строк (выводящихся операторами print в коде обработчика объекта-посредника) и ответное сообщение передано в очередь PackageTrackingToMQDestination.

Прочитайте результат из этой очереди, опять же используя rfhutil. Закладка Data показывает содержимое полученного ответного сообщения (рисунок 9).


Рисунок 9. Ответное сообщение
Рисунок 9. Ответное сообщение

Еще раз подчеркнем, что, выполнив эти действия, вы получаете эффективную синхронную Web-службу, которая является Web-службой "запрос-ответ", доступной по HTTP и работающей по асинхронному протоколу, то есть WebSphere MQ. Это поднимает вопрос о том, как сопоставить ответ с соответствующим ему запросом.



В начало


Корреляция сообщений

В нашем решении передача запроса и получение ответа абсолютно отделены друг от друга. Как же тогда клиентское приложение сможет извлечь корректное ответное сообщение для запроса, переданного ранее, из очереди ответов? Ответ – корреляционный идентификатор (correlation ID).

Клиент указывает уникальный идентификатор сообщения в сообщении запроса, который передается вместе с сообщением по всему пути к адресату исходящей службы. Там он кэшируется и копируется в поле correlation ID ответного сообщения, затем передается назад клиенту в этом поле. Клиент может извлечь сообщение с соответствующим корреляционным идентификатором, который был предварительно установлен как идентификатор сообщения в оригинальном сообщении запроса. Для этой работы не требуется дополнительной настройки или кодирования.



В начало


Заключение

В данной статье мы представили самый сложный сценарий из наших предыдущих статей – подключение приложения MQ-клиента к Web-службе SOAP/HTTP через SIBus. Запросы и ответы обрабатываются клиентским приложением в асинхронном режиме. Необходимое преобразование сообщений между двумя участвующими протоколами обрабатывается объектами-посредниками, работающими на шине. Во время выполнения можно настроить дополнительную маршрутизацию и другую информацию, например, установить свойства контекста для адресата.

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

В следующей (и последней) статье мы подведем итоги работы, выполненной во всех статьях этой серии, и обсудим будущее ESB в разработке приложений.




В начало


Загрузка

ОписаниеИмяРазмерМетод загрузки
Code sampleesb_part7_code.zip9 KB  FTP|HTTP
Информация о методах загрузки


Ресурсы

Научиться

Получить продукты и технологии

Обсудить


Об авторах

Рэйчел Рейниц (Rachel Reinitz) является старшим специалистом-консультантом по информационным технологиям и программным службам IBM для WebSphere, специализация - Web-службы. Рэйчел консультирует пользователей и ISV по вопросам использования сервис-ориентированной архитектуры и Web-служб для решения их технических и бизнес-задач. Она разработала курс обучения расширенным Web-службам IBM и часто выступает на конференциях. Рэйчел также опытный инструктор по экстремальному программированию (eXtreme Programming – XP) и использует принципы XP четыре года. Она живет в Bay Area, Калифорния, любит туризм, общение и международные путешествия.


Андре Тост (Andre Tost) работает старшим сотрудником технической службы в подразделении WebSphere Business Development, где помогает стратегическим партнерам IBM интегрировать их приложения с WebSphere. Уделяет особое внимание технологии Web-служб семейства продуктов WebSphere. До этого он десять лет занимался различными вопросами разработки и архитектуры программного обеспечения IBM, в частности программой WebSphere Business Components. Приехав из Германии, он поселился в в Рочестере, Миннесота. В свободное время любит заниматься своей семьей и, когда есть возможность, играет и смотрит футбол.




Выскажите мнение об этой странице


Пожалуйста, найдите минутку и заполните форму, чтобы повысить уровень сервиса.



ДаНетНе знаю
 


 


12345
 


В начало


IBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.

    IBM в России Конфиденциальность Контакты