GLO-4002 - Site du cours 2023

Temps estimé: 2 heures

Laboratoire sur la mise en production

L'objectif du laboratoire est de vous familiariser avec la mise en production d'une application et des requis spécifiques à cette étape de la vie de vos applications.

Création d'un compte Heroku

À des fins de simplicité, vous aurez à déployer les applications du laboratoire sur la plateforme Heroku. Un compte de base permet de tester la plateforme et de déployer des applications sur des instances de serveurs appelées Free Dynos.

⚠️ Veuillez noter que le cours n'a aucune affiliation avec la plateforme Heroku et qu'elle a été choisie seulement parce qu'elle offrait les outils les plus simples pour les besoins du cours.

Cliquez sur le lien suivant pour vous créer un compte: https://signup.heroku.com/.

Déploiement d'une première application

Si vous n'êtes pas familiés avec Heroku, suivez les étapes suivantes afin d'en faire un tour rapide. Si vous connaissez déjà bien la plateforme, vous pouvez passer à la section suivante.

Une fois votre compte créé, suivez les étapes suivantes pour déployer l'application type fournie par Heroku:

  • Créez un nouveau fork à partir du projet Java Getting Started fourni par Heroku.
  • Connectez-vous à votre nouveau compte Heroku si ce n'est pas déjà fait.
  • À partir du Dashboard, cliquez sur le bouton Create new app et entrez les informations demandées:
    • Nom de l'application: glo4002-USERNAME-java-getting-started
    • Région: United States
  • Choisissez GitHub comme méthode de déploiement pour y associer votre compte.
  • Entrez le nom du fork que vous avez créé précédemment (java-getting-started) et cliquez sur le bouton Search. Une fois le projet trouvé, cliquez sur Connect.
  • Lorsque le projet sera connecté à Heroku, vous aurez l'option de déployer automatiquement ou manuellement le projet. Choisissez l'option manuelle et déployez la branche master.
  • Heroku détectera automatiquement le type de projet contenu dans le repo ainsi que le système de build utilisé. Vous devriez voir dans les logs de déploiement que l'application est compilée et préparée au déploiement.
  • Une fois le déploiement terminé, cliquez sur le bouton View pour accéder à l'URL de votre application. En plus de la page principale, vous pourrez aller à /db pour voir les informations provenant de la base de données de l'exemple en question.

Exercice

Code base

Vous rappelez-vous de l'application Cart-OO? Non? C'est normal, nous ne l'avons pas fait cette année! Vous la retrouverez ici. Il a été décidé, après plusieurs semaines de délai, de finalement l'envoyer en production! Hourra!

Lors du développement, on vous avait avisé que le port du serveur à utiliser pouvait être une valeur quelconque vers lequel le trafic serait redirigé. Toutefois, la plateforme de déploiement n'avait pas encore été choisie à ce moment-là... Puisque l'application sera maintenant déployée sur Heroku, on vous demande de modifier l'application pour que le port puisse être dynamique et reçu en paramètre.

Veuillez forker le dépôt GitHub suivant: https://github.com/GLO4002UL/officiel-lab-production

Premier défi

Modifiez l'application cart-oo dont vous venez de faire un fork pour qu'on puisse la démarrer sur un numéro de port passé en argument.

Une fois que c'est fait, mettez à jour votre pom.xml afin que Maven crée ce qu'on appelle un JAR-with-dependencies, ou encore, un Uber JAR. Ajoutez le bloc de code suivant dans la section <plugins></plugins>:

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-shade-plugin</artifactId>
   <version>3.2.1</version>
   <executions>
       <execution>
           <phase>package</phase>
           <goals>
               <goal>shade</goal>
           </goals>
           <configuration>
               <createDependencyReducedPom>false</createDependencyReducedPom>
               <transformers>
                   <transformer
                       implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                       <mainClass>ca.ulaval.glo4002.cart.CartServer</mainClass>
                   </transformer>
                   <transformer
                       implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
               </transformers>
           </configuration>
       </execution>
   </executions>
</plugin>

Et finalement, le déploiement requiert un fichier nommé Procfile qui décrit comment démarrer votre application. C'est dans ce fichier qu'on pourra également passer nos paramètres dont la fameuse variable \$PORT. Voici un exemple de Procfile:

web: java -Dport=$PORT -Dparam1=value1 -Dparam2=value2 -jar target/application-name-1.0.0-SNAPSHOT.jar

Puisque c'est le premier déploiement de l'application, veuillez la déployer en spécifiant le stockage In-Memory (donc, avec l'option -Dstore=memory).

Une fois que vous avez réussi à déployer l'application correctement, allez vérifier que tout fonctionne via l'interface web: https://epic-austin-420b87.netlify.com/ (changez l'URL en haut à droite).

C'est à vous de jouer!

Deuxième défi

Maintenant que vous avez trouvé le problème avec le port, l'application démarre maintenant correctement. Félicitations!

Toutefois, vous recevez des plaintes de clients qui indiquent qu'ils ne peuvent rien acheter. Votre collègue (qui a apparemment été convoqué par le boss...) vous assure pourtant que la base de données contient des items!

Si vous ne voulez pas finir comme votre (ancien?) collègue, assurez-vous de démarrer l'application en mode démo (i.e. -Dmode=demo) afin de populer la base de données et de vous assurez que tout roule! Regardez dans l'interface web pour vous assurez que les produits sont bel et bien listés... oops! Que se passe-t-il? Est-ce que les logs vous aide?

Il y a peut-être un peu trop de log en fait. Trop c'est comme pas assez! Prenez le temps de vous familiariser avec logback et sa configuration (un début de configuration est dans le fichier src/main/resources/logback.xml). Pouvez-vous réduire un peu la verbosité de tout ça? Idéalement, on ne devrait plus voir les logs de jersey... seulement les vraies erreurs! Attention aussi de ne pas juste supprimer tous les logs, les erreurs nous intéressent toujours...

Rappel: Pour populer la base de données, utilisez le mode démo qui s'active avec -Dmode=demo.

Troisième défi: Release Part 1

Puisque l’application est destinée à aller en production, il est généralement considéré comme une bonne pratique de créer une nouvelle version de celle-ci avant son déploiement.

Tout d’abord, mettez à jour votre pom.xml avec les informations de votre dépôt GitHub afin que Maven sache où pousser ses changements de la release. Ajoutez le bloc suivant à l’intérieur de <project></project>:

<scm>
  <connection>scm:git:git@github.com:YOURUSERNAME/officiel-lab-cart-oo.git</connection>
  <developerConnection>scm:git:git@github.com:YOURUSERNAME/officiel-lab-cart-oo.git</developerConnection>
  <url>https://github.com/YOURUSERNAME/officiel-lab-cart-oo</url>
  <tag>HEAD</tag>
</scm>

Vous êtes maintenant prêt à créer votre release! Exécutez la commande suivante:

mvn release:perform -Darguments="-Dmaven.deploy.skip=true"

Une fois la release créée, vous pouvez redéployer votre application.

NOTE: Il est à noter que Heroku ne supporte pas la notion de tag pour le déploiement. Si vous souhaitez déployer un tag, vous aurez à pusher le bon commit sur votre branche de déploiement. Vous trouverez un exemple ci-dessous. Soyez prudent avec les commandes qui suivent, on effectue un force push sur la branche de destination (la branche production dans l’exemple):

mvn release:perform -Darguments="-Dmaven.deploy.skip=true" # Release de la nouvelle version
git push -f origin cart-1.0.0^{}:production # Ceci assume que vous déployez la branche production

Maven Release Plugin

Lors de l’invocation du Maven Release Plugin, Maven exécutera les étapes suivantes:

  • Compiler l’application
  • Exécuter les tests unitaires
  • Assembler le JAR final
  • Exécuter les tests d’intégration
  • Mettre à jour la version pour retirer le suffixe -SNAPSHOT
  • Commiter les changements de version
  • Créer un tag pour la version à releaser
  • Cloner et recompiler / assembler le tag
  • Mettre à jour la version pour passer à la prochaine version -SNAPSHOT
  • Compiler / assembler la nouvelle version -SNAPSHOT
  • Commiter la mise à jour de la version -SNAPSHOT

Quatrième défi: Release Part 2

Si vous avez tenté de déployer l’application et que plus rien ne fonctionne c’est que vous avez oublié de mettre à jour le fichier Procfile avec la nouvelle version de l’application! N’ayez crainte, nous allons résoudre ceci de façon permanente.

Afin d’éviter ce genre de situation où une valeur de version hard-codée est utilisée dans un fichier de configuration, il est possible de configurer maven-shade-plugin pour que le JAR résultant ait toujours le même nom.

Mettez à jour la configuration du plugin maven-shade-plugin dans votre fichier pom.xml avec cette nouvelle ligne:

<plugin>
  ...
  <artifactId>maven-shade-plugin</artifactId>
  ...
  <configuration>
    ...
    <!-- Défini le nom du JAR final -->
    <finalName>cart-server-app</finalName>
  </configuration>
  ...
</plugin>

Vous pouvez maintenant mettre à jour votre fichier Procfile pour lancer target/cart-server-app.jar sans spécifier la version.