Skip to content
November 7, 2012 / ahriman hpc mode

Windows Azure Mobile Services. Краткое руководство по разработке. Часть 4. Push-уведомления.

Оглавление:

Windows Azure Mobile Services. Краткое руководство по разработке. Часть 1. Введение.
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 2. Хранение данных в Mobile Services
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 3. Аутентификация.
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 4. Push-уведомления.

Для того, чтобы отправлять push-уведомления в ваше приложение с использованием Windows Azure Mobile Services, необходимо воспользоваться сервисом Windows Push Notification (WNS). Результатом этой части руководства будет то, что мобильный сервис будет посылать push-уведомление всякий раз, когда будет вставлена новая запись. .

Регистрация в Магазине Windows

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

Перейдите на странице регистрации приложения – Submit an app, войдите с вашим аккаунтом Microsoft и нажмите Appname(рисунок 1).

clip_image002

Рис. 1. Добавление приложения в Магазин Windows

Введите название вашего приложения в поле Appname, нажмите Reserveappname и Save(рисунок 2).

clip_image004

Рис. 2. Добавление приложения в Магазин Windows

Откройте созданный ранее проект и, нажав правой кнопкой мыши на названии проекта, нажмите Store=>AssociateAppwiththeStore. (рисунок 3).

clip_image006

Рис. 3. Интерфейс Visual Studio 2012

Нажмите Sign in и войдите в систему с вашим аккаунтом Microsoft. Выберите зарегистрированное ранее приложение и нажмите Next=>Associate (рисунок 4).

clip_image008

Рис. 4. Добавление приложения в Магазин Windows

Перейдите на страницу My Applications page и выберите ваше приложение из списка (рисунок 5).

clip_image010

Рис. 5. Настройки приложения

В API Settings запишите значения Client secret и Package security identifier (SID) (рисунок 6).

clip_image012

Рис. 6. Настройки приложения

Перейдите на портал управления. Выберите на вкладке MobileServices ваше приложение (рисунок 7).

clip_image014

Рис. 7. Портал управления Windows Azure

На вкладке Push введите записанные ранее значения Clientsecret и PackageSID и нажмите Save(рисунок 8).

clip_image016

Рис. 8. Настройки push-уведомлений

Интеграция мобильного сервиса и приложения с WNS проведена успешно.

Добавление push-уведомлений в приложение

Добавьте в файл App.xaml.cs:

using Windows.Networking.PushNotifications;

Добавьте в файл App.xaml.cs:

public static PushNotificationChannel CurrentChannel { get; private set; }

private async void AcquirePushChannel()

{

CurrentChannel =

await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

}

В этом коде получается и сохраняется канал push-уведомлений.

Вставьте в начало обработчика OnLaunched вызов нового метода, что будет гарантировать, что при каждом запуске приложения будет инициализироваться свойство CurrentChannel :

AcquirePushChannel();

Добавьте в MainPage.xaml.cs в класс TodoItem новое свойство:

[DataMember(Name = “channel”)]

public string Channel { get; set; }

Замените метод ButtonSave_Click:

private void ButtonSave_Click(object sender, RoutedEventArgs e)

{

var todoItem = new TodoItem { Text = TextInput.Text, Channel = App.CurrentChannel.Uri };

InsertTodoItem(todoItem);

}

Если вы используете собственный проект, а не сгенерированный на портале управления, откройте Package.appxmanifest file и убедитесь, что на вкладке ApplicationUI значение Toastcapable определено как Yes(рисунок 9).

clip_image018

Рис. 9. Включения уведомлений

Таким образом приложение сможет использовать всплывающие уведомления.

Обновление скрипта на портале управления

На портале управления перейдите на вкладку Data и выберите таблицу TodoItem (рисунок 10).

clip_image020

Рис. 10. Портал управления Windows Azure

На вкладке Script нажмите Insert(рисунок 11).

clip_image022

Рис. 11. Портал управления Windows Azure

Замените функцию вставки на следующий код, и нажмите Save:

function insert(item, user, request) {

request.execute({

success: function() {

// записать в ответ и отослать

// уведомление в фоне

request.respond();

push.wns.sendToastText04(item.channel, {

text1: item.text

}, {

success: function(pushResponse) {

console.log(“Sent push:”, pushResponse);

}

});

}

});

}

Таким образом регистрируется новый скрипт, обрабатывающий операцию вставки и отсылающий push-уведомлений (вставленный текст) в канал, предоставленный запросов на вставку.

Запуск приложения

Запустите приложение, введите текст в поле InsertaTodoItem и нажмите Save(рисунок 12).

clip_image024

Рис. 12. Интерфейс приложения

Обратите внимание, что после вставки сущности приложение получит push-уведомление от WNS (рисунок 13).

clip_image026

Рис. 13. Интерфейс приложения

Сделаем теперь так, чтобы можно было отсылать push-уведомления пользователям приложения Магазина Windows.

Создание новой таблицы

На портале управления перейдите на вкладку MobileServicesи выберите ваше приложение (рисунок 14).

clip_image027

Рис. 14. Портал управления Windows Azure

На вкладке Data нажмите Create(рисунок 15).

clip_image029

Рис. 15. Портал управления Windows Azure

В открывшемся диалоге введите в поле Tablenameзначение Channel, остальные значения оставьте стандартными (рисунок 16). Нажмите кнопку.

clip_image031

Рис. 16. Создание новой таблицы

В новой таблице будут храниться URI каналов, которые будут использоваться при посылке push-уведомлений отдельно от данных сущности.

Обновление приложения

Удалите из MainPage.xaml.cs свойство Channel в классе TodoItem . Класс должен выглядеть так:

public class TodoItem

{

public int Id { get; set; }

[DataMember(Name = “text”)]

public string Text { get; set; }

[DataMember(Name = “complete”)]

public bool Complete { get; set; }

}

Замените метод ButtonSave_Click:

private void ButtonSave_Click(object sender, RoutedEventArgs e)

{

var todoItem = new TodoItem { Text = TextInput.Text };

InsertTodoItem(todoItem);

}

Добавьте код, создающий новый класс Channel:

public class Channel

{

public int Id { get; set; }

[DataMember(Name = “uri”)]

public string Uri { get; set; }

}

Замените в файле App.xaml.cs метод AcquirePushChannel:

private async void AcquirePushChannel()

{

CurrentChannel =

await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

IMobileServiceTable<Channel> channelTable = App.MobileService.GetTable<Channel>();

var channel = new Channel { Uri = CurrentChannel.Uri };

await channelTable.InsertAsync(channel);

}

В этом коде происходит вставка текущего канала в таблицу Channel.

Обновление серверных скриптов

На портале управления на вкладке Data выберите таблицу Channel (рисунок 18).

clip_image033

Рис. 18. Портал управления Windows Azure

На вкладке Script нажмите Insert(рисунок 19).

clip_image035

Рис. 19. Портал управления Windows Azure

Замените функцию вставки (Insert) и нажмите Save:

function insert(item, user, request) {

var channelTable = tables.getTable(‘Channel’);

channelTable

.where({ uri: item.uri })

.read({ success: insertChannelIfNotFound });

function insertChannelIfNotFound(existingChannels) {

if (existingChannels.length > 0) {

request.respond(200, existingChannels[0]);

} else {

request.execute();

}

}

}

Скрипт проверяет таблицу Channel на наличие каналов с идентичным URI и, в том случае, если такового нет, происходит вставка канала.

Нажмите Script и выберите Insert(рисунок 20).

clip_image036

Рис. 20. Портал управления Windows Azure

Замените функцию вставки и нажмите Save:

function insert(item, user, request) {

request.execute({

success: function() {

request.respond();

sendNotifications();

}

});

function sendNotifications() {

var channelTable = tables.getTable(‘Channel’);

channelTable.read({

success: function(channels) {

channels.forEach(function(channel) {

push.wns.sendToastText04(channel.uri, {

text1: item.text

}, {

success: function(pushResponse) {

console.log(“Sent push:”, pushResponse);

}

});

});

}

});

}

}

Скрипт вставки будет отправлять push-уведомление с текстом вставленной сущности во все каналы, хранящиеся в таблице Channel.

Запуск приложения

Запустите приложение и введите текст в поле InsertaTodoItem, после чего нажмите Save(рисунок 21).

clip_image037

Рис. 21. Интерфейс приложения

Запустите на нескольких машинах ваше приложение и повторите процедуру, обратите внимание, что везде будет приходить push-уведомление от WNS (рисунок 22).

clip_image038

Рис. 22. Интерфейс приложения

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

Advertisements
November 7, 2012 / ahriman hpc mode

Windows Azure Mobile Services. Краткое руководство по разработке. Часть 3. Аутентификация.

Оглавление:

Windows Azure Mobile Services. Краткое руководство по разработке. Часть 1. Введение.
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 2. Хранение данных в Mobile Services
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 3. Аутентификация.
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 4. Push-уведомления.

В этой части рассмотрены вопросы аутентификации в мобильном сервисе из вашего приложения.

Регистрация приложения для аутентификации и настройка мобильного сервиса

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

Войдите на портале управления, перейдите на MobileServicesи выберите ваш мобильный сервис (рисунок 1).

clip_image002

Рис. 1. Портал управления Windows Azure

Перейдите на вкладку Dashboard и запишите значение SiteURL (рисунок 2).

clip_image004

Рис. 2. Портал управления Windows Azure

Настроим аутентификацию через Facebook. Для этого понадобится аккаунт Facebook.

Перейдите на страницу Facebook Developers и войдите в систему.

Нажмите Apps, затем Create New App (рисунок 3).

clip_image006

Рис. 3. Портал Facebook

Выберите уникальное имя для приложения и нажмите OK(рисунок 4), что зарегистрирует приложение на Facebook.

clip_image008

Рис. 4. Портал Facebook

В Select how your app integrates with Facebook разверните Website with Facebook Login,введите URL мобильного сервиса в поле Site URL и нажмите Save Changes (рисунок 5).

clip_image010

Рис. 5. Портал Facebook

Запишите значения App ID и App Secret (рисунок 6).

clip_image012

Рис. 6. Портал Facebook

Аутентификация на портале настроена.

Перейдите на портал управления Windows Azure и во вкладке Identity введите записанные значения App ID и App Secret, после чего нажмите Save(рисунок 7).

clip_image014

Рис. 7. Портал управления Windows Azure

Ограничения прав аутентифицировавшихся пользователей

На портале управления во вкладке Data выберите таблицу TodoItem(рисунок 8).

clip_image016

Рис. 8. Портал управления Windows Azure

На вкладке Permissions определите все права в Onlyauthenticatedusersи нажмите Save(рисунок 9).

clip_image018

Рис. 9. Портал управления Windows Azure

Откройте проект из предыдущей части и запустите его. Убедитесь, что при запуске приложения выдается ошибка 401 (Unauthorized). Это происходит из-за того, что теперь таблица TodoItem доступна только аутентифицировавшимся пользователям.

Добавьте в файл mainpage.xaml.cs:

using Windows.UI.Popups;

Добавьте в класс MainPage:

private MobileServiceUser user;

private async System.Threading.Tasks.Task Authenticate()

{

while (user == null)

{

string message;

try

{

user = await App.MobileService

.LoginAsync(MobileServiceAuthenticationProvider.Facebook);

message =

string.Format(“You are now logged in – {0}”, user.UserId);

}

catch (InvalidOperationException)

{

message = “You must log in. Login Required”;

}

var dialog = new MessageDialog(message);

dialog.Commands.Add(new UICommand(“OK”));

await dialog.ShowAsync();

}

}

В этом коде создается переменная для хранения текущего пользователя и метод для обработки процесса аутентификации.

Замените содержимое метода OnNavigatedTo:

protected override async void OnNavigatedTo(NavigationEventArgs e)

{

await Authenticate();

RefreshTodoItems();

}

Запустите приложение и аутентифицируйтесь в выбранном провайдере идентификации.

Существует возможность использовать серверные скрипты для авторизации аутентифицировавшихся пользователей и выдачи им прав на доступ к данным в Windows Azure Mobile Services.

Регистрация скриптов

Перейдите на портал управления Windows Azure и на вкладке MobileServicesвыберите ваше приложение (рисунок 10) .

clip_image019

Рис. 10. Портал управления Windows Azure

На вкладке Data выберите таблицу TodoItem (рисунок 11).

clip_image020

Рис. 11. Портал управления Windows Azure

Нажмите Script и выберите Insert (рисунок 12).

clip_image022

Рис. 12. Портал управления Windows Azure

Замените код и нажмите Save.

function insert(item, user, request) {

item.userId = user.userId;

request.execute();

}

Скрипт добавляет в сущность значение userId, которая является идентификатором аутентифицировшегося пользователя, перед тем, как она вставляется в таблицу.

Замените код операции Read:

function read(query, user, request) {

query.where({ userId: user.userId });

request.execute();

}

Запуск приложения

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

November 7, 2012 / ahriman hpc mode

Планирование затрат и использования Windows Azure в Microsoft Assessment And Planning Toolkit на примере SCVMM

MAP Toolkit позволяет создать некоторый набор ваших веб-приложений и БД SQL Server и создать “предположение” (в терминах MAPT) о том, насколько они подходят для миграции в Windows Azure. После чего, естественно, генерирует рекомендации.

Итак, в нашем случае MAPT установлен на виртуальной машине Hyper-V с IIS, на хостовой машине же установлен SCVMM. Мы посмотрим, как сгенерировать отчет по миграции приложений в облако для SCVMM.

1) Открываем MAPT.

2) Раскрываем пункт Cloud в правом меню Inventory and Assessment.

image

Выбираем Windows Azure Application Migration. В панели Action справа появятся доступные действия.

image

Рис.2.

а) Нажимаем Capture Performance Metrics. Таким образом мы соберем данные по имеющимся серверам и приложениям.

б) На шаге Computer List выберем доступные компьютеры – в нашем случае это хостовый сервер Kraftway и виртуальная машина (Localhost). Обратите внимание на дополнительную информацию, предоставляемую на этом шаге – сервисы, класс, тип компьютера и статус WMI.

image

в) На шаге WMI Credentials нам необходимо ввести логин-пароль (можно и администраторские). Нажмем New Account и добавим учетные данные.

image

image

г) Нажимаем Next и затем Finish. Дождёмся, пока соберутся данные по производительности.

 

3) Нажмем Create Application (разумеется, для того, чтобы создать проект по миграции приложения в облако, нужно указать MAPT на само приложение).

4) В появившемся Azure Application Configuration Wizard пройдём последовательность действий по конфигурации приложения.

5) На шаге Name and Approach нам необходимо ввести название приложения (как оно будет отображаться в консоли) и подход к миграции. Всего доступно три подхода, как, в общем-то, и при разработке под Windows Azure. Native – приложение должно быть развернуто в облако с использованием ролевой модели и SQL Azure полностью, VM Role – приложение должно быть развернуто в облако внутри виртуальной машины и с SQL Azure (допустим, сложное legacy приложение) и Hybrid – приложение разворачивается в облако частично, какая-то важная же часть остается в локальной инфраструктуре. Поскольку мы попробуем для начала создать проект для SCVMM, выберем VM Role.

image

 

6) Шаг Choose Web Application. Выберем наше приложение. Оснастка показывает текущую загрузку CPU, потребление приложением памяти и сети.

image

 

7) Шаг Choose Databases. На данном шаге можно выбрать базы данных, которые будут “развернуты” в SQL Azure.

image

8) Шаг Choose Servers. Здесь мы можем выбрать какие-либо другие сервера/сервисы/приложения для развертывания.

image

9) Шаги Considerations. Данные опросники по различным аспектам приложения (в основном, по архитектуре и прогнозируемые вами особенности работы приложения) необходимо тщательно и внимательно заполнить, так как от них зависит итоговый отчет и assessment.

image

 

10) На странице Summary у вас будет полный набор введенной информации. Нажмите OK.

Теперь в оснастке MAPT появилось наше приложение.

image

Обратите внимание, что в сведениях также доступно краткое резюме проекта. В случае SCVMM и всех ответов на вопросы N/A (в опросниках) мы получаем, что наше приложение будет требовать примерно три large-экземпляра ролей и одну SQL Azure базу данных.Кроме этого в Estimated Monthly Consumption нам доступно примерное потребление часов работы и трафика (посчитать стоимость, соответственно, мы можем с помощью этих данных и калькулятора для Windows Azure).

Давайте создадим проект миграции. В панели Actions нажмем Generate report/proposal.

image

Сгенерированный пакет отчетов доступен в меню View->Saved Reports And Proposals.

Пакет состоит из трех файлов: AzureROI[date], Windows Azure Migration Proposal[date] и WindowsAzureApplicationSummary[date]. Нам интересны два последних.

Итак, файл Excel WindowsAzureApplicationSummary[date] содержит обобщённые данные о вашем приложении и возможностях его миграции в облако. В основном это то, что вы вводили в процессе настройки приложения, но есть также ориентировочные потребности в экземплярах ролей, трафике и так далее.

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

 

Совершенно аналогичным образом можно создать проект по миграции приложения (-ий), размещенного в IIS как на локальном компьютере, на котором установлен MAPT, так и на любом другом.

November 7, 2012 / ahriman hpc mode

Windows Azure Mobile Services. Краткое руководство по разработке. Часть 2. Хранение данных в Mobile Services

Оглавление:

Windows Azure Mobile Services. Краткое руководство по разработке. Часть 1. Введение.
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 2. Хранение данных в Mobile Services
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 3. Аутентификация.
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 4. Push-уведомления.

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

Загрузите C# версию GetStartedWithData Developer Code Samples (рисунок 1).

clip_image002

Рис. 1. Developer Code Samples

Откройте проект в Visual Studio 2012 Express для Windows 8.

Откройте MainPage.xaml.cs.

Обратите внимание на то, что объекты TodoItem хранятся в памяти – ObservableCollection<TodoItem>.

Нажмите F5.

Введите текст в Insert a TodoItem и нажмите Save (рисунок 2).

clip_image004

Рис. 2. Интерфейс приложения

Сохраненный текст отображается в Query andupdatedata.

Доступ к данным с использованием мобильного сервиса

Установите Mobile Services SDK.

В Visual Studio в Project нажмите AddReference, разверните Windows, нажмите Extensions, отметьте WindowsAzureMobileServicesManagedClient и нажмите OK(рисунок 3).

clip_image006

Рис. 3. Добавление зависимостей в приложение

Нажатие на кнопку добавит клиент мобильных сервисов в проект.

В MainPage.xaml.cs и App.xaml.cs добавьте следующий код:

using Microsoft.WindowsAzure.MobileServices;

На портале управления перейдите в MobileServices и выберите ваш мобильный сервис.

Перейдите на вкладку Dashboard и запишите SiteURL, а также, нажав Managekeys запишите Applicationkey(рисунок 4).

clip_image008

Рис. 4. Портал управления Windows Azure

В Visual Studio раскомментируйте в файле App.xaml.cs определяющий переменную MobileService код и вставьте соответствующие значения URL и application, скопированные с портала управления, в конструктор MobileServiceClient.

В MainPage.xaml.cs закомментируйте строку, определяющую коллекцию items и раскомментируйте следующие строки кода:

private MobileServiceCollectionView<TodoItem> items;

private IMobileServiceTable<TodoItem> todoTable =

App.MobileService.GetTable<TodoItem>();

В этом коде создается коллекция для мобильных сервисов (item) и проекси-класс для таблицы TodoItem (todoTable).

В методе InsertTodoItem удалите определяющую свойство TodoItem.Id строку, добавьте модификатор async , и раскомментируйте строку кода:

await todoTable.InsertAsync(todoItem);

В методе RefreshTodoItems раскомментируйте:

items = todoTable.ToCollectionView();

Этот код определяет привязку к коллекции сущностей в todoTable, содержащую все записи, возвращаемые мобильным сервисом.

В метод UpdateCheckedTodoItem добавьте модификатор async modifier to и раскомментируйте:

await todoTable.UpdateAsync(item);

Теперь приложение использует мобильный сервис как бэкенд для хранилища.

Запуск приложения

В Visual Studio нажмите F5.

Введите текст в InsertaTodoItem и нажмите Save. Это приведет к добавлению сущности мобильному сервису.

На портале управления перейдите на MobileServicesи выберите ваш мобильный сервис.

Перейдите на вкладку Data и нажмите Browse(рисунок 5).

clip_image010

Рис. 5. Просмотр данных в таблице TodoItem

Замените в файле MainPage.xaml.cs метод RefreshTodoItems на следующий код, который будет осуществлять фильтрацию:

private void RefreshTodoItems()

{

// Запрос отфильтровывает сущности

items = todoTable

.Where(todoItem => todoItem.Complete == false)

.ToCollectionView();

ListItems.ItemsSource = items;

}

В приложении отметьте одну из сущностей в списке и нажмтие Refresh.

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

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

Проверка данных

Хорошим тоном является проверка длины данных, приходящих от пользователя. Зарегистрируем скрипт ,проверяющий длину данных в строке, отправляемой мобильному сервису, и выводящем ошибку для слишком длинных строк, в данном случае длиннее 10 символов.

На портале управления перейдите на MobileServices и выберите ваше приложение (рисунок 6).

clip_image012

Рис. 6. Портал управления Windows Azure

На вкладке Data нажмите на таблицу TodoItem (рисунок 7).

clip_image014

Рис. 7. Портал управления Windows Azure

Нажмите Script и выберите Insert (рисунок 8).

clip_image016

Рис. 8. Портал управления Windows Azure

Замените скрипт на код ниже и нажмите Save.

function insert(item, user, request) {

if (item.text.length > 10) {

request.respond(statusCodes.BAD_REQUEST, ‘Text length must be under 10’);

} else {

request.execute();

}

}

В скрипте проверяется длина значения свойства TodoItem.text и генерируется ошибка в том случае, если она превышает 10 символов, иначе выполняется метод execute.

Обновление клиента

Откройте в Visual Studio 2012 Express для Windows 8 проект из предыдущей части.

Запустите приложение, нажав F5 key и попробуйте ввести строку длиннее 10 символов в поле InsertaTodoItem, после чего нажмите Save.

Будет выброшено исключение MobileServiceInvalidOperationException, так как код ответа с сервера будет 400 (Bad Request) .

Вставьте в MainPage.xaml.cs следующий код:

using Windows.UI.Popups;

Замените метод InsertTodoItem:

private async void InsertTodoItem(TodoItem todoItem)

{

// Происходит вставка в БД нового TodoItem.

// По завершению операции сущность добавляется в CollectionView

try

{

await todoTable.InsertAsync(todoItem);

items.Add(todoItem);

}

catch (MobileServiceInvalidOperationException e)

{

MessageDialog errormsg = new MessageDialog(e.Response.Content,

string.Format(“{0} (HTTP {1})”,

e.Response.StatusDescription,

e.Response.StatusCode));

var ignoreAsyncOpResult = errormsg.ShowAsync();

}

}

В этом коде обрабатывается исключение MobileServiceInvalidOperationException, выдавая ошибку во всплывающем окне.

Добавление даты к сущности

В Scripts на портале управления, замените скрипт Insert и нажмите Save.

function insert(item, user, request) {

if (item.text.length > 10) {

request.respond(statusCodes.BAD_REQUEST, ‘Text length must be under 10’);

} else {

item.createdAt = new Date();

request.execute();

}

}

Запустите приложение, нажав F5, после чего введите строку из более чем 10 символов в поле Insert a TodoItem и нажмите Save.

Обратите внимание, что нового поля даты в интерфейсе нет.

На портале управления на вкладке Browse выберите таблицу todoitem.

В базе столбец createdAt есть, и вставленная последней сущность имеет значение даты.

Обновление интерфейса приложения

Клиент мобильного сервиса игнорирует данные в ответе, которые нельзя сериализовать в свойства определенного типа. Добавим в интерфейс возможность отображать эти новые данные.

Замените в MainPage.xaml.cs класс TodoItem:

public class TodoItem

{

public int Id { get; set; }

[DataMember(Name=”text”)]

public string Text { get; set; }

[DataMember(Name=”complete”)]

public bool Complete { get; set; }

[DataMember(Name=”createdAt”)]

public DateTime? CreatedAt { get; set; }

}

Новое определение класса содержит nullable DateTime.

Атрибут DataMemberAttribute сообщает клиенту о том, что необходимо соотнести новое свойство CreatedAt со столбцом createdAt из таблицы TodoItem.

Добавьте под элементом CheckBoxComplete в файле MainPage.xaml следующий код, который отобразит в текстовом поле новое поле CreatedAt:

<TextBlock Name=”WhenCreated” Text=”{Binding CreatedAt}” VerticalAlignment=”Center”/>

Нажмите F5 для запуска приложения.

Замените RefreshTodoItems:

private void RefreshTodoItems()

{

// В этом запросе отфильтровываются “завершенные”

// задачи и сущности без даты

items = todoTable

.Where(todoItem => todoItem.Complete == false

&& todoItem.CreatedAt != null)

.ToCollectionView();

ListItems.ItemsSource = items;

}

Запустите приложение. Все сущности с неопределенным значением даты исчезли из списка в интерфейсе.

November 7, 2012 / ahriman hpc mode

Windows Azure Mobile Services. Краткое руководство по разработке. Часть 1. Введение.

В этом кратком руководстве-переводе мы рассмотрим разработку приложения Магазина Windows, использующего Windows Azure Mobile Services как облачный бэкенд в различных задачах. Это перевод официального руководства с http://windows.azure.com.

Оглавление:

Windows Azure Mobile Services. Краткое руководство по разработке. Часть 1. Введение.
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 2. Хранение данных в Mobile Services
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 3. Аутентификация.
Windows Azure Mobile Services. Краткое руководство по разработке. Часть 4. Push-уведомления.

Windows Azure Mobile Services: введение в облачные сервисы для мобильных разработчиков

Приложение-планировщик задач будет выглядеть так, как на рисунке 1.

clip_image002

Рис. 1. Результат работы

Для того, чтобы успешно выполнить все задачи из этого цикла, необходимо иметь аккаунт Windows Azure с активированной функциональностью WAMS, либо зарегистрировать бесплатный аккаунт по ссылке Windows Azure Free Trial.

Создание нового мобильного сервиса

Войдите под своими учетными данными на портал управления Windows Azure.

Нажмите +NEW (рисунок 2).

clip_image004

Рис. 2. Создание мобильного сервиса

Разверните MobileService и нажмите Create(рисунок 3).

clip_image006

Рис. 3. Создание мобильного сервиса.

В появившемся диалоговом окне на странице Createamobileservice введите значение URL, которое будет далее использоваться для идентификации вашего мобильного сервиса, и дождитесь проверки его наличия. Нажмите Next. (рисунок 4).

clip_image008

Рис. 4. Создание мобильного сервиса

Дальше будет создан новый экземпляр SQL Database, который можно использовать не только для мобильного сервиса. Либо вы можете воспользоваться существующим экземпляром, нажав на UseexistingDatabase.

Введите в Nameнаименование новой базы данных, затем введите логин администратора в Loginname, введите два раза пароль и нажмите Next (рисунок 5).

clip_image010

Рис. 5. Создание мобильного сервиса

Мобильный сервис создан.

Создание приложения Магазина Windows

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

На портале управления нажмите MobileServicesи выберите созданный мобильный сервис.

На вкладке quickstart выберите Windows и Create a new Windows Store app (рисунок 6).

clip_image012

Рис. 6. Вкладка Quickstart

Вам будет предложено выполнить три простых шага, которые необходимы для подключения приложения Магазина Windows к мобильному сервису (рисунок 7).

clip_image014

Рис. 7. Создание нового приложения Windows 8

Загрузите и установите Visual Studio 2012 Express for Windows 8 и Mobile Services SDK.

Нажмите CreateTodoItemstable для создания таблицы для данных.

ВDownloadandrunapplicationвыберите предпочитаемый язык приложения, нажмите Download.

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

Запуск приложения

Откройте файл решения в Visual Studio 2012 Express для Windows 8 (рисунок 8).

clip_image016

Рис. 8. Интерфейс Visual Studio 2012 Express

Запустите проект, нажав F5.

Введите какой-либо текст в InsertaTodoItem и нажмите Save(рисунок 9).

clip_image018

Рис. 9. Интерфейс приложения

Нажатие на клавишу вызовет отправку POST-запросе на мобильный сервис в Windows Azure. Данные из запроса будут вставлены в таблицу TodoItem.Сущности, хранимые в таблицу, будут получаться мобильным сервисом и показаны в приложении.

На портале управления перейдите на вкладку Data и нажмите на таблице TodoItems(рисунок 10).

clip_image020

Рис. 10. Вкладка Data

Откроется страница с данными, хранящимися в таблице приложения (рисунок 11)

clip_image022

Рис. 11. Данные из таблицы для приложения

October 30, 2012 / ahriman hpc mode

Windows Azure и Java. Руководство по использованию.

Windows Azure и Java. Ч.1. Hello World.

Для разработки на Java для платформы Windows Azure необходимо иметь:

1) Java Developer Kit не ниже 1.6

2) Windows Azure SDK.

3) Необходимые библиотеки Java, которые можно загрузить и подключить к проекту либо вручную, либо с помощью Maven, либо установив плагин к Eclipse. Ссылки: http://msdn.microsoft.com/en-us/library/windowsazure/hh690953(v=vs.103).aspx

4) Аккаунт Windows Azure.

Имея все 4 позиции, вы можете начать разрабатывать ваши проекты либо переносить уже существующие в облако.

В данном руководстве будет использоваться среда разработки Eclipse Juno (http://eclipse.org) с установленным плагином.

1. Установка плагина.

После скачивания и распаковки Eclipse запустите среду разработки. Перед вами появляется рабочая область среды разработки. Вызовите Help=>InstallNewSoftware и введите в строку Work With адрес репозитория – http://dl.msopentech.com/eclipse (рисунок 1). Нажмите Enter.

clip_image002[4]

Рис.1. Рабочая область Eclipse Juno.

В нижнем окне после загрузки списка содержимого репозитория возникнет выпадающая “ветка” Windows Azure Toolkit For Java. В данной ветке содержится несколько проектов – Microsoft JDBC Driver for SQL Server (для работы с хранилищем, в том числе SQL Azure Databases) и другие. Отметьте всю ветку и нажмите Next.

В зависимости от скорости Интернета и доступности репозитория загрузка может занять до нескольких минут.

После загрузки необходимых метаданных появится окно настроек (рисунок 2).

clip_image004[4]

Рис. 2. Установка плагина Windows Azure для Eclipse

Нажмите Next и в следующем окне согласитесь с лицензионным соглашением, после чего нажмите Finish.

После установки плагина вам предложат перезагрузить Eclipse. Согласитесь.

1. Альтернатива. Подключение библиотек вручную.

Для того, чтобы вручную подключить плагин, необходимо скачать соответствующие библиотеки и зависимости со страницы http://msdn.microsoft.com/en-us/library/windowsazure/hh690953(v=vs.103).aspx.

Создайте в Eclipse Java-проект (рисунок 3).

clip_image006[4]

Рис.3. Создание Java-проекта.

Введите необходимые сведения в появившемся диалоговом окне. Достаточно ввести имя проекта (рисунок 4).

clip_image008[4]

Рис.4. Настройки проекта.

Нажмите Next. На странице Java Settings перейдите на вкладку Libraries и нажмите External JARs.

clip_image010[4]

Рис.5. Добавление библиотек.

Выберите загруженные с сайта JAR (рисунок 6).

clip_image012[4]

Рис.6. Выбор библиотек.

Нажмите Finish.

Java-проект с подключенными библиотеками, необходимыми для работы с Windows Azure, создан.

2. Создание Java-проекта.

Для создания проекта нажмите в Eclipse CTRL+N и выберите Dynamic Web Project (рисунок 7).

clip_image014[4]

Рис. 7. Шаблоны проектов

На странице настроек нового проекта введите необходимые данные – выберите веб-сервер (например, Tomcat 7.0), название проекта. Нажмите Finish.

clip_image016[4]

Рис.8. Настройки проекта.

Структура вашего приложения должна выглядеть как на рисунке 9.

clip_image018[4]

Рис. 9. Структура проекта.

Основная папка, которая нас интересует – WebContent. В неё вы поместите основной JSP-файл.

Щелкните правой кнопкой мыши на папке WebContent и нажмите New=>JSP File. В появившемся диалоговом окне введите имя файла Index.jsp и нажмите Next. На странице Select JSP Template выберите шаблон проекта New JSP File (html) и нажмите Finish.

Введите в появившемся окне редактора в контейнере <body> следующий код:

<body>
Hello Azure.
</body>

Нажмите для сохранения изменений.

Теперь необходимо экспортировать пакет Java-проекта. Для этого нажмите правой кнопкой мыши на проекте JavaWindowsAzure и нажмите Export=>WAR File. В появившемся диалоговом окне нажмите Browse и выберите папку approot проекта Windows Azure (рисунок 10).

clip_image020[4]

Рис.10. Экспорт пакета проекта

3. Создание проекта Windows Azure.

Для создания Java-проекта Windows Azure нажмите в Eclipse CTRL+N и найдите вкладку Windows Azure, после чего два раза кликните на Windows Azure Project, чтобы инициировать создание проекта (рисунок 11).

clip_image022[4]

Рис. 11. Создание Windows Azure проекта.

Откроется окно настроек создаваемого проекта. Обратите внимание на уже существующие настройки, после чего нажмите Finish – для первого проекта можно ограничиться настройками по умолчанию (рисунок 12).

clip_image024[4]

Рис. 12. Настройки проекта Windows Azure.

Нажмите Next. В следующем окне отметьте IncludeaJDKfromthislocationи Includeaserverfromthislocationи укажите пути к соответствующим дистрибутивам JDK и Tomcat. Выделите HelloWorld.warи нажмите Remove. Нажмите Addи выберите экспортированный в прошлом пункте WAR (рисунок 13). Нажмите Finish.

clip_image026[4]

Рис. 13. Настройки проекта

Выберите проект WindowsAzureForJavaApp и нажмите на кнопку RunInWindowsAzureEmulator(рисунок 14).

clip_image028[4]

Рис. 14. Запуск приложения в локальном эмуляторе вычислений

После того, как вы нажмете на кнопку, произойдет развертывание проекта в локальный эмулятор вычислений Windows Azure. Обратите внимание на периодически появляющиеся окна – одновременно с запуском в эмуляторе запускается также сервер Tomcat 7.

Откройте графический интерфейс локального эмулятора вычислений (рисунки 15,16).

clip_image030[4]

Рис. 15. Вызов интерфейса эмулятора вычислений

clip_image032[4]

Рис. 16. Интерфейс эмулятора вычислений

Нажмите на WorkerRole1 и выберите 0. Это экземпляр вашей роли (рисунок 17).

clip_image034[4]

Рис. 17. Лог экземпляра роли

После запуска веб-сервера (рисунок 18) зайдите в веб-браузере на http://localhost:8080/ http://localhost:8080/JavaWindowsAzure/, чтобы увидеть вашу страницу с простым сообщением.

clip_image036[4]

Рис. 18. Успешный запуск веб-сервера

4. Развертывание проекта в облако.

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

Щелкните правой кнопкой мыши на облачном проекте Windows Azure и нажмите Properties. В окне свойств перейдите на вкладку Windows Azure (рисунок 19).

clip_image038[4]

Рис. 19. Настройка облачного проекта для развертывания в облако

На вкладке Windows Azure выберите Deployment to cloud. На вкладке Remote Access снимите галочку – таким образом вы отключите удаленный доступ к вашей роли, что сейчас не нужно, так как это связано с загрузкой сертификата безопасности. Закройте окно конфигурации и пересоберите проект (Project => Build All). В этот момент будут созданы необходимые для развертывания в облако файлы, находящиеся в папке deploy вашего проекта.

Войдите на портал управления Windows Azure под своим аккаунтом.

Создайте вычислительный сервис, который будет выполнять код вашего приложения. На левой панели нажмите Newи нажмите Compute => CloudService => QuickCreate (рисунок 20). Введите название вычислительного сервиса. Нажмите CreateCloudService.

clip_image040[4]

Рис. 20. Создание вычислительного сервиса

Перейдите обратно в Eclipse.

Нажмите кнопку Publish to Windows Azure Cloud (рисунок 21).

clip_image042[4]

Рис. 21. Publish to Windows Azure Cloud

Нажмите Download. Введите свои учетные данные для подписки Windows Azure. Сохраните файл настроек подписки (рисунок 22).

clip_image044[4]

Рис. 22. Сохранение файла настроек подписки

Нажмите Importи укажите расположение сохраненного файла настроек подписки. Настройки подписки будут импортированы (рисунок 23). Нажмите Publish.

clip_image046[4]

Рис. 23. Импортированные настройки подписик

Дождитесь окончания развертывания роли. Во время развертывания происходит весь процесс установки вашего приложения: ищется свободное оборудование, сервис загружается на портал, создаётся и разворачивается виртуальная машина, на неё загружается сервис, после чего происходит инициирование событий OnStartup и Run – в событии OnStartup запускается веб-сервер и JDK, необходимые для выполнения нашего приложения, в событии-методе Run происходит основная логика приложения.

Обратите внимание на новое представление в Eclipse – Windows Azure Activity Log (рисунок 24).

clip_image048[4]

Рис. 24. Представление Windows Azure Activity Log

Перейдя на уровень развертывания (azurejavatest), обратите внимание на панель свойств справа. В нем доступно DNS-имя развертывания. URL выглядит как <guid>.cloudapp.net, где <guid> – некоторый случайный идентификатор, отличающийся от адреса, который получит приложение при развертывании в реальной среде. Хотя ячейки развертывания и разделены между собой, физических различий между ними нет – все определяется тем, куда подключен балансировщик нагрузки. Попробуйте перейти по ссылке. В том случае, если вы сконфигурировали все правильно, вам должна быть выведена страница вашего сайта. Если появляется окно администраторской панели Tomcat, попробуйте добавить в ссылку имя вашего приложения и указать непосредственно имя файла, допустим:

http://fe744ac908e24c4dafbc2afce3c7f5da.cloudapp.net/JavaWindowsAzure/Index.jsp

Определив корректность работы приложения с помощью тестового развертывания, можно переводить его в реальное развертывание. При развертывании приложения в реальной среде Windows Azure перенастраивает балансировщики нагрузки, обеспечивая доступ к приложению по URL реального развертывания.
Для Swap VIP нажмите кнопку Swap на панели администрирования вашего вычислительного сервиса (рисунок 25).

clip_image050[4]

Рис. 25. Swap VIP

Нажмите на ссылку DNS name для открытия сайта в реальном развертывании в новом окне браузера и обратите внимание на ссылку в адресной строке браузера.

Примечание: Если вы получаете при входе на сайт DNS-ошибку 404, подождите пару минут и попробуйте еще – возможно, DNS-имя ещё не готово. Windows Azure создает DNS-имена динамически и применение этих изменений может занять несколько минут.

Даже если развертывание находится в статусе suspended, Windows Azure всё ещё держит выделенные для каждого экземпляра виртуальные машины в рабочем состоянии, таким образом начисляя за них счёт. После окончания тестирования приложения вам необходимо удалить развертывание из Windows Azure во избежание дополнительных затрат.

Windows Azure & Java. Использование Service Runtime Library

Windows Azure SDK For Java предоставляет библиотеку Windows Azure Service Runtime, позволяющую взаимодействовать приложению, написанному на Java, со средой Windows Azure (локальным эмуляторм или облаком) и получать информацию о развертывании (информацию о состоянии ролей, экземпляров и т.д.), а также запрашивать и задавать некоторые значения, включая запросы на “очистку” экземпляров роли.

К основным классам данной библиотеки относятся:

* RoleEnvironment

* RoleInstance

* Role

 

Всего в библиотеке гораздо больше классов, которые можно изучить на MSDN.

Рассмотрим подробнее каждый из классов.

RoleEnvironment

Данный класс является отображением среды выполнения Windows Azure, в которой работает экземпляр вашего приложения. Класс предоставляет следующую функциональность (список неполон):

static void clearStatus()
Очистка статуса экземпляра роли.

static Map<String,String>getConfigurationSettings()
Получение настроек, хранящихся в файле конфигурации роли.

static RoleInstance getCurrentRoleInstance()
Возвращает объект типа RoleInstance, отображающий экземпляр роли, в котором выполняется приложение в данный момент.

static String getDeploymentId()
Возвращает идентификатор развертывания, уникальное идентифицирующий развертывание, в котором выполняется экземпляр. Возвращает ID в форуме deployment(nn), где nn – integer в случае выполнения в локальном эмуляторе и GUID в случае выполнения в облаке.

static Map<String,LocalResource>getLocalResources()
Возвращает набор именованных ресурсов локального хранилища, зарезервированных в файловой системой виртуальной машиной, в котором выполняются экземпляр роли. Возвращаемая коллекция содержит набор объектов LocalResources. Список локальных ресурсов определяется в файле определения сервиса.

static Map<String,Role>getRoles()
Возвращает набор объектов типа Role, определенных в вашем приложении.

static boolean isAvailable()

Определяет, запущено ли приложение в облаке или нет. Возвращает true, если да. Если возвращается false, запрещено использовать любые части класса RoleEnvironment (будет выброшено исключение RoleEnvironmentAvailableException).

static boolean isEmulated()
Определяет, запущено ли приложение в локальном эмуляторе или нет. Возвращает true, если да.

static void requestRecycle()
Запрашивает перезапуск экземпляра роли.

static void setStatus(RoleInstanceStatus status, Date expiration_utc)
Устанавливает статус экземпляра роли.

RoleInstance

Класс RoleInstance является отображением конкретного экземпляра роли и содержит в себе следующую функциональность:

getFaultDomain()
Возвращает значение типа Integer, отображающее домен неисправности, в котором расположен экземпляр.

String getId()
Возвращает идентификатор экземпляра.

Map<String,RoleInstanceEndpoint> getInstanceEndpoints()
Возвращает набор точек входа экземпляра роли.

Role getRole()
Возвращает объект типа Role для данного экземпляра.

Int getUpdateDomain()
Возвращает значение типа Integer, отображающее домен обновления, в котором находится экземпляр.

Role

Класс Role является отображением роли в вашем приложении. Роли (веб-роль, воркер-роль) определяются в файле определения сервиса. Класс содержит всего два метода:

Map<String,RoleInstance>getInstances()
Возвращает набор экземпляров для данной роли.

String getName()
Возвращает имя роли, прописанное в файле определения сервиса.

Межклассовые отношения RoleEnvironment, Role, RoleInstance

· Метод RoleEnvironment.getCurrentRoleInstance возвращает экземпляр роли типа RoleInstance, с помощью которого можно получить различные данные об экземпляре, такие как домены неисправностей и обновления, точки входа и так далее.

· Метод RoleEnvironment.getRoles возвращает набор ролей вашего сервиса.

· Метод RoleInstance.getRole возвращает объект типа Role, ассоциированный с ролью экземпляра, с помощью которого вы можете получить имя роли для данного экземпляра.

· Метод Role.getRoleInstances возвращает набор экземпляров ролей.

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

* RoleInstanceEndpoint. Данный класс отображает точку входа для экземпляра роли и содержит следующие методы:

InetSocketAddress getIpEndPoint()
Возвращает объект типа InetSocketAddress , отображающий точку входа для экземпляра роли.

String getProtocol()
Возвращает протокол точки входа.

RoleInstance getRoleInstance()
Возвращает объект типа RoleInstance, к которому принадлежит данная точка входа.

* RoleEnvironmentChangedEvent. Данный класс отображает событие, которое совершается во время изменения конфигурации сервиса. Содержит один метод:

Collection<RoleEnvironmentChange> getChanges()
Возвращает набор изменений конфигурации, которые были применены к экземпляру роли.

* RoleEnvironmentConfigurationSettingChange . Данный класс является отображением изменения конфигурации и содержит один метод:

String getConfigurationSettingName()
Возвращает имя настройки конфигурации, которая была изменена.

* RoleEnvironmentTopologyChange отображает изменение топологии сервиса. Топология сервиса – количество экземпляров для роли. Содержит один метод:

String getRoleName()
Возвращает имя роли, над которой было совершено изменение.

* RoleInstanceStatus . Данное перечисление (enum) является отображением статуса экземпляра роли и содержит две константы:

Busy
Экземпляр не будет отвечать на запросы.

Ready
Экземпляр готов отвечать на запросы.

В первой части цикла был приведен алгоритм настройки проекта. Для дальнейшей работы можно работать прямо из проекта из первой статьи, редактируя лишь файл .JSP. В практической же части будет выполнен новый код, использующий основные возможности Service Runtime Library, с использованием Tomcat 7.

Вызовите окно Properties вашего Java-проекта (не облачного).

Перейдите на вкладку Java Build Path и нажмите Add Library(рисунок 26).

clip_image052[4]

Рис. 26. Добавление библиотек в проект

Выберите Package for Windows Azure Libraries for Java (by MS Open Tech) (рисунок 27).

clip_image054[4]

Рис. 27. Добавление библиотек Windows Azure в проект

Нажмите Finish.

Java-проект с подключенными библиотеками, необходимыми для работы с Windows Azure, создан.

Откройте JSP-файл, который вы должны отредактировать в соответствии с кодом ниже.

<%@ page language=“java” contentType=“text/html; charset=ISO-8859-1”

      pageEncoding=“ISO-8859-1”

      import=“com.microsoft.windowsazure.serviceruntime.*, java.util.Map, java.util.*”%>

<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”&gt;

<html>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1”>

<title>Hello</title>

</head>

<body>

      <b>Hello Azure!</b>

      <br />

      <p>

            RoleEnvironment.isEmulated() возвратил

            <%=RoleEnvironment.isEmulated()%>.

      </p>

      <p>

            Идентификатор экземпляра роли равен

            <%=RoleEnvironment.getCurrentRoleInstance().getId()%>.

      </p>

      <p>

            Имя роли:

            <%=RoleEnvironment.getCurrentRoleInstance().getRole()

                              .getName()%>.

      </p>

      <%

            Map<String, RoleInstanceEndpoint> endpoints =

            RoleEnvironment.getCurrentRoleInstance().getInstanceEndpoints();

            for (Map.Entry<String, RoleInstanceEndpoint> entry : endpoints

                        .entrySet())

            {

                  out.println(“Точка входа ‘”

                              + entry.getKey()

                              +

                              “‘ : “

                              + entry.getValue().getIpEndPoint().getAddress()

                                         .getHostAddress());

            }

            Map<String, LocalResource> localresources = RoleEnvironment

                        .getLocalResources();

            Set set = localresources.entrySet();

            Iterator iterator = set.iterator();

            LocalResource localResource;

            while (iterator.hasNext())

            {

                  Map.Entry entry = (Map.Entry) iterator.next();

                  localResource = (LocalResource) entry.getValue();

                  out.println(“Локально зарезервированные файловые ресурсы: \n Название: “

                              + localResource.getName()

                              + “Путь: “

                              + localResource.getRootPath()

                              + “\n Максимальный размер (Мб): “

                              + localResource.getMaximumSizeInMegabytes() + “\n”);

            }

            ;

            Map<String, String> mapConfigSettings = RoleEnvironment

                        .getConfigurationSettings();

            String mysetting = mapConfigSettings.get(“name”);

            out.println(mysetting);

      %>

</body>

</html>

Соберите проект – Project => Build Project.

Теперь необходимо экспортировать пакет Java-проекта. Для этого нажмите правой кнопкой мыши на проекте JavaWindowsAzure и нажмите Export=>WAR File. В появившемся диалоговом окне нажмите Browse и выберите папку approot проекта Windows Azure.

Нажмите Run In Windows Azure Emulator.

Произойдет развертывание проекта в локальный эмулятор вычислений Windows Azure. Откройте графический интерфейс локального эмулятора вычислений (рисунок 28).

clip_image056[4]

Рис. 28. Интерфейс эмулятора вычислений, лог роли

Нажмите на WorkerRole1 и выберите 0. Это экземпляр вашей роли.

После запуска веб-сервера зайдите в веб-браузере на http://localhost:8080/JavaWindowsAzure, чтобы увидеть вашу страницу (рисунок 29).

clip_image058[4]

Рис. 29. Страница с результатом выполнения

Остановите развертывание, нажав соответствующую кнопку (рисунок 30).

clip_image060[4]

Рис. 30. Кнопка остановки развертывания в локальном эмуляторе

Таким образом, вы увидели, как можно взаимодействовать со средой выполнения локального эмулятора из Java-приложения. Аналогичным образом осуществляется взаимодействие с облачной средой – достаточно выложить проект в облако.

Windows Azure & Java. Вопросы отладки Java-приложений.

Плагин Windows Azure для интегрированной среды разработки Eclipse позволяет в числе своих возможностей отлаживать приложения как в локальном эмуляторе, так и в облаке. Для того, чтобы сконфигурировать проект для использования отладки, необходимо нажать правой кнопкой мыши на вашей роли (с синей шестеренкой) и вызвать окно Properties (рисунок 31), где необходимо перейти на вкладку Windows Azure, после чего на вкладку Debugging, где отметить опцию Enable remote debugging for this role.

clip_image062[4]

Рис. 31. Свойства роли

Панель позволяет выбрать также точку входа, по которой будет происходить отладка приложения, и другие опции – такие, как ожидание приложения до входа отладчика и т.д. Немного подробнее про Start JVM in suspended mode, waiting for a debugger connection: данная опция предназначена только для некоторых ситуаций, связанных с локальным эмулятором – с помощью ее можно задержать запуск сервера до тех пор, пока отладчик Eclipse не подключится к соответствующей JVM. Откройте меню Windows Azure Debug Configuration и выберите свой проект в Java project to debug, после чего убедитесь, что Configure debugging for указан в значение Windows Azure compute emulator (рисунок 32). Закройте диалог и окно Properties.

clip_image064[4]

Рис.32. Свойства роли.

Теперь можно переходить к непосредственному процессу отладки в локальном эмуляторе. Сначала необходимо отметить точку прерывания (breakpoint). Для этого:

Разверните папку WebContent вашего приложения и откройте Index.jsp.

На какой-либо строке щелкните в серой панели справа правой кнопкой мыши и нажмите Toggle Breakpoints. Поставьте две точки прерывания на строках получения локальных зарезервированных ресурсов хранилища и получения настроек конфигурации.

Map<String, LocalResource> localresources = RoleEnvironment.getLocalResources();

Map<String, String> mapConfigSettings = RoleEnvironment.getConfigurationSettings();

clip_image066[4]

Рис. 33. Установка точки прерывания.

После установки точки прерывания появится соответствующий значок (рисунок 34).

clip_image068[4]

Рис.34. Иконка точки прерывания

Запустите проект в локальном эмуляторе.

После окончания процесса запуска необходимо соответствующим образом сконфигурировать конфигурацию отладки. Для этого:

В меню нажмите на иконке стрелки справа от значка жука и выберите Debug Configurations (рисунок 35).

clip_image070[4]

Рис. 35. Открытие окна конфигурации отладки.

Разверните вкладку Remote Java Applications и выберите Windows Azure Emulator (WorkerRole1) (рисунок 36). Убедитесь, что выбран режим Socket Attach. Нажмите Debug.

clip_image071[4]

Рис. 36. Окно конфигураций отладки.

Как только процесс будет завершен, перейдите на страницу JSP в браузере. При открытии обратите внимание, что Eclipse предложит поменять перспективу (рисунок 37). Согласитесь.

clip_image073[4]

Рис. 37. Подтверждение смены перспективы

У вас должна открыться перспектива отладки (рисунок 38).

clip_image075[4]

Рис. 38. Перспектива отладки Java-приложения в Eclipse.

Вам доступна полная функциональность Eclipse по отладке. Нажмите F8 (Resume) и просмотрите данные, которые предоставляет вам среда разработки.

Отладка в облаке Windows Azure

Остановите развертывание.

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

Для настройки проекта для облачной отладки сначала сконфигурируйте сборку проекта для облачной сборки (окно Properties облачного проекта, вкладка Windows Azure, Build for). Нажмите Project->Build all.

Вернитесь к первому абзацу и в окне Properties сконфигурируйте Build for как Deployment to cloud. В этом же диалоге сконфигурируйте значение Host (оно должно быть равно DNS-имени вашего тестового развертывания без http://). DNS-имя развертывания можно получить, зайдя на портал управления Windows Azure и выбрав ваше развертывание.

Закройте диалог и окно Properties вашего проекта и соберите проект (Project –> Build all). Далее загрузите пакет и конфигурационный файл в развертывание в облаке с помощью кнопки Publishв Eclipse. В том случае, если у вас не создано развертывание, обратитесь к первой части.

Дождитесь окончания процесса развертывания вашего проекта. После этого в меню нажмите на иконке стрелки справа от значка жука и выберите Debug Configurations. Разверните вкладку Remote Java Applications и выберите Windows Azure Cloud (WorkerRole1). Убедитесь, что выбран режим Socket Attach. Нажмите Debug.

Как только процесс будет завершен, перейдите на страницу JSP в браузере. Например, http://8eee90deb9394d98bfc4979a9f7fabcd.cloudapp.net/JavaWindowsAzure/NewFile.jsp.

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

Для того, чтобы совершить все те же самые действия по настройке отладки, но с GlassFish, вам необходимо будет сконфигурировать GlassFish вручную, не трогая конфигурацию плагина Windows Azure для Eclipse.

Windows Azure & Java. Дополнительные возможности. Remote Desktop, Session Affinity.

Связка Windows Azure & Java позволяет разработчику подключаться по удаленному рабочему столу (Remote Access, Remote Desktop Protocol (RDP)) к виртуальным машинам, выполняющим приложение. Для конфигурации удаленного доступа необходимо сконфигурировать соответствующим образом вкладку Remote Access в свойствах проекта (рисунок 39).

clip_image077[4]

Рис.39. Окно свойств проекта – настройки удаленного доступа

По умолчанию каждый новый проект Windows Azure имеет включенную возможность удаленного доступа, основанную на использовании самоподписанного сертификата (который идёт в тестовом варианте в комплекте с Windows Azure Plugin для Eclipse, и находится в папке cert в проекте Windows Azure). Данный самоподписанный сертификат имеет две части – файл публичного сертификата (SampleRemoteAccessPublic.cer) и файл сертификата типа Personal Information Exchange (SampleRemoteAccessPrivate.pfx), который содержит в себе приватный ключ для сертификата и пароль по умолчанию (Password1). Данный сертификат не должен быть использован в реальном развертывании (достаточно префикса Sample). Вы можете использовать для целей удаленного доступа либо этот сертификат, либо воспользоваться способом, приведенным в данной статье.

Давайте настроим удаленный доступ для вашего проекта. Для этого:

Нажмите правой кнопкой мыши на облачном проекте в Eclipse и нажмите Properties.

В открывшемся окне раскройте вкладку Windows Azure и выберите Remote Access.

В открывшемся диалоге Remote Access отметьте опцию Enable all roles to accept Remote Desktop connections with these login credentials – таким образом вы активируете удаленный доступ на всех ролях с данными учетными данными. Укажите учетные данные для удаленного подключения в соответствующих текстовых полях – эти учетные даные – не те, которые используются в сертификате.

Ещё одна важная настройка – дата истечения учетных данных, после которой учетные данные уже не будут приниматься. Важно для обеспечения безопасности – меняйте логин-пароль почаще.

В разделе Certificate to encrypt user credentials нажмите New для создания собственного самоподписанного сертификата, так как мы не хотим использовать тестовый вариант – он слишком небезопасен даже в тестовой среде (либо, если у вас уже есть каким-либо образом созданный самоподписанный сертификат, просто укажите его местоположение с помощью кнопок Workspace и FileSystem).

В диалоге New Certificate введите пароль для файла PFX.

Укажите путь и имя файлов, в которых будут сохранены файлы сертификата и публичный и приватный ключи (.cer, .pfx). В данной статье мы выберем для удобства папку certificates вWorkspace, однако разницы, где вы сохраните ваши сертификаты, абсолютно никакой нет (рисунок 40).

clip_image079[4]

Рис.40. Настройка самоподписанного сертификата.

Нажмите OK. Перейдите на вкладку Windows Azure.

На вкладке Windows Azure выберите Deployment to cloud.

Соберите проект – Project –> Build All (CTRL + B).

Войдите на портал управления Windows Azure. Перейдите на вкладку Settings(рисунок 41).

clip_image081[4]

Рис. 41. Настройки подписки Windows Azure

После этого нажмите на кнопку Uploadдля добавления сертификата (рисунок 42).

clip_image083[4]

Рис. 42. Диалог загрузки сертификата

Разверните сервис в облако.

Убедитесь, что развертывание прошло успешно и имеет статус Ready.

Теперь необходимо подключиться удалённо. После успешного развертывания вы можете подключиться к вашей виртуальной машине приложения. Для этого перейдите на вкладку CloudServices, нажмите на вашем вычислительном сервисе, перейдите на вкладку Configureи нажмите Remote(рисунок 43).

clip_image085[4]

Рис. 43. Кнопка подключения по Remote Desktop

Session Affinity

Windows Azure Plugin для Eclipse with Java позволяет использовать HTTP session affinity (другое название – “липкие сессии для ролей”). Настройки данной функциональности находятся во вкладке Load Balancing в свойствах роли (рисунок 44).

clip_image087[4]

Рис. 44. Настройки Session Affinity.

В появившемся диалоге Properties for WorkerRole1 Load Balancing отметьте опцию Enable HTTP session affinity (sticky sessions) for this role и выберите конечную точку входа для использования (Input endpoint to use). Если у вас еще не сконфигурирована точка входа, плагин предложит вам создать стандартную точку входа http (public:80, private:8080). Естественно, что можно сконфигурировать множество точек входа, но для липких сессий можно указать только одну.

clip_image089[4]

Рис. 45. Настроенная балансировка нагрузки

Соберите ваш проект – Project –> Build All (CTRL + B). Теперь, после включения липких сессий, запросы HTTP, приходящие от клиентов, будут обрабатываться одним и тем же экземпляром ролей. Это позволяет делать гибкую обработку и реализовывать хранение состояния сессий. Необходимо уточнить, что данный механизм реализуется тем, что плагин установливает модуль IIS Application Request Routing  в каждый из экземпляров вашей роли и, таким образом, маршрутизирует HTTP-запросы, сначала заворачивая их на себя, после чего отправляя их по соответствующим экземплярам.

Что необходимо учитывать при работе с липкими сессиями:

Липкие сессии и Session Affinity не работают в локальном эмуляторе вычислений. Так как вычисления только эмулируются, не может быть никаких дополнительных установок модулей.

Сохранение состояния сессий с помощью механизма Session Affinity

Так как у вас уже имеется готовый проект со страницей .JSP, вы можете реализовать сохранение состояния сессий. Нам пригодится еще один файл для просмотра того, как всё это работает – newsession.jsp.

Ваш итоговый файл JSP  должен выглядеть в соответствии с кодом ниже. Обратите внимание, что используется дополнительный код из предыдущей части цикла. Код взят с MSDN.

<%@ page language=“java” contentType=“text/html; charset=ISO-8859-1”

      pageEncoding=“ISO-8859-1”

      import=“com.microsoft.windowsazure.serviceruntime.*, java.util.Map, java.util.*,java.text.DateFormat”%>

<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”&gt;

<html>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1”>

<title>Hello</title>

</head>

<body>

      <b>Hello Azure!</b>

      <br />

      <p>

            RoleEnvironment.isEmulated() возвратил

            <%=RoleEnvironment.isEmulated()%>.

      </p>

      <p>

            Идентификатор экземпляра роли равен

            <%=RoleEnvironment.getCurrentRoleInstance().getId()%>.

      </p>

      <p>

            Имя роли:

            <%=RoleEnvironment.getCurrentRoleInstance().getRole()

                              .getName()%>.

      </p>

      <%

            Map<String, RoleInstanceEndpoint> endpoints =

            RoleEnvironment.getCurrentRoleInstance().getInstanceEndpoints();

            for (Map.Entry<String, RoleInstanceEndpoint> entry : endpoints

                        .entrySet())

            {

                  out.println(“Точка входа ‘”

                              + entry.getKey()

                              +

                              “‘ : “

                              + entry.getValue().getIpEndPoint().getAddress()

                                         .getHostAddress());

            }

            Map<String, LocalResource> localresources = RoleEnvironment

                        .getLocalResources();

            Set set = localresources.entrySet();

            Iterator iterator = set.iterator();

            LocalResource localResource;

            while (iterator.hasNext())

            {

                  Map.Entry entry = (Map.Entry) iterator.next();

                  localResource = (LocalResource) entry.getValue();

                  out.println(“Локально зарезервированные файловые ресурсы: \n Название: “

                              + localResource.getName()

                              + “Путь: “

                              + localResource.getRootPath()

                              + “\n Максимальный размер (Мб): “

                              + localResource.getMaximumSizeInMegabytes() + “\n”);

            }

            ;

            Map<String, String> mapConfigSettings = RoleEnvironment

                        .getConfigurationSettings();

            String mysetting = mapConfigSettings.get(“name”);

            out.println(mysetting);

            // Отслеживание количества визитов в сессии.

            Integer visits = (Integer) session.getAttribute(“visits”);

            if (null == visits)

            {

                  // Визиты в сессии не отслеживаются, при первом визите инициализация.

                  visits = new Integer(1);

            }

            else

            {

                  // Визиты отслеживаются, поэтому инкрементирование счетчика визитов.

                  visits = new Integer(visits.intValue() + 1);

            }

            // Обновление данных сессии для включения текущего количества счетчиков.

            session.setAttribute(“visits”, visits);

            // проверка на наличие логина пользователя в сессии

            String name;

            name = (String) session.getAttribute(“username”);

            if (null == name)

            {

                  // если логина нет, проверяется текстовое поле логина

                  name = request.getParameter(“username”);

                  if (null != name && “” != name)

                  {

                        // сохранение логина в сессии

                        session.setAttribute(“username”, name);

                        // приветствие.

      %>

      <p>

            Welcome

            <%=name%>!

      </p>

      <%

            }

                  else

                  {

                        // логина нет. отображение формы.

      %>

      <form action=<%=request.getRequestURI()%> method=“post”>

            Enter your name: <input type=“text” name=“username” /> (Press the <b>Enter</b>

            key when done)

      </form>

      <%

            }

            }

            else

            {

                  // приветствие возвратившегося пользователя.

      %>

      <p>

            Welcome back

            <%=name%>!

      </p>

      <%

            }

            // отображение инфорамации сессии.

            DateFormat dfDate = DateFormat.getDateInstance(DateFormat.FULL);

            DateFormat dfTime = DateFormat.getTimeInstance();

            long creationTime = session.getCreationTime();

            long lastAccessedTime = session.getLastAccessedTime();

            Date dateCreated = new Date(creationTime);

            Date dateLastAccessed = new Date(lastAccessedTime);

      %>

      <p />

      <table border=1 width=90%>

            <tr>

                  <th>Session information</th>

                  <th>Value</th>

            </tr>

            <tr>

                  <td>Session ID</td>

                  <td><%=session.getId()%></td>

            </tr>

            <tr>

                  <td>New or existing</td>

                  <td><%=(session.isNew() ? “New” : “Existing”)%></td>

            </tr>

            <tr>

                  <td>Created</td>

                  <td><%=dfDate.format(dateCreated)%> <%=dfTime.format(dateCreated)%></td>

            </tr>

            <tr>

                  <td>Last accessed</td>

                  <td><%=dfDate.format(dateLastAccessed)%> <%=dfTime.format(dateLastAccessed)%></td>

            </tr>

            <tr>

                  <td>Maximum inactive interval</td>

                  <td><%=Integer.toString(session.getMaxInactiveInterval())%>

                        seconds</td>

            </tr>

            <tr>

                  <td>Visits or refreshes by you to this session</td>

                  <td><%=visits.intValue()%></td>

            </tr>

            <tr>

                  <td>Windows Azure deployment ID</td>

                  <td><%=RoleEnvironment.getCurrentRoleInstance().getId()%></td>

            </tr>

            <tr>

                  <th>Session attributes</th>

                  <th>Value</th>

            </tr>

            <%

                  // определение атрибутов сессии.

                  Enumeration<String> e = session.getAttributeNames();

                  String attributeName;

                  Object attributeValue;

                  // отображение атрибутов.

                  while (e.hasMoreElements())

                  {

                        attributeName = e.nextElement();

                        attributeValue = session.getAttribute(attributeName);

            %>

            <tr>

                  <td><%=attributeName%></td>

                  <td><%=attributeValue.toString()%></td>

            </tr>

            <%

                  }

            %>

      </table>

      <p />

      <!– Allow the user to create a new session. –>

      <form action=“newsession.jsp” method=“post”>

            <input type=“submit” name=“newSession” value=“Create new session” />

      </form>

      %>

</body>

</html>

Файл newsession.jsp должен иметь следующий код.

<%@ page language=“java” contentType=“text/html; charset=ISO-8859-1”

      pageEncoding=“ISO-8859-1”%>

<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”&gt;

<html>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1”>

<title>New session page</title>

</head>

<body>

      <%

            // удаление текущей сессии.

            session.invalidate();

            // возврат пользователя к главной странице

            response.sendRedirect(“NewFile.jsp”);

      %>

</body>

</html>

Экспортируйте Java-проект в облачный проект.

Разверните проект в облаке и просмотрите результат.

Windows Azure & Java. Что такое Service Bus и как её использовать из Java-приложения. Часть 1.

clip_image091[4]

Рис. 46. Service Bus

Один из дополнительных компонентов платформы Windows Azure, предоставляющий функциональность безопасного, устойчивого к ошибкам и высокомасштабируемого механизма обмена сообщения, является Service Bus. Service Bus позволяет разработчику объединять в единую инфраструктуру обмена сообщениями несколько сущностей, использовать множество протоколов обмена сообщениями, и делать это достаточно красиво и аккуратно – приложение регистрируется в Service Bus Relay, разработчик/администратор выбирает некоторый уникальный адрес конечной точки входа (следуя конвенциям именования –https://[имяточкивхода].accesscontrol.windows.net/), после чего приложение может инициировать создание исходящего подключения к Service Bus Relay. Далее приложение будет держать этот канал открытым до тех пор, пока не будет выключено или перезагружено, постоянно посылая небольшие heartbeat-пакеты (раз в несколько секунд). Весь траффик, попадающий в Service Bus Relay, будет перенаправлен затем на конечную точку входа в облако и локальное приложение-приемник (которых может быть множество одновременно на одну конечную точку входа сервиса – при этом Service Bus Relay случайным образом выбирает, какой из приемников-слушателей получит входящий запрос, обеспечивая таким образом балансировку нагрузки. При этом необходимо учитывать, что нет никаких гарантий, что нагрузка будет ровно “размазана” по всем слушателям).

Service Bus оперирует двумя основными концепциями – Queues (очереди) и Topics (топики).

Очереди

Очереди Service Bus предоставляют модель коммуникаций, называемую brokered messaging communication – при использовании очередей части распределенного приложения осуществляют коммуникации между собой через очередь (что позволяет разрабатывать слабо-связанные системы) – отправитель сообщения кладет сообщение в очередь (очередь следует модели First In, First Out –FIFO), откуда (из начала) его забирает обработчик. Всё происходит асинхронно, поэтому никому ждать, пока кто-то закончит, не требуется. Принцип работы распределенной архитектуры с использованием очереди Service Bus изображен на рисунок 47.

clip_image092[4]

Рис. 47. Принцип работы распределенной архитектуры с использованием очереди Service Bus

Подобную архитектуру можно использовать при разработке самых разных приложений (это является типичным паттерном в “облачных” приложениях), например для обеспечения коммуникаций между веб и воркер-ролями в приложении в Windows Azure, коммуникаций между локальным и облачным приложением в гибридной модели, а также для связывания нескольких частей распределенного локальногоприложения (таким образом, сценарий локального приложения расширяется в облако, но только в контексте хранения и маршрутизации сообщений). Очереди Service Bus позволяют масштабировать приложения и добиваться высокой степени отказоустойчивости за счёт собственных механизмов – если обработчики сообщения не могут какое-то время обработать сообщения, сообщения будут храниться до определенных пор либо до того момента, как обработчики не вернутся обратно в онлайн и не будут готовы к работе.

Топики

По принципу работы топики похожи на очереди, однако их главной особенностью является множество конечных точек для обработчиков – они называются подписками (Subscriptions), и такая модель называется publish/subscribe messaging communication – каждый потребитель-обработчик “подписывается” на подписку. Каждая подписка имеет доступ ко всем добавленным сообщениям, при этом механизм фильтрации позволяет им определить, доступно ли сообщение через подписку или нет, и если доступно, то обработчик забирает сообщение из подписки аналогичным очередям образом. Таким образом, можно реализовать распространение одного и того же сообщения на несколько подписок. Механизм подписок использует принцип работы FIFO и представлен на рисунок 48.

clip_image094[4]

Рис.48. Принцип работы подписок (Subscription) Service Bus

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

Для того, чтобы начать работу с Service Bus в Windows Azure, необходимо создать именованный сервис (пространство имен), которое будет предоставлять контейнер для Service Bus.

Зайдите на портал управления Windows Azure (http://manage.windowsazure.com)

В левом нижнем углу портала управления нажмите New=>AppServices=>ServiceBusQueue=>QuickCreate(рисунок 49). Введите название очереди и нажмите Createanewqueue.

clip_image096[4]

Рис.49. Интерфейс портала управления Windows Azure, управление Service Bus

Дождитесь создания пространства имен и очереди (рисунок 50).

clip_image098[4]

Рис. 50. Интерфейс управления Service Bus

Нажмите на пространство имён. Перейдя на администраторскую панель пространства имен, нажмите AccessKeyи запишите владельца пространства имен и ключ.

На этом настройка Service Busзакончена.

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

import java.math.BigDecimal;

import java.util.Calendar;

import java.util.List;

import com.microsoft.windowsazure.services.serviceBus.*;

import com.microsoft.windowsazure.services.serviceBus.models.*;

import com.microsoft.windowsazure.services.core.*;

import javax.xml.datatype.*;

import javax.xml.datatype.DatatypeConstants.Field;

public class TestServiceBus {

      // Все операции по управлению вашим контейнером Service Bus выполняются с

      // помощью класса ServiceBusContract, при создании которого конструктору

      // передаётся

      // конфигурация вашего контейнера – название контейнера, имя issuer и ключ.

      // Все эти данные можно получить из панели свойств Properties вашего

      // контейнера Service Bus на портале Windows Azure.

      // Далее можно воспользоваться функциональностью класса ServiceBusService,

      // предоставляющего управление очередями – создание, удаление и т.д. В

      // данном методе создаётся контейнер Service Bus с именем QueueSample.

      private static ServiceBusContract createServiceBus(String issuer, String key) {

            Configuration config = ServiceBusConfiguration

                        .configureWithWrapAuthentication(“testqueue-ns1”, issuer, key,

                                   “.servicebus.windows.net”,

                                   “-sb.accesscontrol.windows.net/WRAPv0.9”);

            ServiceBusContract service = ServiceBusService.create(config);

            return service;

      }

      // В данном методе используется функциональность класса QueueInfo, с помощью

      // которой в данном случае определяется

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

      // в 5Гб). С помощью методов QueueInfo можно настраивать различные параметры

      // ваших очередей, в т.ч. Time To Live для сообщений, максимальный размер и

      // многое другое.

      private static QueueInfo createQueue(String name, ServiceBusContract service) {

            long queueSize = 5120;

            QueueInfo queueInfo = new QueueInfo(“myqueue”);

            try {

                  queueInfo.setMaxSizeInMegabytes(queueSize);

                  CreateQueueResult result = service.createQueue(queueInfo);

            } catch (ServiceException e) {

                  System.out.print(“ServiceException: ” + e.getMessage());

            }

            return queueInfo;

      }

      // Для отображения сообщения в объектной модели существует класс

      // BrokeredMessage, объекты которого содержат набор методов для управления

      // сообщением,

      // набор параметров и набор данных. В набор данных можно передать любой

      // сериализуемый объект. Очереди Service Bus имеют ограничение на размер

      // сообщения в 256 килобайт (заголовок, содержащий свойства – 64 килобайта),

      // однако ограничений как таковых на количество хранимых в очереди сообщений

      // нет, кроме задаваемого вами ограничения-максимального размера очереди.

      private static void putMessageToQueue(String queueName,

      ServiceBusContract service, BrokeredMessage message) {

            try {

                  service.sendQueueMessage(queueName, message);

            } catch (ServiceException e) {

                  System.out.print(“ServiceException encountered: ” + e.getMessage());

            }

      }

      // Аналогично сервису очередей хранилища Windows Azure, вы можете

      // использовать два метода для извлечения сообщений из очередей –

      // получение и удаление (ReceiveAndDelete) и “подсматривание” – получение

      // сообщение, но не удаление его из очереди (PeekLock). При использовании

      // метода ReceiveAndDelete при получении очередью запроса на извлечение

      // сообщения, очередь помечает это сообщение как “потреблённое”.

      // При использовании метода PeekLock процесс получения дробится на два этапа

      // – когда Service Bus получает запрос на извлечение сообщения, он находит

      // это сообщение, помечает его как locked (в этот момент другие обработчики

      // перестают видеть это сообщение) и возвращает его приложению. После

      // окончания

      // обработки приложением сообщения закрывается второй этап процесса с

      // помощью вызова метода Delete полученного сообщения. После этого сообщение

      // помечается как удаленное.

      // Типичным паттерном опроса очереди на наличие новых сообщений является

      // использование бесконечного цикла while. В данном методе очередь

      // опрашивается постоянно. Если вы хотите

      // ограничить выполнение каким-либо количеством полученных сообщений, вам

      // необходимо реализовать логику с использованием break.

      private static void getMessageFromQueue(String queueName,

      ServiceBusContract service) throws ServiceException {

            // ReceiveMessageOptions opts = ReceiveMessageOptions.DEFAULT;

            // opts.setReceiveMode(ReceiveMode.PEEK_LOCK);

            while (true) {

                  ReceiveQueueMessageResult result = service

                  .receiveQueueMessage(queueName);

                  BrokeredMessage message = result.getValue();

                  if (message != null && message.getMessageId() != null) {

                        try {

                              System.out

                              .println(“Сообщение: “

                              + message.toString());

                              System.out.println(“ID сообщения: “

                              + message.getMessageId());

                              System.out

                                         .println(“Если вы задали какое-то свойство, его можно получить с помощью метода getProperty(): “

                                                     + message.getProperty(“CustomProperty”));

                              System.out.println(“Сообщение прочитано – удалено.”);

                              service.deleteMessage(message);

                        } catch (Exception ex) {

                              // если было выброшено исключение, сообщение будет

                              // разблокировано для других обработчиков

                              System.out.println(“Исключение!”);

                              service.unlockMessage(message);

                        }

                  } else {

                        System.out.println(“Больше нет сообщений, прерываем цикл.”);

                        break;

                  }

            }

      }

      public static void main(String args[]) {

            ServiceBusContract service = createServiceBus(“owner”,

            “=”);

            QueueInfo queue = createQueue(“myqueue”, service);

            BrokeredMessage message = new BrokeredMessage(

            “Наше сообщение в очередь.”);

            putMessageToQueue(“testqueue”, service, message);

            try {

                  getMessageFromQueue(“testqueue”, service);

            } catch (ServiceException e) {

                  e.printStackTrace();

            }

      }

}

 

Запустите проект и просмотрите результат в консоли.

Обратите внимание на метод ServiceBusConfiguration.configureWithWrapAuthentication. В стандартном виде он принимает 5 аргументов: название пространства имён Service Bus (testqueuens1), имя для аутентификации (обычно owner), пароль (ключ, key на портале управления), serviceBusRootUri – корневой URI Service Bus, обычно “.servicebus.windows.net”, и wrapRootUri – корневой URI для сервиса аутентификации, который равен “-sb.accesscontrol.windows.net/WRAPv0.9”.

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

04.04.2012 11:57:06 com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusExceptionProcessor processCatch
WARNING: com.sun.jersey.api.client.UniformInterfaceException: PUT https://ahrimansb.servicebus.windows.net/myqueue returned a response status of 409 Conflict
com.sun.jersey.api.client.UniformInterfaceException: PUT https://ahrimansb.servicebus.windows.net/myqueue returned a response status of 409 Conflict
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:676)
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
    at com.sun.jersey.api.client.WebResource$Builder.put(WebResource.java:533)
    at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusRestProxy.createQueue(ServiceBusRestProxy.java:265)
    at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusExceptionProcessor.createQueue(ServiceBusExceptionProcessor.java:188)
    at TestServiceBusRelay.createQueue(TestServiceBusRelay.java:46)
    at TestServiceBusRelay.main(TestServiceBusRelay.java:135)
ServiceException: com.sun.jersey.api.client.UniformInterfaceException: PUT https://testqueue-ns1.servicebus.windows.net/myqueue returned a response status of 409 Conflict
Response Body: <Error><Code>409</Code><Detail>Conflict.TrackingId:59992d2d-e47f-40a0-935e-a16ea910d5f2_2,TimeStamp:4/4/2012 4:57:08 AM</Detail></Error>Сообщение: com.microsoft.windowsazure.services.serviceBus.models.BrokeredMessage@878c4c

В этом случае вы можете также просто удалить очередь с помощью портала управления Windows Azure.

Windows Azure & Java. Что такое Service Bus и как ее использовать из Java-приложения. Часть 2. Топики.

Топики

По принципу работы топики похожи на очереди, однако их главной особенностью является множество конечных точек для обработчиков – они называются подписками (Subscriptions), и такая модель называется publish/subscribe messaging communication – каждый потребитель-обработчик “подписывается” на подписку. Каждая подписка имеет доступ ко всем добавленным сообщениям, при этом механизм фильтрации позволяет им определить, доступно ли сообщение через подписку или нет, и если доступно, то обработчик забирает сообщение из подписки аналогичным очередям образом. Таким образом, можно реализовать распространение одного и того же сообщения на несколько подписок. Механизм подписок использует принцип работы FIFO и представлен на рисунок 51.

clip_image100[4]

Рис. 51. Топики и подписки

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

Для создания топика необходимо нажать на портале управления Windows Azure New=>AppServices=>ServiceBusTopic=>QuickCreateи ввести название топика (рисунок 52).

clip_image102[4]

Рис. 52. Создание топика Service Bus

Ниже приведен Java-код, готовый к использованию, с комментариями. Хочу обратить ваше внимание на использование новой функциональности (в прошлой части всё было гораздо проще). В данном коде используется дополнительный метод convertStreamToString(InputStream is), который преобразовывает поток в строку. Кроме этого, показано два метода добавления контента в сообщение – как напрямую (в конструкторе), так и с помощью метода setBody().

 

import java.io.BufferedReader;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.Reader;

import java.io.StringWriter;

import java.io.Writer;

import java.math.BigDecimal;

import java.util.ArrayList;

import java.util.Calendar;

import java.util.List;

import com.microsoft.windowsazure.services.serviceBus.*;

import com.microsoft.windowsazure.services.serviceBus.models.*;

import com.microsoft.windowsazure.services.core.*;

import javax.xml.datatype.*;

import javax.xml.datatype.DatatypeConstants.Field;

public class TestServiceBus {

      // Все операции по управлению вашим контейнером Service Bus выполняются с

      // помощью класса ServiceBusContract, при создании которого конструктору

      // передаётся

      // конфигурация вашего контейнера – название контейнера, имя issuer и ключ.

      // Все эти данные можно получить из панели свойств Properties вашего

      // контейнера Service Bus на портале Windows Azure.

      // Далее можно воспользоваться функциональностью класса ServiceBusService,

      // предоставляющего управление очередями – создание, удаление и т.д. В

      // данном методе создаётся контейнер Service Bus с именем ahrimansb.

      private static ServiceBusContract createServiceBus(String issuer, String key) {

            Configuration config = ServiceBusConfiguration

                        .configureWithWrapAuthentication(“testqueue-ns1”, issuer, key,

                                   “.servicebus.windows.net”,

                                   “-sb.accesscontrol.windows.net/WRAPv0.9”);

            ServiceBusContract service = ServiceBusService.create(config);

            return service;

      }

      // В данном методе используется функциональность класса TopicInfo, с помощью

      // которой в данном случае определяется

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

      // в 5Гб). С помощью методов TopicInfo можно настраивать различные параметры

      // ваших очередей, в т.ч. Time To Live для сообщений, максимальный размер и

      // многое другое.

      private static void createTopic(String name, ServiceBusContract service) {

            long queueSize = 5120;

            TopicInfo topicInfo = new TopicInfo(name);

            try {

                  topicInfo.setMaxSizeInMegabytes(queueSize);

                  CreateTopicResult result = service.createTopic(topicInfo);

            } catch (ServiceException e) {

                  System.out.print(“ServiceException: ” + e.getMessage());

            }

      }

      // В данном методе используется фильтр по умолчанию MatchAll (поэтому нет

      // никаких дополнительных указаний значения фильтра).

      // При использовании фильтра по умолчанию все сообщения, которые поступают в

      // топик, помещаются в подписку-очередь.

      private static void createSubscriptionWithFilterMatchAll(

      String subscriptionInfoName, String topicName,

      ServiceBusContract service) {

            try {

                  SubscriptionInfo subInfo = new SubscriptionInfo(

                  subscriptionInfoName);

                  CreateSubscriptionResult result = service.createSubscription(

                  topicName, subInfo);

            } catch (ServiceException e) {

                  System.out.print(“ServiceException: ” + e.getMessage());

            }

      }

      // В данном методе создаётся ещё одна подписка с SQL-фильтром сообщений

      // (SqlFilter). При этом

      // в качестве условия используется сравнение некоторого custom-свойства

      // MessageSequenceId.

      // После создания двух подписок сообщения, поступающие в соответствующий

      // топик, буду уходить –

      // все в первую подписку, и только удовлетворяющие условиям фильтра – во

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

      // что гораздо оптимальнее создать несколько подписок с разными фильтрами и

      // распределять сообщения по определенному условию.

      private static void createSubscriptionWithFilter(

      String subscriptionInfoName, String topicName,

      ServiceBusContract service) {

            SubscriptionInfo subInfo = new SubscriptionInfo(subscriptionInfoName);

            try {

                  CreateSubscriptionResult result = service.createSubscription(

                  topicName, subInfo);

            } catch (ServiceException e) {

                  e.printStackTrace();

            }

            RuleInfo ruleInfo = new RuleInfo();

            ruleInfo = ruleInfo.withSqlExpressionFilter(“MessageNumber > 4”);

            try {

                  CreateRuleResult ruleResult = service.createRule(topicName,

                  “subscriptioninfoname2”, ruleInfo);

            } catch (ServiceException e) {

                  e.printStackTrace();

            }

      }

      // Для отображения сообщения в объектной модели существует класс

      // BrokeredMessage, объекты которого содержат набор методов для управления

      // сообщением,

      // набор параметров и набор данных. В набор данных можно передать любой

      // сериализуемый объект. Очереди Service Bus имеют ограничение на размер

      // сообщения в 256 мегабайт(заголовок, содержащий свойства – 64 мегабайт),

      // однако ограничений как таковых на количество хранимых в очереди сообщений

      // нет, кроме задаваемого вами ограничения-максимального размера очереди. В

      // данном случае мы также указываем custom-свойство MessageSequenceId,

      // которое будет использоваться для фильтра

      private static void putMessageToTopic(String topicName,

      ServiceBusContract service, BrokeredMessage message) {

            try {

                  message.setProperty(“MessageNumber”, “6”);

                  service.sendTopicMessage(topicName, message);

            } catch (ServiceException e) {

                  System.out.print(“ServiceException: ” + e.getMessage());

            }

      }

      // Метод для добавления множества сообщений в топик.

      private static void putMessagesToTopic(String topicName,

      ServiceBusContract service, List<BrokeredMessage> messages) {

            try {

                  for (BrokeredMessage message : messages) {

                        service.sendTopicMessage(topicName, message);

                  }

            } catch (ServiceException e) {

                  e.printStackTrace();

            }

      }

      // Аналогично сервису очередей хранилища Windows Azure, вы можете

      // использовать два метода для извлечения сообщений из очередей топиков –

      // получение и удаление (ReceiveAndDelete) и “подсматривание” – получение

      // сообщение, но не удаление его из очереди топика (PeekLock). При

      // использовании

      // метода ReceiveAndDelete при получении запроса на извлечение

      // сообщения, очередь помечает это сообщение как “потреблённое”.

      // При использовании метода PeekLock процесс получения дробится на два этапа

      // – когда Service Bus получает запрос на извлечение сообщения, он находит

      // это сообщение, помечает его как locked (в этот момент другие обработчики

      // перестают видеть это сообщение) и возвращает его приложению. После

      // окончания

      // обработки приложением сообщения закрывается второй этап процесса с

      // помощью вызова метода Delete полученного сообщения. После этого сообщение

      // помечается как удаленное.

      // Типичным паттерном опроса очереди на наличие новых сообщений является

      // использование бесконечного цикла while. В данном методе очередь

      // опрашивается постоянно. Если вы хотите

      // ограничить выполнение каким-либо количеством полученных сообщений, вам

      // необходимо реализовать логику с использованием break.

      private static void getMessageFromTopic(String topicName,

      String subscriptionName, ServiceBusContract service)

      throws ServiceException {

            ReceiveMessageOptions opts = ReceiveMessageOptions.DEFAULT;

            opts.setReceiveMode(ReceiveMode.PEEK_LOCK);

            while (true) {

                  ReceiveSubscriptionMessageResult result = service

                  .receiveSubscriptionMessage(topicName, subscriptionName,

                  opts);

                  BrokeredMessage message = result.getValue();

                  if (message != null && message.getMessageId() != null) {

                        try {

                              System.out

                                         .println(“Начало работы по опросу очереди подписки с именем:”

                                                     + subscriptionName);

                              System.out.println(“Сообщение: “

                              + convertStreamToString(message.getBody()));

                              System.out.println(“ID сообщения: “

                              + message.getMessageId());

                              System.out

                                         .println(“Если вы задали какое-то свойство, его можно получить с помощью метода getProperty(): “

                                                     + message.getProperty(“MessageNumber”));

                              System.out.println(“Сообщение прочитано – удалено.”);

                              service.deleteMessage(message);

                        } catch (Exception ex) {

                              // если было выброшено исключение, сообщение будет

                              // разблокировано для других обработчиков

                              System.out.println(“Исключение!”);

                              service.unlockMessage(message);

                        }

                  } else {

                        System.out

                                   .println(“Больше нет сообщений, но топик продолжает опрашиваться.”);

                  }

            }

      }

      private static void deleteTopic(String topicName, ServiceBusContract service) {

            try {

                  service.deleteTopic(topicName);

            } catch (ServiceException e) {

                  e.printStackTrace();

            }

      }

      private static void deleteSubscription(String subscriptionName,

      String subscriptionInfoName, ServiceBusContract service) {

            try {

                  service.deleteSubscription(subscriptionName, subscriptionInfoName);

            } catch (ServiceException e) {

                  e.printStackTrace();

            }

      }

      public static void main(String args[]) throws FileNotFoundException {

            ServiceBusContract service = createServiceBus(“owner”,

            “”);

            createTopic(“mytopic”, service);

            createSubscriptionWithFilterMatchAll(“subscriptioninfoname1”,

            “mytopic”, service);

            createSubscriptionWithFilter(“subscriptioninfoname2”, “mytopic”,

            service);

            InputStream input = new FileInputStream(“c:\\temp\\1.txt”);

            BrokeredMessage message = new BrokeredMessage(“Our message.”);

            message.setBody(input);

            ArrayList<BrokeredMessage> messages = new ArrayList<BrokeredMessage>();

            for (int i = 0; i < 5; i++) {

                  BrokeredMessage msg = new BrokeredMessage(“Message text: ” + i);

                  msg.setProperty(“MessageNumber”, i);

                  messages.add(msg);

            }

            putMessageToTopic(“mytopic”, service, message);

            putMessagesToTopic(“mytopic”, service, messages);

            try {

                  getMessageFromTopic(“mytopic”, “subscriptioninfoname1”, service);

                  getMessageFromTopic(“mytopic”, “mysubscriptionwithfilter”, service);

            } catch (ServiceException e) {

                  e.printStackTrace();

            }

      }

      public static String convertStreamToString(InputStream is)

      throws IOException {

            if (is != null) {

                  Writer writer = new StringWriter();

                  char[] buffer = new char[1024];

                  try {

                        Reader reader = new BufferedReader(new InputStreamReader(is,

                        “UTF-8”));

                        int n;

                        while ((n = reader.read(buffer)) != -1) {

                              writer.write(buffer, 0, n);

                        }

                  } finally {

                        is.close();

                  }

                  return writer.toString();

            } else {

                  return “”;

            }

      }

}

Далее просто запустите ваше приложение. Для этого нажмите ALT+Shift+X либо нажмите соответствующую кнопку в меню в Eclipse(рисунок 53).

clip_image104[4]

Рис.53. Запуск простого Java-проекта.

В консоли вы должны увидеть результат.

Обратите внимание, что, если вы получаете исключение ниже, вам необходимо реализовать проверку на существование топика и подписки перед тем, как их создавать – это исключение значит, что такие сущности уже есть в контейнере.

04.04.2012 11:57:06 com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusExceptionProcessor processCatch
WARNING: com.sun.jersey.api.client.UniformInterfaceException: PUT https://ahrimansb.servicebus.windows.net/myqueue returned a response status of 409 Conflict
com.sun.jersey.api.client.UniformInterfaceException: PUT https://ahrimansb.servicebus.windows.net/myqueue returned a response status of 409 Conflict
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:676)
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
    at com.sun.jersey.api.client.WebResource$Builder.put(WebResource.java:533)
    at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusRestProxy.createQueue(ServiceBusRestProxy.java:265)
    at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusExceptionProcessor.createQueue(ServiceBusExceptionProcessor.java:188)
    at TestServiceBusRelay.createQueue(TestServiceBusRelay.java:46)
    at TestServiceBusRelay.main(TestServiceBusRelay.java:135)
ServiceException: com.sun.jersey.api.client.UniformInterfaceException: PUT https://ahrimansb.servicebus.windows.net/myqueue returned a response status of 409 Conflict
Response Body: <Error><Code>409</Code><Detail>Conflict.TrackingId:59992d2d-e47f-40a0-935e-a16ea910d5f2_2,TimeStamp:4/4/2012 4:57:08 AM</Detail></Error>Сообщение: com.microsoft.windowsazure.services.serviceBus.models.BrokeredMessage@878c4c

В этом случае вы можете также просто удалить топик или подписку с помощью портала управления Windows Azure.

Разработка на Java для Windows Azure–что нужно учитывать

Итак, что нужно учитывать при разработке на Java для Windows Azure? Есть плагин для Eclipse (что уже очень большой прогресс), есть SDK, есть готовые наработки. Однако просто так взять и разработать приложение, может быть, и не получится – необходимо учитывать ряд особенностей платформы, которые могут быть и неочевидны.

Microsoft рассматривает язык программирования Java как first-class citizen на своей платформе Windows Azure. В целом я согласен с этим заявлением, потому что уже существующие предложения для размещения Java-приложений в облаке Microsoft позволяют разместить любое приложение. Попробуем рассмотреть “за” и “против” размещения Java-приложения в Windows Azure.

Почему вообще необходимо облако для нужд Java-приложения? Уже разработанные приложения могут быть достаточно сложными и иметь распределенную архитектуру, которая использует множество серверов, соответственно, то, что предлагает облачная платформа, подходит для этих нужд и, возможно, сулит экономические выгоды.

Web-приложения на Java и Windows Azure

Обычно веб-приложения на Java пишутся с использованием сервлетов, JSP, JSF и так далее. На мощностях Tomcat, JBoss, Jetty, GlassFish. В плагине Windows Azure для Eclipse есть конфигурационные файлы, подготовленные отдельно для каждогоиз этих серверов приложений и контейнеров. Кроме этого, у Microsoft уже заготовлены полезные готовые проекты с мануалами, так называемые Solution Accelerator – Windows Azure Tomcat Solution Accelerator и Windows Azure Jetty Solution Accelerator, например.

Распространенный вопрос про сохранение сессий и липкие сессии актуален и с Java—приложениями. Плагин позволяет делать липкие сессии. Вторым подходом является использование Atomus TomcatAzureSessionManager (сохраняющего сессию в хранилище таблиц Windows Azure)  и Windows Azure Sticky HTTP Session Router. Разработчику позволяется использовать модуль IIS Application Request Routing.

Что с хранилищем в Java-приложении?

Где хранить данные, если у нас есть Java-приложение? Есть несколько вариантов – это SQL Azure Databases, реляционная СУБД на основе SQL Server 2008 R2 и наследующая большинство функциональности (и, всё же, не всей). JDBC Driver от Microsoft официально поддерживает SQL Azure Databases. В целом, работа с JDBC Driver, SQL Azure Databases и Java-приложением достаточно приятна и несложна. Если же есть уже готовая база данных и ее требуется перенести в облако, у Microsoft есть для этого средство – SQL Azure Migration Wizard. Позволяет переносить готовую базу данных в облако, будь она Oracle, MySQL или Access.

Вторым вариантом размещения данных являются сервисы хранилища Windows Azure. Windows Azure SDK for Java полностью поддерживает взаимодействие хранилища Windows Azure и Java, поэтому и тут не возникнет никаких проблем. Напоминание: сервисы хранилищ состоят из трех основных сервисов – блобы (дешевое и масштабируемое хранилище больших документов, которое может использовать Windows Azure Content Delivery Network для доставки контента ближе к пользователям), таблицы (масштабируемое и дешевое хранение нереляционных данных, аналог реляционных баз данных, но не позволяет хранить сколь-либо связные данные) и очереди (хранилище сообщений для осуществления коммуникации между ролями).

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

К недостаткам необходимо отнести:

Максимальный размер базы данных в SQL Azure Databases – 150 гигабайт. Для определенной части приложений такого объема будет достаточно, но, если его станет мало, придется придумывать решение по масштабированию. В SQL Azure уже есть федерации, можно реализовывать шардинг – в целом, недостатком это является только потому, что придется делать это самому, а не дать на откуп платформе.

Отсутствие поддержки для Java сервиса кэширования.

Количество внешних портов-конечных точек входа для каждого экземпляра. Сейчас равно 25, раньше было всего 5 и это было действительно плохо, учитывая использование некоторыми функциональностями Java портов, этого может и не хватить (JMX и др.). Например, для Glassfish необходимо по умолчанию открыть 4 порта сразу же.

Java != Microsoft.Несмотря на то, что Java – first-class citizen на платформе, внятной поддержки от вендоров из мира Java можно и не дождаться – всё это только входит в моду.

Отсутствие шаблонов для Java Runtime и серверов приложений.В принципе, можно объединить с предыдущим пунктом. На платформе есть стандартные образа виртуальных машин, которые построены на основе Windows Server 2008 или Windows Server 2008 R2 различных билдов. Естественно, по умолчанию там нет Java Runtime и тем более каких-то серверов приложений. Есть некоторая возможность, и ходят слухи по Интернету, что может и появиться подобный шаблон, но это всего лишь слухи. В целом же развертывание приложения с Tomcat не занимает особо много времени и не вызывает трудностей. С Glassfish и JBoss немного сложнее, но опять же ненамного. Этот недостаток опять же очень сложно назвать недостатком – невозможно “объять необъятное”, невозможно иметь поддержку всех версий Tomcat и Glassfish, и при этом оставаться простой в освоении платформой. Кроме этого, ролевая модель Windows Azure и Startup-задачи позволяют выполнять любые настройки и установки при запуске экземпляра, в том числе производить любые настройки ваших серверов приложений. Microsoft не ставит никаких ограничений в этом контексте – Java-разработчику позволено выбирать, устанавливать и настраивать любые версии Java Runtime и серверов приложений. А с плагином Windows Azure для Eclipse всё вообще становится задачей внесения изменений в текстовый файл конфигурации.

Как видите, недостатков не так много. Надо обязательно упомянуть, что Microsoft активно работает над вопросами interoperability и Windows Azure, вероятно, является наиболее открытой ко всему миру IT платформой.

Выводы

Как уже было сказано выше, недостатков при разработке на Java на платформе Windows Azure не так много, как может показаться на первый взгляд. Да, необходимо пересматривать архитектуру проекта, предусматривать стоимость, масштабируемость, недостатки, преимущества, специфичные для Windows Azure настройки (брандмауэры SQL Azure Databases, балансировщики нагрузки и так далее). Необходимо также четко понимать, нужно ли вообще переносить в облако свое приложение – но это уже универсальная задача, не специфичная для Java-приложений, так как, несмотря на преимущества и экономическую эффективность, для некоторых ситуаций облако может и не подойти. В целом же платформа Microsoft – ещё одна возможность для выполнения ваших приложений. А, учитывая явный интерес корпорации к interoperability с Java, Python… да, на самом деле, со всем, что сейчас реально популярно и не-.NET, эта возможность должна быть рассмотрена всерьёз.

October 3, 2012 / ahriman hpc mode

Обновления материалов

Давно вынашивал эту статью, и вот она опубликована в двух частях. Enjoy! Скоро будет Whitepaper PDF.

Обзор безопасности Windows Azure, ч. 1

Обзор безопасности Windows Azure, ч. 2

UPD: А вот и Whitepaper подоспел.