Содержание


Создание приложения с помощью IBM Workflow для Bluemix

Comments

Первая часть этой серии руководств по использованию рабочих процессов в Bluemix знакомит читателя с тем, как работает служба Workflow, на примере приложения, которое обрабатывает те самые надоедливые коды купонного опроса, которые печатаются в нижней части товарных чеков. (Магазины часто печатают на товарных чеках URL и код опроса. Если зайти на веб-сайт и ввести этот код, открывается страница с анкетой. Заполнив ее, вы получите код купона, который можно использовать для получения скидки при покупке другого товара в этом магазине.) Хорошо бы вместо того чтобы хранить квитанции и вручную вводить URL-адрес и код, получать по электронной почте кликабельную ссылку! Еще хотелось бы, чтобы страница опроса распознавала вас и автоматически отправляла код скидки по электронной почте, вместо того чтобы просто выводить его на экран.

Вам приходилось создавать приложение, которое обращается к нескольким службам, выдающим асинхронные ответы? Или приложение, взаимодействующее с пользователями, которые могут ответить через три дня? Или приложение, которое сопоставляет несколько таких ответов и объединяет их результаты? Мы покажем, как это сделать с помощью единого сценария на основе «долгоиграющего» рабочего процесса JavaScript с отслеживанием состояния, который сопоставляет события, когда они происходят.

Что нужно для разработки сценария

  • Знакомство с JavaScript и REST-службами
  • Учетные записи в IBM DevOps Services (прежнее название: JazzHub) и Bluemix

Шаг 1. Создание экземпляров служб рабочих процессов Bluemix и SendGrid

Войдите в Bluemix и следуйте инструкциям по созданию нового экземпляра службы Workflow, а также установите плагин JazzHub, как описано в разделе Getting Started документации.

Примечание. Для использования службы Workflow не требуется приложение Bluemix. Так что при создании экземпляра службы, как указано выше, оставьте его непривязанным. Рабочие процессы легко использовать из Bluemix-приложений с помощью HTTP-вызовов, как показано в следующем примере.

Поскольку приложению из этого примера рабочий процесс требуется для отправки сообщений электронной почты, вам понадобится отдельная служба email с API-интерфейсом, например, SendGrid из каталога Bluemix. Если у вас еще нет экземпляра службы SendGrid в Bluemix, создайте его и запишите реквизиты доступа. Один из способов посмотреть реквизиты доступа – связать Bluemix-приложение с экземпляром службы SendGrid и рассмотреть это приложение на панели управления. Вы увидите, что оно привязано к экземпляру службы SendGrid, и сможете посмотреть реквизиты доступа, нажав кнопку Show credentials.

Реквизиты доступа SendGrid
Реквизиты доступа SendGrid

Примечание. Активация службы SendGrid может происходить с задержкой, так что она начнет работать лишь через некоторое время. Чтобы убедиться, что она работает, перейдите на страницу SendGrid для тестирования API и воспользуйтесь функцией Try It для проверки работы электронной почты. Шаг 2 можно выполнить без нее, но для выполнения шага 3 служба должна работать.

Шаг 2. Создание сценария рабочего процесса

Откройте страницу IBM DevOps Services в веб-браузере (для бета-версии службы Workflow используйте браузер Chrome) и создайте новый проект. В этом проекте создайте файл с расширением jsflow. Это сценарий рабочего процесса, который содержит всю необходимую логику.

Чтобы проверить правильность установки плагина службы рабочих процессов, щелкните на файле jsflow и найдите новый пункт меню Tools в DevOps Services. Выберите его, чтобы развернуть подменю с пунктами Deploy и Invoke, которые взаимодействуют с созданным экземпляром службы Workflow, позволяя развернуть и запустить процесс.

Меню Tools
Меню Tools

Теперь можно приступать к созданию рабочего процесса. Рабочий процесс представляет собой набор служб, с которыми пользователи и приложение взаимодействуют по протоколу HTTP. Создайте простую пару прием-ответ, чтобы получить HTTP-запрос и ответить на него строкой. Это первое взаимодействие с процессом, когда продавец запрашивает начало опроса для конкретного покупателя.

start = RECEIVEPOST(null, 'begin'); 
replyToStart = REPLYPOST(start, 'begin', 
                         'Survey information has been sent to:' + start.out.customeremail);

Запустите этот процесс. Сохраните файл и выберите пункт Deploy из раскрывающегося меню Tools. Увидев сообщение об успешном выполнении, выберите из раскрывающегося меню пункт Invoke. В этом процессе адрес электронной почты покупателя используется для последующего асинхронного взаимодействия с продавцом и передачи текста первого ответа, приведенного в предыдущем примере кода (см. start.out.customeremail). Укажите адрес электронной почты в качестве параметра вызова, как показано на следующем рисунке. Выберите POST и FORM в верхней строке.

Простой рабочий процесс
Простой рабочий процесс

Нажмите кнопку Invoke. Вы должны увидеть примерно следующее.

Ответ на вызов
Ответ на вызов

Поздравляем! Только что вы создали свой первый рабочий процесс. Давайте рассмотрим, что здесь происходит. Рабочий процесс состоит из действий, и действия – это единственный вид элементов, допустимый на верхнем уровне определения сценария. У действия есть имя (например, start и replyToStart), и оно определяется путем вызова соответствующей функции JavaScript (например, RECEIVEPOST и REPLYPOST). Порядок выполнения действий определяется связями между ними. Связи передаются в определение действия в качестве первого аргумента. Действие start не имеет входящих связей (null) и, таким образом, может запускать экземпляр рабочего процесса. К действию replyToStart проведена линия связи от действия start и, таким образом, оно не может начаться до завершения действия start.

Посмотрим, что происходит после запуска. Обратите внимание, что оба действия ссылаются на относительный URL begin. Это определяет относительный URL этого конкретного взаимодействия, потому, что у рабочего процесса может быть несколько принимающих действий. Нужна возможность направлять вызовы к каждому действию. Так как оба они ссылаются на один и тот же относительный URL, они представляют собой пару прием-ответ и сочетаются во время выполнения, так что ответ реагирует на HTTP-вызов соответствующего принимающего действия. Посмотрите на конец URL-адреса в диалоговом окне invoke, и вы увидите, что он оканчивается относительным URL begin.

Как видите, ответ представляет собой выражение JavaScript, которое составляет строку. На верхнем уровне рабочего процесса нельзя использовать произвольный JavaScript, однако он допускается в выражениях и в специальных действиях SCRIPT. Выражение обращается к переменной start.out и получает из нее значение customeremail, введенное в диалоговое окно invoke и переданное в качестве form-encoded параметра при нажатии кнопки Invoke в предыдущем разделе. В возвращаемой строке содержится значение этого адреса электронной почты. У каждого действия есть выходная переменная по умолчанию с именем типа [activityname].out.

Инструмент invoke просто делает HTTP-вызов. Вы можете сделать тот же самый вызов самостоятельно с помощью инструмента cURL, как описано ниже. Используйте целевой URL-адрес, показанный в инструменте invoke.

curl --data-urlencode "customeremail=XXX"   
[put your workflow endpoint here]

Шаг 3. Отправка ссылки на анкету по электронной почте

Чтобы было еще интереснее, отправим покупателю ссылку на анкету, добавив к процессу следующий вызов POST. Он направляет запрос к службе SendGrid для передачи покупателю ссылки на анкету по электронной почте. Отредактируйте следующий пример кода с использованием значений своих реквизитов доступа SendGrid, полученных на шаге 1. Замените значение api_user своим именем пользователя SendGrid, а api-key – паролем SendGrid. Для простоты в этом примере имя пользователя и пароль встроены в строку, хотя этого делать не рекомендуется.

sendsurveymail = POST(start, 'https://api.sendgrid.com/api/mail.send.json', 
    { 
      'from': 'AmazingCoupons@mailinator.com', 
      'to': start.out.customeremail, 
      'subject': 'Fill out the survey to get your coupon!', 
      'text': 'Please fill out the survey at:  
          http://surveysample.mybluemix.net/?location=' +Location+'/submitsurvey', 
      'api_user': 'XXX',  //replace the XXX with your SendGrid username 
      'api_key': 'XXX' //replace the XXX with your SendGrid password 
     });

Выберите Tools > Visualize, и вы увидите, что теперь процесс имеет две параллельные ветви. Можно щелкнуть правой кнопкой мыши на ссылке, чтобы Открыть новое окно и разместить его рядом с окном сценария. При изменении сценария изображение будет обновляться, демонстрируя схему создаваемого рабочего процесса.

Визуализация процесса
Визуализация процесса

На предыдущем рисунке ссылка в тексте сообщения указывает на пример анкеты, который представляет собой простую форму HTML/JS, уже развернутую в Bluemix. При желании можно увидеть детали этой формы. Вы можете скопировать Bluemix Liberty-проект, в котором находится эта форма, и поиграть с ней.

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

Посмотрите на ссылку в этом сообщении. Первая часть – это ссылка на приложение опроса. Вторая часть — это параметр location, который фактически является ссылкой на тот же экземпляр рабочего процесса, который послал это сообщение. Форма составлена так, чтобы нажатие кнопки Submit приводило к отправке HTTP-запроса по этому URL-адресу.

Этот URL-адрес взят из переменной location рабочего процесса, которая использовалась в действии POST на предыдущих шагах. Обратите внимание, что мы создали там этот URL и добавили параметр location со значением Location + '/submitsurvey'. Если теперь щелкнуть на этой ссылке, она перенесет вас к анкете, которую можно заполнить.

анкета
анкета

Внимание! Если не добавить действие receive, способное обработать обратный вызов, то попытка отправить анкету завершится неудачей.

Шаг 4. Обработка заполненной анкеты

Добавим пару прием-ответ для обработки присланной формы. Добавьте в сценарий рабочего процесса следующий код. Обратите внимание, что относительный URL-адрес submitsurvey – тот, что был добавлен в конец URL-адреса на предыдущем шаге.

submit = RECEIVEPOST(sendsurveymail, 'submitsurvey'); 
replyToSubmit = REPLYPOST(submit,'submitsurvey', 'Thanks '+  
     start.out.customeremail +'. Your coupon is on its way!');

Сохраните, разверните и перезапустите рабочий процесс. Получив анкету, заполните и отправьте ее.

ответная анкета
ответная анкета

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

Шаг 5. Получение прогноза погоды для добавления рекламы холодных напитков

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

Пока жестко запрограммируем код города – Кембридж, штат Массачусетс, США. Однако в первоначальном вызове процесса с адресом электронной почты покупателя можно передать второй параметр. Добавьте следующую строку:

weather = GET(submit, 'http://api.openweathermap.org/data/2.5/weather?q=cambridge,ma');

Шаг 6. Отправка кода купона с рекламой

Наконец, нужно отправить код купона. Сначала создадим его, а затем отправим вместе с предложением холодного напитка, если на улице жарко (или горячего, если холодно). В реальной жизни код купона создается серверной службой, к которой рабочий процесс направляет запрос POST. Здесь же используется действие SCRIPT для генерации случайного числа. В этом сценарии мы также проверяем, указывает ли сообщение от метеослужбы на то, что на улице жарко. В этом случае мы добавим строку с рекламой нового прохладительного напитка; в противном случае – строку с рекламой нового горячего напитка.

JavaScript можно внедрить в процесс с помощью действия SCRIPT. Сценарий компилируется и выполняется только тогда, когда это действие достигнуто; то есть когда достигнут соответствующий узел на схеме рабочего процесса. Для завершения рабочего процесса добавьте SCRIPT и еще один запрос POST по электронной почте:

buildSaleObj = SCRIPT(weather, function() { 
  var coupon = Math.floor(Math.random()*90000) + 10000;   
  var emailbody = 'You have earned at 20% discount! Please use code '+ coupon +' online or in stores.'; 
    if(weather.out.main.temp >= 290){ 
  	emailbody += 'It is quite warm out. Try our new iced Mocha-Latte!'; 
  } else emailbody += "Try our new Caffe Malin" 
  //с данными анкеты, доступными в submitsurvey.out, можно делать еще что-нибудь 
}); 
sendmail = POST(buildSaleObj, 'https://api.sendgrid.com/api/mail.send.json', 
                { 
      'from': 'AmazingCoupons@mailinator.com', 
                        'to': start.out.customeremail, 
                        'subject': 'Coupon!', 
                        'text': emailbody, 
     			  'api_user': 'XXX', //replace XXX with your SendGrid username 
	  		  'api_key':  'XXX', //replace XXX with your SendGrid password 
                } 
);

Чтобы увидеть, как теперь выглядит процесс, нажмите кнопку Tools > Visualize. Пример приведен на следующем рисунке.

Визуализация окончательного процесса
Визуализация окончательного процесса

Если теперь сохранить, развернуть и перезапустить сценарий рабочего процесса, то вы увидите окончательное сообщение электронной почты после запуска рабочего процесса. Оно передает покупателю код купона, и тот может радостно отправляться за скидкой! При отправке сообщения электронной почты, показанного на рисунке, температура в Кембридже составляла 294°К, поэтому также была отправлена реклама прохладительного напитка.

купон
купон

Заключение

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

Данный сценарий можно расширить несколькими способами: публиковать результаты опроса в базу данных, такую как Cloudant; создать еще одну форму, которую продавец будет использовать для инициирования рабочего процесса и представления дополнительной информации о сделке; добавить таймаут, чтобы рабочий процесс завершался, если покупатель не прислал анкету в течение 30 дней; добавить новую ветвь рабочего процесса для вознаграждения продавца за заполнение анкеты его покупателем. Обратите внимание, что в бета-версии ожидание не поддерживается.

За дополнительной информацией о службе Workflow обращайтесь к документации, принимайте участие в форуме (используйте тег workflow) и изучайте примеры из проекта общедоступных примеров, где приведены некоторые основные ограничения языка, включая условные переходы.


Ресурсы для скачивания


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Облачные вычисления
ArticleID=1022221
ArticleTitle=Создание приложения с помощью IBM Workflow для Bluemix
publish-date=11252015