Il y a à peu près un an, Google ouvrait l'App Engine aux développeurs, il
n'était alors possible de déployer que des applications développées en Python.

Pour rappel, Google App Engine est une offre de Cloud Computing permettant aux
développeurs d’héberger leurs applications Web sur les serveurs de Google. Les
applications ainsi hébergées bénéficient de ce fait de la même capacité de
montée en charge que les services Google tels que Gmail ou Google
Finance.
Google n’est pas la seule entreprise positionnée sur ce secteur, bien que pas
tout à fait similaires, Amazon et Microsoft ont eux aussi leurs offres avec
respectivement AWS et Windows Azure.
Un des atouts de Google App Engine c’est que gratuitement un développeur peut
déployer une application qui soit accédées à raison de 5 millions de pages vues
par mois. Ce qui est somme toute une offre d’hébergement intéressante. Au-delà
de ces quotas, il est possible d’acheter des ressources supplémentaires.
Depuis quelques mois, nous pouvions voir dans la roadmap de ce projet que le
support d’autres langages était un des objectifs de Google. Aujourd'hui, c’est
chose faite, Google ouvre son service à une nouvelle communauté et
contrairement à leur poisson d’avril, ce n’est pas Fortran mais bien Java qui
est désormais supporté.
Cette nouvelle devrait donc être accueillie avec un vif enthousiasme lorsque
l’on sait que le support de Java a été l’une des premières évolutions suggérées
par les développeurs lors de la sortie de la première version de l’App
Engine.
La version Java ne déroge pas au qualificatif de « Simple d’utilisation » qui
caractérisait la version Python. En effet, il n’y a pas de différence majeure
dans l’approche qu’ont ses deux dernières. Un atout supplémentaire de la
version Java et qui a son importance, c’est le fait qu’elle s’accompagne d’un
plugin Eclipse. Il est ainsi possible de créer une application et de la
déployer en quelques clics.
De plus, l’intégration avec GWT (Google Web Toolkit) est enfantine et proposée
par défaut par le plugin.
L’environnement de développement App Engine Java supporte les versions Java 5
et Java 6, sachant que sur les serveurs distants c’est la 6 qui est supportée.
Les pré-requis au développement et au déploiement d’applications sur la
plate-forme sont relativement faibles : avoir installé Java et le SDK de l’App
Engine. L’installation du plugin Eclipse est bien entendu un plus non
négligeable.
L’administration des applications se fait via la même interface que pour les
applications Python. Il est ainsi possible de voir la répartition de la charge
dans le temps, les requêtes HTTP les plus récurrentes, le taux d’utilisation
ramené aux quotas. Il est également possible de consulter les logs. Enfin, une
page permet d’accéder aux données stockées dans le Datastore.
Etudions de plus près l’architecture d’un projet et l’utilisation des APIs
Passons à la pratique :
Les applications Google App Engine doivent être structurées en respectant
l’arborescence WAR, ainsi, si vous créez un projet via le plugin Eclipse, vous
obtiendrez une structuration semblable à celle-ci :

Cette arborescence de projet ne présente pas de spécificité particulière, on
notera la présence d’un fichier web.xml permettant d’assurer le mapping entre
les URLs et les classes des Servlets.
Lorsque vous déployez une application sur Google App Engine, une association
s’opère entre les fichiers que vous transférez sur les serveurs de Google et
les applications que vous êtes en mesure d’administrer. Cette association est
possible grâce à un identifiant que vous vous devez de retranscrire dans le
fichier appengine-web.xml. Ce fichier est l’équivalent du fichier app.yaml de
la version Python de l’App Engine.
Les Servlets sont tout à fait communes et ne différent pas de celles que l’on
peut développer dans une application traditionnelle. La Servlet d’un HelloWorld
pourrait donc se présenter ainsi :
package com.sfeir.demo;
import java.io.IOException;
import javax.servlet.http.*;
public class DemoServlet extends HttpServlet {
public void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws
IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello,
world");
}
}
Maintenant que nous savons qu’il n’est pas difficile de créer un projet,
intéressons nous aux APIs spécifiques de Google App Engine.
Utiliser les APIs :
Authentification
Ajouter un système d’authentification des utilisateurs se fait tout aussi
facilement qu’avec la version Python :
package com.sfeir.demo;
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
public class DemoServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse
resp)
throws IOException {
UserService userService =
UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user != null) {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, " +
user.getNickname());
} else {
resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
}
}
}
Ici, on utilise le UserService pour récupérer l’utilisateur actuellement
connecté à l’application. S’il y a bel et bien un utilisateur authentifié, nous
lui affichons un message de bienvenue et si ce n’est pas le cas, l’API nous
permet de le rediriger vers une page de login. Lorsque vous travaillez en «
local », le système d’authentification est émulé, il n’y a pas de vérification
à proprement parler de l’existence des utilisateurs. Lorsque vous déployez
votre application, le UserService se base sur les Google Accounts pour vérifier
l’existence des utilisateurs.
Il est également possible de savoir si l’utilisateur actuellement authentifié
est un administrateur de l’application et ainsi de lui donner accès ou non à
certaines fonctionnalités.
Persistance
Attention, comme pour la version Python de Google App Engine, le stockage des
données ne s’effectue pas dans une base de données relationnelle. Google
dispose de son propre formalisme de stockage des données qui s’apparente à une
Map multidimensionnelle partagée.
Le développeur dispose de trois solutions distinctes pour persister ses
données, en effet, Google App Engine Java implémente JDO (Java Data Object),
JPA (Java Persitance API) et met également à disposition une API de plus bas
niveau (Datastore API).
Dans cette version de Google App Engine, Google pousse un Framework de
persistance : DataNucleus. Sa configuration se fait très simplement (voir doc
pour plus de détails)
Voici un exemple utilisant JDO, la définition des données à persister se fait
par annotation.
Ci-dessous, l’objet Comment est défini comme pouvant être persisté, en le
sauvant, les éléments annotés comme @Persistent feront parti de la sauvegarde.
package com.sfeir.demo;
import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.users.User;
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Comment {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
@Persistent
private User author;
@Persistent
private String content;
@Persistent
private Date date;
public Comment(User author, String content, Date date) {
this.author = author;
this.content = content;
this.date = date;
}
…
}
Il est ensuite très simple de manipuler cet objet au travers de l’API. Ainsi,
pour persister une instance de cet objet, on peut utiliser le
PersistenceManager de la manière suivante :
Comment comment = new Comment(user.getNickName(), content, new
Date()) ;
PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
PersistenceManager pm =
pmfInstance.get().getPersistenceManager();
try {
pm.makePersistent(comment);
} finally {
pm.close();
}
Avec ce PersistenceManager, il est tout aussi simple de récupérer un objet
pm.getObjectById(…) ou encore de le supprimer pm.deletePersistent(…).
Au même titre qu’il était possible d’interroger la base au travers du GQL dans
la version Python, il est ici possible d’utiliser un langage de requête proche
de SQL pour récupérer des données, il s’agit de JDOQL.
On pourrait récupérer la liste de nos commentaires ainsi :
PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
PersistenceManager pm = pmfInstance.get().getPersistenceManager();
String query = "select from " + Comment.class.getName();
List<Comment> comments = (List<Comment>)
pm.newQuery(query).execute() ;
Gestion d'un cache mémoire
Afin de ne pas surcharger le Datastore avec des requêtes récurrentes, il peut
être intéressant de stocker un certain nombre d’informations dans un cache
mémoire. Cela peut se faire très simplement au travers de l’utilisation de la
Memcache API.
cache =
CacheManager.getInstance().getCacheFactory().createCache(Collections.emptyMap());
cache.put(‘‘cachedInteger’’, 25) ;
Integer cachedValue = (Integer) cache.get(‘‘cachedInteger’’);
Dans l’exemple ci-dessus, après avoir récupéré l’instance du cache mémoire, on
y insère un entier à la clef « cachedInteger » au travers d’un put. Un simple
get avec la clef nous permet de récupérer la donnée que nous avions mise en
cache.
Le cache est utilisé pour cet exemple de manière très simpliste mais on
pourrait imaginer l’utiliser pour retourner des informations ayant plus de
valeur, comme le contenu RSS de l’application ou encore une page fréquemment
requêtée.
Cette API de cache propose d’autres fonctionnalités intéressantes comme la
possibilité de définir une période de validité pendant laquelle les données
peuvent être considérées comme « fraiches ». Différentes politiques
de gestion sont également applicables, ainsi il est possible de n’ajouter la
donnée que si celle-ci est déjà présente ou réciproquement.
Envoi de mail
L'envoi de mail fait partie des fonctionnalités intégrées à Google App Engine
et relativement simples à mettre en place au sein d'un projet.
Dans cette version Java, l'API implémente l'interface JavaMail, pour des
raisons de sécurité, seules les adresses d’un administrateur de l’application
ou celle de l’utilisateur couramment authentifié peuvent être spécifiées comme
adresses de l’émetteur.
Properties props = new Properties();
Session session = Session.getDefaultInstance(props,
null);
String msgBody = "Contenu du mail";
...
Message msg = new MimeMessage(session);
msg.setFrom(new
InternetAddress("admin@mondomaine.com"));
msg.addRecipient(Message.RecipientType.TO,new
InternetAddress("destinataire@sondomaine.com", "Destinataire"));
msg.setSubject("Email envoyé par Google App
Engine");
msg.setText(msgBody);
Transport.send(msg);
L’exemple ci-dessus montre l’envoi d’un mail basic, sachez qu’il est également
possible d’ajouter des pièces jointes (voir types MIME autorisés) avec la
contrainte toutefois que l’e-mail ne dépasse pas les 1mb.
Comme pour la version Python, il est également mis à la disposition des
développeurs une API permettant d’interroger des hôtes distants (via l’API URL
FETCH) et une autre permettant de manipuler des images.
Cette version de Google App Engine étant toute récente, il va être intéressant
de suivre l’adhésion des développeurs de la communauté Java à ce service. D’une
part, elle offre une grande facilité de développement et de ce fait un gain de
temps dans l’élaboration d’applications, ce qui devrait en attirer plus d’un.
D’autre part, tout comme pour la version Python un certain nombre de quotas et
de restrictions sont à prendre en compte lors de l’utilisation de ce service,
ce qui exclu certain types d’applications de cette offre d’hébergement.
Cette nouvelle version est également un beau coup de pousse donné à GWT, en
effet le plugin Eclipse permet de créer en quelques clics une application GWT
pour Google App Engine et devrait donc amener davantage de développeurs à
adopter ce Framework Web.
Google Guice sera peut être un autre des bénéficiaires de cette version Java,
bien qu’il ne soit pas poussé outre mesure par Google pour être associé à
Google App Engine, sa légèreté et sa simplicité d’utilisation devrait lui
permettre de s’intégrer facilement aux applications déployées sur la
plate-forme.
Quoi qu’il en soit c’est une nouveauté que nous nous devons de suivre.
Références :
Pour
s'inscrire
L'annonce officielle
Le Coud
Computing
Tout sur Google App
Engine
DataNucleus
Découvrir GWT
En savoir plus sur
GUICE
Amazon Web Services
Windows
Azure