Вторая волна разработки Java-приложений: Инфраструктура Gaelyk в приложениях для Google App Engine

Узнайте о написанной на Groovy инфраструктуре, которая еще ускоряет процесс разработки приложений для платформы Google App Engine

С момента выхода предварительного релиза Google App Engine появилось множество инфраструктур, направленных на упрощение создания приложений для этой платформы. Gaelyk – инфраструктура, написанная на Groovy, – это одна из подобных технологий, разработанная специально для приложений, работающих с хранилищем данных Google. Одной из ее привлекательных особенностей является впечатляющий уровень масштабирования, который она способна обеспечить для ваших приложений.

Эндрю Гловер, президент компании, Stelligent Incorporated

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



01.04.2011

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

Об этой серии

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

Первая статья серии называется Знакомство с Google App Engine. В ней рассказывалось о возможности аренды инфраструктуры Google для бесплатного, но сопряженного с некоторыми ограничениями развертывания Java-приложений. Прочитав следующие статьи, вы узнали о различиях между платформами Google App Engine и Amazon EC2. Наконец, в предыдущей статье (Работа с CouchDB через интерфейсы REST при помощи RESTClient в Groovy) был приведен обзор возможностей CouchDB, представляющей собой альтернативу реляционным СУБД. Такие особенности CouchDB, как отсутствие схем и ориентированность на документы могли показаться оригинальными, однако в статье, посвященной Google App Engine, вы уже встречались со схожей СУБД, информация в которой не хранится в соответствии с реляционными схемами.

В этой статье мы вернемся к вопросам, связанным с Google App Engine. Эта платформа уже прочно заняла свое место в мире открытых технологий, в котором появляется все больше инфраструктур, направленных на облегчение разработки приложений для App Engine. Вы узнаете о том, как одна из таких инфраструктур под названием Gaelyk позволяет еще легче создавать приложения с использованием многих технологий, о которых рассказывалось в предыдущих статьях.

Легковесные приложения должны создаваться быстро

Инфраструктура Google предоставляется бесплатно (хотя не забывайте, что только для приложений, которые используют не более 500 МБ места на диске и страницы которых просматривают не чаще, чем 5 млн раз в месяц), но при этом она накладывает ряд ограничений на используемые Java-технологии. В частности, не все библиотеки JDK и бесплатные решения можно использовать в приложениях для App Engine. Google App Engine является платформой, поэтому приложения необходимо разрабатывать непосредственно под нее. Однако нет ничего удивительного в том, что в последнее время появился ряд бесплатных библиотек, помогающих решить проблемы, которые могли расцениваться как препятствия для использования этой платформы.

Одним из таких бурно развивающихся проектов является Gaelyk, представляющий собой инфраструктуру, облегчающую разработку легковесных Groovy-приложений, следующих принципам архитектуры MVC (Model-View-Controller). Используя ряд возможностей языка Groovy, Gaelyk предоставляет ряд функций, работающих поверх API Google App Engine. Кроме того, вы можете работать с Gaelyk при помощи модуля App Engine для Eclipse. Благодаря этим возможностям быстрое создание и развертывание приложений для Google App Engine упрощается до предела.

Архитектура хранения данных Google

Реализация инфраструктуры хранения данных Google App Engine скрыта от глаз разработчиков, но вы можете быть уверены, что она не представляет собой реляционную СУБД. Тем не менее, вы можете сохранять, читать, изменять и удалять хранимые в ней объекты, используя стандартную технологию JDO (Java Data Objects) или низкоуровневый API, предоставляемый Google.

В статье Работа с CouchDB через интерфейсы REST при помощи RESTClient в Groovy демонстрировалась работа с документ-ориентированной СУБД на примере хранения извещений о неправильной парковке. В продолжение этой темы мы создадим Web-приложение, позволяющее добавлять, изменять и удалять подобные извещения. В отличие от CouchDB в основе хранилища данных Google не лежит понятие документа, но ее модель является весьма гибкой, поскольку она тоже не ограничивается рамками реляционной структуры. Вследствие этого Web-приложение может моделировать парковочные извещения максимально точным образом, используя следующие атрибуты:

  • имя офицера, выписавшего извещение;
  • дату нарушения;
  • место, где произошло нарушение;
  • описание нарушения;
  • дополнительные заметки.

Для описания места нарушения мы по-прежнему будем использовать общее текстовое поле, поскольку оно может указываться множеством различных способов, например стоянка у магазина Best Buy или угол 18th St. и D St. У нас нет особой необходимости унифицировать формат описания, потому что он не предписывается данной предметной областью.

Вначале убедитесь, что у вас установлен модуль Google App Engine для Eclipse (инструкции по его установке можно найти в статье Знакомство с Google App Engine). Кроме того, загрузите JAR-файл Gaelyk с Web-сайта проекта (см. раздел Ресурсы). Запомните место на локальном диске, где вы сохранили файл, поскольку чуть позже его придется перенести в другую директорию.

Инфраструктура Gaelyk написана на Groovy, поэтому вам также понадобится последняя версия этого языка. Его можно загрузить в виде простого JAR-файла с именем groovy-all-1.6.5.jar на момент написания этой статьи (ссылка приведена в разделе Ресурсы). Наконец, следует задать идентификатор приложения при помощи административной панели Google App Engine. Если хотите, вы можете указать идентификатор, ранее использовавшийся в статье Знакомство с Google App Engine.

Далее создайте в Eclipse новый проект типа Google Web Application Project, нажмите на кнопку Next и введите всю необходимую информацию. Убедитесь, что снят флажок Use Google Web Toolkit (использовать инструментарий GWT), поскольку он нам не понадобится (рисунок 1).

Рисунок 1. Создание проекта приложения для Google App Engine в Eclipse
Create a new Google Web Application Project within Eclipse dialog box

После нажатия на кнопку Finish будут сгенерированы заготовки кода приложения.

Теперь скопируйте JAR-файлы Groovy и Gaelyk в директорию war/WEB-INF/lib directory только что созданного проекта, как показано на рисунке 2.

Рисунок 2. Библиотеки, необходимые для работы Gaelyk
Picture of your newly created project's war/WEB-INF/lib directory with the Groovy and Gaelyk JARs copied in

Для использования Gaelyk на платформе Google App Engine следует добавить дополнительную информацию в файл WEB-INF/appengine-web.xml file. Поместите идентификатор приложения в секцию application в начале файла, а затем добавьте в него фрагмент XML, приведенный в листинге 1.

Листинг 1. Конфигурирование App Engine
<static-files>
 <exclude path="/WEB-INF/**.groovy" />
 <exclude path="**.gtpl" />
</static-files>

Это фрагмент нужен для того, чтобы Google App Engine не расценивал файлы, которые будут созданы ниже для работы с Gaelyk, как статические ресурсы. Чуть позже вы увидите, что Gaelyk активно использует шаблонную модель. Файлы с расширением .gtpl будут выполнять ту же функцию, что и страницы JSP (JavaServer Pages), а, следовательно, должны обрабатываться инфраструктурой Gaelyk, а не App Engine.

Далее откройте файл web.xml, также находящийся в директории WEB-INF. Это все тот же файл с настройками Web-приложения, много лет знакомый Java-разработчикам (вы с ним встречались в статьях, посвященных Appa Engine и EC2). В web.xml описываются связи между различными шаблонами адресов запросов и сервлетами-обработчиками. Скопируйте в этот файл содержимое листинга 2.

Листинг 2. Содержимое файла web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
 <servlet>
  <servlet-name>GroovletServlet</servlet-name>
  <servlet-class>groovyx.gaelyk.GaelykServlet</servlet-class>
 </servlet>
 <servlet>
  <servlet-name>TemplateServlet</servlet-name>
  <servlet-class>groovyx.gaelyk.GaelykTemplateServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>GroovletServlet</servlet-name>
  <url-pattern>*.groovy</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>TemplateServlet</servlet-name>
  <url-pattern>*.gtpl</url-pattern>
 </servlet-mapping>
 <welcome-file-list>
  <welcome-file>index.gtpl</welcome-file>
 </welcome-file-list>
</web-app>

Обратите внимание на указание файла index.gtpl в качестве главной страницы приложения (welcome page). Переименуйте файл index.html, автоматически сгенерированный модулем Eclipse, в index.gtpl (если вы используете Windows®, то просто выделите файл и нажмите F2).

Теперь, когда все необходимые библиотеки находятся в classpath, а оба XML-файла содержат нужные настройки, пришло время проверить поведение приложения. Для этого отредактируйте файл index.gtpl, чтобы он принял вид, как в листинге 3.

Листинг 3. Пример файла GTPL
<html>
 <head><title>A Simple GTPL</title></head>
  <body>
   <b><% print "Hello Gaelyk!".replace(" ", " from ") %></b>
   <p>
   <ol>
    <% def wrd = "Groovy"
       wrd.each{ letter ->
    %>
    <li><%= letter %></li>
    <% } %>
   </ol>
   </p>
  </body>
</html>

Как видите, файлы GTPL (шаблоны Gaelyk/Groovy) в Gaelyk очень похожи на JSP. Вы можете добавлять произвольный код, в данном случае написанный на Groovy, в скриптлеты. Обратите внимание, что у вас есть возможность использовать замыкания и ссылаться на переменные. 

Сохраните файл index.gtpl, а затем выделите базовый каталог проекта в Eclipse, нажмите правую кнопку мыши, выберите пункт Run As, a затем - опцию Web Application с буквой G на голубом фоне (рисунок 3).

Рисунок 3. Запуск Web-приложения для Google App Engine
Screenshot of selecting the Web Application option that contains a blue G logo

По умолчанию модуль Eclipse запускает локальный экземпляр Jetty, слушающий порт 8080. Вы можете изменить порт, выбрав пункт  Run Configurations (настройки запуска проекта).

Запустив Web-приложение на основе Gaelyk на локальном сервере, откройте Web-браузер и обратитесь по адресу http://localhost:8080. Внешний вид страницы index.gtpl должен выглядеть, как показано на рисунке 4.

Рисунок 4. Здравствуй, мир!
Screenshot of output of index.gtpl at http://localhost:8080

Это оказалось несложно, не правда ли?


Хранение и манипулирование данными - это просто

Система для хранения и манипулирования парковочными извещениями достаточно проста. Она включает в себя Web-форму для создания извещений, а также возможности для просмотра, удаления и редактирования существующих извещений. Вначале мы создадим простую HTML-форму на основе шаблона Gaelyk (назовем его createticket.gtpl). Эта форма, показанная на рисунке 5, содержит набор полей, отражающих все необходимые атрибуты извещения.

Рисунок 5. Простая форма для добавления извещения
Screenshot of a blank simple ticket form

При отправке эта форма будет передавать данные грувлету (groovlet). Создайте директорию WEB-INF/groovy, в которой будут храниться все грувлеты нашего приложения (как вы помните, эта директория использовалась в статье Знакомство с Google App Engine). Далее создайте файл createticket.groovy в директории groovy, в котором будет код грувлета, обрабатывающего данные формы create-ticket.

Разумеется, ничто не мешает вам использовать такие технологии, как JDO или JPA (Java Persistence API) при работе с Gaelyk, однако существует другой, не менее удобный способ взаимодействия с хранилищем данных Google: класс Entity из API App Engine. Разработчики Gaelyk расширили функциональность Entity при помощи некоторых приемов программирования на Groovy, что позволило упростить манипулирование сохраняемыми объектами поистине волшебным образом.

Наш грувлет должен уметь извлекать значения элементов страницы createticket.gtpl и создавать новые извещения в хранилище данных. Благодаря классу Entity нам не придется создавать специальный POJO-класс, моделирующий извещения (аналогичный JDO-класс Triathlon использовался в статье Знакомство с Google App Engine). Извещения могут легко описываться в стиле Groovy и сохраняться практически без всяких усилий со стороны разработчика.

В листинге 4 показано, как грувлет извлекает данные формы из объекта params, предоставляемого Gaelyk (аналогичный объект также предоставляется в Grails), а затем создает экземпляр класса Entity.

Листинг 4. Создание экземпляра Entity
def formatter = new SimpleDateFormat("MM/dd/yyyy")
def offensedate = formatter.parse("${params.of_month}/${params.of_day}/${params.of_year}")

def ticket = new Entity("ticket")
ticket.officer = params.officer
ticket.license = params.plate
ticket.issuseDate = offensedate
ticket.location = params.location
ticket.notes = params.notes
ticket.offense = params.offense

Обратите внимание, что ticket является экземпляром общего класса Entity. Строка "ticket" String говорит о том, какого типа объектом является этот экземпляр. Подобное указание типа в виде строки оказывается очень удобным при поиске извещений. Далее, грувлет заполняет свойства экземпляра Entity данными, полученными через форму, например, свойству ticket.officer присваивается значение параметра officer. Форма содержит три поля для указания даты извещения, значения которых преобразуются в единый объект-дату при помощи класса SimpleDateFormat, после чего дата присваивается свойству issueDate.

К этому момент объект уже содержит все атрибуты извещения. Все что осталось - это сохранить его в хранилище.

ticket.save()

Сохранив объект, приложение должно перенаправить пользователя на страницу просмотра извещений. В этом нет ничего сложного: создается новый запрос, который передается на обработку грувлету view-ticket. 

redirect "viewticket.groovy?id=${ticket.key.id}"

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


Создание представлений: ничего сложного

В предыдущем примере, после сохранения объекта ticket в хранилище данных, мы создали еще один запрос к другому грувлету, который отвечает за просмотр существующих извещений. Фактически этот грувлет реализует операцию read на платформе Google App Engine, принимая на вход идентификатор созданного извещения. В коде грувлета используется класс KeyFactory из API Google для создания экземпляра Key, который в свою очередь служит для поиска извещения в хранилище через объект  datastoreService. Gaelyk автоматически предоставляет доступ к этому объекту во всех грувлетах (листинг 5).

Листинг 5. Просмотр ранее сохраненного экземпляра Entity
import com.google.appengine.api.datastore.KeyFactory

if (params["id"]) {
 def id = Long.parseLong(params["id"])
 try {
   def key = KeyFactory.createKey("ticket", id)
   def ticket = datastoreService.get(key)

   request.setAttribute "ticket", ticket

   forward "viewticket.gtpl"

   } catch (Throwable t) {
    //перенаправление на страницу с сообщением об ошибке...
   }
} else {
 forward "index.gtpl"
}

Как только нужное извещение найдено в хранилище, оно помещается в HTTP-запрос (который автоматически доступен в каждом грувлете через переменную request), после чего запрос передается на обработку странице viewticket.gtpl. Как любая подобная JSP-страница, она отображает атрибуты переданного в запросе извещения.

Как видно из листинга 6, Gaelyk поддерживает директиву includes. Другими словами, вы можете включать в свои шаблоны .gptl другие файлы подобно тому, как это делается в JSP. При этом во всех страницах .gptl у вас будет доступ к переменной request, представляющей собой текущий HTTP-запрос.

Листинг 6. Страница GTPL для просмотра атрибутов единственного объекта Entity
<% include "/WEB-INF/includes/header.gtpl" %>

<% def ticket = request.getAttribute("ticket") %>

<div class="info">
 <h2>Parking Ticket</h2>
 </div>

<table>
<tr>
	<th>Issuing Officer</th>
	<th>Vehicle Plate</th>
	<th>Date</th>
	<th>Offense</th>
	<th>Location</th>
	<th>Notes</th>
  </tr>
 <tr>
	<td>${ticket.officer} </td>
	<td>${ticket.license}</td>
	<td>${ticket.issuseDate}</td>
	<td>${ticket.offense}</td>
	<td>${ticket.location}</td>
	<td>${ticket.notes}</td>
  </tr>
 </table>

<% include "/WEB-INF/includes/footer.gtpl" %>

Вероятно, вы убедились, что Gaelyk превращает создание легковесных Web-приложений для платформы Google App Engine в легкое упражнение. Более того, работа с хранилищем данных App Engine также упрощается до предела. Вам лишь нужно немного привыкнуть к низкоуровневому API Google, например, классу Entity, а также выполнению запросов, которые чем-то напоминают выборку документов из CouchDB. Обратите внимание на пример выборки извещений, приведенный в листинге 7.

Листинг 7. Просмотр набора объектов Entity
import com.google.appengine.api.datastore.Query
import static com.google.appengine.api.datastore.FetchOptions.Builder.withLimit

try {
 def query = new Query("ticket")
 query.addSort("issuseDate", Query.SortDirection.DESCENDING)
 def preparedQuery = datastoreService.prepare(query)
 def tickets = preparedQuery.asList( withLimit(10) )

 request.setAttribute "tickets", tickets
forward "index.gtpl"
} catch (Throwable t) {
 forward "index.gtpl"
}

В листинге используется класс Query из API App Engine. Как видно из примера, вы можете сортировать полученные результаты, а также ограничивать их количество. Вы не сможете использовать SQL, однако можете быть уверены, что данные благополучно хранятся и могут быть получены, пусть и несколько другим способом.

Развертывание приложения на облачных серверах не требует никаких усилий, как и в статье Знакомство с Google App Engine. Модуль App Engine для Eclipse позволяет вам просто нажать на кнопку Deploy App Engine Project  (развернуть приложение на платформе App Engine), возложив всю работу на инфраструктуру Google. Вы легко можете развернуть демонстрационное приложение прямо сейчас, просто загрузив его исходный код. Приложение содержит компоненты, которые не были включены в статью из-за нехватки места. Например, в нем реализована функция удаления извещений, расширен пользовательский интерфейс, а также продемонстрированы некоторые дополнительные возможности Gaelyk.


Быстрая разработка приложений: теперь это просто

Платформы облачных вычислений и не ограниченные схемами хранилища данных, базирующиеся на инновационных открытых технологиях, несомненно, являются частью будущего разработки Java-приложений. Их легко начать использовать, в частности потому, что аппаратное и программное обеспечение, продемонстрированное в этой статье, предоставляется бесплатно. В тот момент, когда Google начнет взимать с вас плату за аренду инфраструктуры, вы легко сможете это себе позволить, поскольку 5 млн обращений в месяц – это огромный объем трафика. В свою очередь инфраструктура Gaelyk позволяет дополнительно ускорить разработку Web-приложений. В общем, создание приложений на Java становится все более приятным занятием, вы не находите?


Загрузка

ОписаниеИмяРазмер
Исходный код примеров к статьеj-javadev2-6.zip8.3 МБ

Ресурсы

Научиться

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

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java
ArticleID=644218
ArticleTitle=Вторая волна разработки Java-приложений: Инфраструктура Gaelyk в приложениях для Google App Engine
publish-date=04012011