03 lutego 2009

Wdrażanie i aktualizacja aplikacji w Grails - rozdział 12 z "Beginning Groovy and Grails"

Po bardzo burzliwych rozdziałach przedstawiających architekturę Grails i potencjał jego wtyczek przyszła pora na niewielkie "podsumowanie" w postaci rozdziału 12. "Deploying and Upgrading". Autorzy wyjaśniają w nim, w jaki sposób uruchamiamy aplikacje grailsowe w ramach serwerów aplikacyjnych Java EE oraz aktualizujemy wersję Grails w aplikacji. Pojawi się również Gant, w którym stworzone zostanie nowe polecenie grails.

Grails dystrybuowany jest z całym środowiskiem rozwojowym opartym na Jetty oraz relacyjnej bazie danych HSQLDB. Wystarczy wykonać polecenie grails run-app, aby uruchomić aplikację w kompletnym środowisku uruchomieniowym - serwerem aplikacji i bazą danych. Brakuje w nim jednak cech środowisk produkcyjnych, z mechanizmami równoważenia obciążenia (ang. load balancing), wysokiej dostępności (ang. high availability) oraz klastrowania (ang. clustering) dla serwera aplikacyjnego oraz wydajnej i transakcyjnej bazy danych.

Wdrożenie (ang. deployment) aplikacji grailsowej składa się z trzech kroków. Najpierw definiujemy konfigurację aplikacji dla poszczególnych środowisk (rozwojowego, testowego i produkcyjnego), tworzymy wersję wdrożeniową w postaci pliku WAR (ang. Web ARchive), aby w końcu wdrożyć go na serwerze aplikacyjnym (kontenerze webowym/servletów).

W każdym ze środowisk, przyjdzie nam zdefiniować specyficzne parametry konfiguracyjne. Polecenie grails uruchamia środowisko w zależności od swojego drugiego parametru na linii poleceń lub w plikach konfiguracyjnych DataSource.groovy lub Config.groovy. Wyróżniamy trzy predefiniowane wartości dla każdego ze środowisk. Dla rozwojowego środowiska jest to dev (na linii poleceń) oraz development w plikach konfiguracyjnych, test (oba parametry) dla testowego oraz prod i production dla środowiska produkcyjnego. Możemy zdefiniować dodatkowe środowiska, np. testów integracyjnych, testów akceptacyjnych (ang. UAT - user Acceptance Tests) oraz testów wydajnościowych (ang. PT - Performance Tests) z dowolnie wybranymi przez nas identyfikatorami. Wskazanie własnego środowiska to wykonanie polecenia grails z parametrem grails.env, np. grails -Dgrails.env=uat run-app.

Grails zawiera 4 główne kategorie konfiguracyjne - konfiguracja adresów URL, domknięcie do wykonania przy uruchomieniu i zatrzymaniu aplikacji, źródła danych i poziomy komunikatów. Katalog grails-app/config jest katalogiem konfiguracyjnym Grails.

Domknięcie init z parametrem servletContext typu javax.servlet.ServletContext w grails-app/config/Bootstrap.groovy jest wykonywane każdorazowo przy uruchomieniu aplikacji (włączając w to sytuację ponownego wdrożenia), a destroy przy zatrzymaniu, aczkolwiek nie jest to gwarantowane, np. podczas zatrzymania serwera aplikacyjnego.

Za pomocą GrailsUtil.environment() możemy określić środowisko, w którym uruchomiona jest aplikacja i podjąć stosowne czynności.

Domyślnie, Grails skonfigurowany jest z wbudowaną bazą danych HSQLDB w trybie pamięciowym (ang. in-memory). Tym samym każde uruchomienie aplikacji to pusta baza danych. W grails-app/config/DataSource.groovy konfigurujemy bazę (sekcja dataSource) i Hibernate (sekcja hibernate). Możliwa jest konfiguracja obu per środowisko w sekcji environments, która nadpisuje bardziej ogólną konfigurację w sekcjach dataSource i hibernate. Nie zapominajmy o umieszczeniu pliku jar sterownika bazy danych w katalogu lib w projekcie. Podczas tworzenia paczki wdrożeniowej Grails umieści go w WEB-INF/lib.

Konfiguracja (poziomu) komunikatów oparta jest na Apache Commons Logging oraz Apache log4j. Znajduje się w grails-app/config/Config.groovy. Grails posiada kilka specjalnych kanałów (ang. loggers) - grails.app.controller dla komunikatów wszystkich kontrolerów, grails.app.domain dla klas domenowych, grails.app.service dla usług oraz grails.app.taglib dla znaczników GSP.

Tworzymy paczkę wdrożeniową aplikacji poleceniem grails war. Autorzy sugerują jednak bardziej wyrafinowany sposób składający się z...7 kroków - pobranie aktualnej wersji z repozytorium, wykonanie testów, zmianę parametru app.version w application.properties samodzielnie bądź poleceniem grails set-version, aby ustawić wersję przygotowywanej aplikacji, np. w formacie X.Y.Z, grails clean, dopiero wtedy grails war (prawdopodobnie ze wskazaniem środowiska produkcyjnego, np. grails prod war), ponowna zmiana app.version i zatwierdzenie application.properties do repozytorium.

W sekcji "Deploying to an Application Server" autorzy piszą "a WAR file can be deployed to Java EE application servers such as JBoss, GlassFish, Apache Geronimo...". I to jest to, co mi się bardzo spodobało. Jest Apache Geronimo! Tylko dlaczego dopiero na 3. pozycji?!

Grails umożliwia uruchomienie aplikacji na porcie HTTPS poleceniem grails run-https. Poza domyślnym portem 8080, aplikacja będzie dostępna na 8443.

Grails nie udostępnia specjalnych poleceń upraszczających wdrożenie aplikacji. Zaleca się użycie narzędzia Gant do tego celu. Gant jest narzędziem automatyzującym pracę w projekcie przez połączenie cech Apache Ant z Groovy - z pierwszego mamy gotowe zadania, a z drugiego język do ich oskryptowania (zamiast korzystać tradycyjnie z XML w Ant). Tak na prawdę polecenia grails to uruchamianie odpowiednich "skryptów" Gant. Stworzenie nowego polecenia dla grails to napisanie skryptu Gant i umieszczenie go w dowolnym z poniższych katalogów - <katalog-domowy-użytkownika>/.grails/scripts, <katalog-projektu>/scripts, <katalog-projektu>/plugins/*/scripts oraz <katalog-domowy-grails>/scripts. Autorzy przedstawiają przykładowy skrypt - a tym samym nowe polecenie grails deploy - do wdrożenia aplikacji na serwerze JBoss AS. Więcej na stronie http://www.beginninggroovyandgrails.com (dlaczego dopiero teraz pojawia się wzmianka o tej stronie?!).

Podczas uruchomienia aplikacji poleceniem grails run-app(s) Grails sprawdza parametr app.grails.version w application.properties, który znajduje się w katalogu głównym projektu aplikacji. Jeśli wartość app.grails.version nie jest zgodna z bieżącą wersją Grails pojawi się komunikat informujący o rozbieżności wersji. Wykonanie grails upgrade uaktualni pliki Grails w projekcie...nadpisując już istniejące (!) Kolejny powód, aby utrzymywać projekt aplikacji w repozytorium.

Jest to ostatni rozdział dotyczący zagadnień projektowych Grails jako szkieletu webowego Java EE. Kolejny i tym samym ostatni będzie o tworzeniu różnego rodzaju klientów dla naszej aplikacji.