AWS Lambda - Implémentation en Java
Introduction
Lors de ce chapitre, nous nous proposons d’examiner un certain nombre de projets Java qui implémentent des fonctions AWS Lambda. Le lecteur sera guidé à créer de nouveaux projets Java et, pour ceux qui préfèrent télécharger les exemples présentés plutôt que de parcourir les étapes nécessaires, ces projets sont disponibles dans le répertoire intitulé chapter3 du repository GitHub de l’ouvrage.
L’interface RequestHandler
Nous avons vu que les classes Java qui représentent des fonctions AWS Lambda peuvent implémenter l’interface RequestHandler. Nous allons regarder de plus près cette interface, mais, avant tout, précisons encore une fois que son implémentation par des fonctions Lambda en Java n’est pas obligatoire, juste recommandée.
Ouvrez un terminal en ligne de commande, créez un nouveau répertoire dédié à votre nouveau projet Java et positionnez-vous dans ce répertoire.
Exécutez la commande sam init, comme le montre le listing suivant :
nicolas@BEL20:~/test$ sam init \
--location https://github.com/nicolasduminil/sam-template
project_name [chapter2-function]: chapter3
aws_lambda_resource_name [Chapter2Resource]: Chapter3Resource
java_package_name [fr.simplex_software.aws.lambda.functions]:
java_class_name [Chapter2Function]: Chapter3Function
java_handler_method_name [handleRequest]:
maven_group_id [fr.simplex-software.aws.lambda]:
maven_artifact_id [chapter2-function]: chapter3
maven_version [1.0.0-SNAPSHOT]:
function_name [AwsLambdaTestFunction]: Chapter3Function
Ici on génère notre nouveau projet Java avec la commande sam init, comme on l’a déjà fait au chapitre précédent, tout en prenant soin de remplacer les valeurs par défaut, proposées entre crochets, par des valeurs qui font sens pour notre projet courant.
Ouvrez le projet Java nouvellement créé dans votre IDE.
Dans la fenêtre du navigateur des projets de l’IDE, ouvrez la classe Java Chapter3Function. Vous allez retrouver la classe extrêmement simple générée automatiquement par notre template Cookie Cutter.
Dans la même fenêtre du navigateur des projets, ouvrez le fichier pom.xml. Éditez ce fichier de manière à remplacer son contenu avec celui présenté dans le listing suivant :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 ...
L’utilisation des POJO (Plain Old Java Objects)
Le projet Java que nous venons de présenter montre comme écrire une fonction AWS Lambda qui reçoit un événement comme argument d’entrée. Cet événement est représenté le plus souvent comme un objet de classe HashMap où, aussi bien les clés que les valeurs, sont des chaînes de caractères. Le plus souvent, mais pas toujours, car rien n’empêche que notre argument d’entrée soit un JavaBean, ou POJO, comme on les appelle également.
Un POJO est un objet qui encapsule de la logique métier, en général une classe appartenant au domaine de votre application comme Customer, Order, Employee, etc. Pour qu’un objet Java se qualifie en tant que POJO il doit satisfaire les conditions suivantes :
-
Sa classe ne doit être ni une sous-classe d’entreprise ni l’implémentation d’une interface d’entreprise. Par classe ou interface d’entreprise, nous entendons ici des classes ou interfaces appartenant au package javax ou jakarta.
-
Il ne doit pas contenir d’annotations d’entreprise, par exemple @javax.persistence, etc.
Tout POJO est un JavaBean, mais tout JavaBean n’est pas un POJO. Car pour être un JavaBean, un POJO doit :
-
implémenter l’interface java.io.Serializable
-
toutes ses propriétés doivent être privées
-
toutes ses propriétés doivent avoir des getter et des setter publiques
-
avoir un constructeur sans argument
Voilà pour la théorie. Le projet Java qui illustre ce chapitre contient le POJO présenté dans le listing suivant :
package fr.simplex_software.aws.lambda.functions.pojo; ...
L’interface RequestStreamHandler
La deuxième interface qui peut être implémentée par une fonction Lambda en Java est RequestStreamHandler. Sa particularité consiste dans le fait que, sa méthode handleRequest() prend un flux d’entrée, permettant de lire les valeurs à traiter, et un flux de sortie permettant d’écrire les résultats du traitement. Contrairement à cette dernière, la méthode homologue de la classe RequestHandler prend comme paramètres directement les valeurs d’entrée à passer à la fonction pour traitement et renvoie en retour le résultat de ce traitement.
Notre projet Java servant à illustrer ce chapitre contient également une fonction Lambda qui implémente cette interface. En voici le listing :
package fr.simplex_software.aws.lambda.functions;
import com.amazonaws.services.lambda.runtime.*;
import javax.json.bind.*;
import java.io.*;
import java.nio.charset.*;
import java.util.*;
public class Chapter3StreamFunction implements RequestStreamHandler
{
@Override
public void handleRequest(InputStream inputStream, OutputStream
outputStream, Context context) throws IOException
{
LambdaLogger logger = context.getLogger();
Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true));
try (
BufferedReader reader = new BufferedReader(new
InputStreamReader(inputStream, StandardCharsets.US_ASCII));
PrintWriter writer = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(outputStream, StandardCharsets.US_ASCII)))
)
{
HashMap<?,?> event = jsonb.fromJson(reader, HashMap.class);
logger.log("### We got a stream of type: " +
inputStream.getClass().toString());
logger.log("### We got an event of type: " +
event.getClass().toString());
writer.write(jsonb.toJson(event));
if (writer.checkError()) ...