-
Archives
- mai 2024
- avril 2024
- mars 2024
- décembre 2023
- novembre 2023
- octobre 2023
- septembre 2023
- mars 2023
- octobre 2022
- août 2022
- juillet 2022
- juin 2022
- avril 2022
- mars 2022
- février 2022
- décembre 2021
- novembre 2021
- juillet 2021
- avril 2020
- juillet 2019
- juin 2019
- avril 2019
- janvier 2019
- mars 2018
- janvier 2018
- juin 2017
- décembre 2016
- février 2016
- janvier 2016
- novembre 2015
- mai 2015
- janvier 2015
- décembre 2014
- août 2014
- février 2014
-
Méta
Protégé : Accès serveur calcul CERIS
Publié dans Développement
Saisissez votre mot de passe pour accéder aux commentaires.
Ajout de Javadoc dans un programme Java
La constitution de la documentation dans un projet Java peut être simplement réalisé directement dans le code source en utilisant un formatage spécifique dans un commentaire.
Le système Javadoc existe depuis la création de Java (https://en.wikipedia.org/wiki/Javadoc) et invite le développeur à produire directement dans son programme la documentation.
En premier lieu, on peut documenter le package si un fichier package-info.java est disponible. Je vous renvoie vers cette documentation qui explique l’utilité de ce fichier: https://www.baeldung.com/java-package-info. Dans le cas d’un petit projet informatique, voici un commentaire explique l’utilisation d’un package:
/**
* main est le package principal du projet de test d'intégration de Jenkins
*/
package main;
Pour faire la suite, nous allons documenter une classe Main dans le fichier main.java :
/**
* Classe de test pour l'intégration de Jenkins
* @author Pierre Jean
* @version 1.0
*/
public class Main {
Il faut être humble dans la constitution de la documentation. À mon avis, il vaut mieux produire la documentation progressivement en mettant les premiers éléments puis progressivement compléter cette documentation par ajout de détails.
L’étape suivante est l’ajout de la documentation d’une méthode basique.
/**
* Méthode pour afficher le double de ce nombre
* <p>
* Cette méthode sert pour tester l'intégration l'affichage d'un nombre.
* Ce nombre est calculé en appelant une méthode d'une classe Calcul
* qui retourne le double du nombre.
* <p>
* Cette méthode permet de réaliser un test unitaire avec Jenkins.
*
* @param nombre paramètre du nombre pour réaliser le doublement
* @return retourne le nombre affiché
*/
public int afficheDeuxFois(int nombre) {
System.out.println(Calcul.doublement(nombre));
return Calcul.doublement(nombre);
}
J’ai ajouté beaucoup d’explication sur une méthode très basique pour détailler la forme de cette documentation avec un seul paramètre et une valeur de retour.
Nous pouvons maintenant imaginer la génération de la documentation sous la forme de pages HTML via le Menu Project > Generate Javadoc …

Puis dans l’interface suivante, on indique sur quel projet (ou quels projets) on souhaite générer la Javadoc et le dossier de génération de cette documentation.

La génération de la documentation va fabriquer différents fichiers HTML dans le dossier doc visible dans Eclipse. On doit donc indiquer si on souhaite réécrire dans le dossier en remplaçant l’ancien contenu.

La fabrication du contenu est visible dans Eclipse dans le dossier doc indiqué dans les étapes précédentes. Il suffit ensuite d’ouvrir le fichier index.html via le menu « Open With » > « Web Browser » pour afficher la documentation finale.

Le rendu final de la documentation est alors affiché dans une forme standardisé réalisant les liens entre les différentes pages de la documentation.

La création de la documentation est simplifiée et standardisée facilement. Chaque langage de programmation dispose de sa propre version de Javadoc.
Publié dans Développement, IMT Mines Alès
Laisser un commentaire
Utilisation de Jenkins avec un simple projet Java en local
L’objectif est de tester l’outil d’intégration Jenkins de manière très simple. Du coup, j’ai choisi de ne pas utiliser d’outils de gestion de code sources de type git, svn ou autre, mais juste de lancer un simple test en automatique.
Une autre contrainte a été d’utiliser Jenkins dans un conteneur Docker qui est démarré simplement via cette commande :
docker run --name=jenkins -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk11
Le conteneur Jenkins est accessible via le navigateur sur l’URL http://127.0.0.1:8080/ avec les plugins recommandés.
Maintenant, on va fabriquer le code java basique qui ne fait que tester une fonction qui double un nombre passé en paramètre, voici le code :
public class Calcul {
public static int doublement(int nombre) {
return nombre * 2;
}
}
Et le test avec Junit 5
class CalculTest {
@Test
void testDoublement() {
assertEquals(Calcul.doublement(0) , 0);
assertEquals(Calcul.doublement(1) , 2);
}
}
Le test est vraiment basic juste pour vérifier le fonctionnement. Maintenant pour tester en ligne de commande en pur Java (qui est aussi utiliser avec Jenkins d’ailleurs ), on peut utiliser cette outil de Junit en ligne de commande.
Télécharger le fichier junit-platform-console-standalone-1.8.2.jar de Console Launcher : https://junit.org/junit5/docs/snapshot/user-guide/#running-tests-console-launcher qui permet d’appeler l’outil de test Junit5 via une ligne de commande.
En local on peut donc lancer cette commande, par exemple dans le workspace:
java -jar c:\DEV20\eclipse-workspace-jee\JenkinsDemo\junit-platform-console-standalone-1.8.2.jar -cp c:\DEV20\eclipse-workspace-jee\JenkinsDemo\bin --scan-classpath --disable-banner
Voici la sortie détaillée :
.
+-- JUnit Jupiter [OK]
| '-- CalculTest [OK]
| '-- testDoublement() [OK]
'-- JUnit Vintage [OK]
Test run finished after 44 ms
[ 3 containers found ]
[ 0 containers skipped ]
[ 3 containers started ]
[ 0 containers aborted ]
[ 3 containers successful ]
[ 0 containers failed ]
[ 1 tests found ]
[ 0 tests skipped ]
[ 1 tests started ]
[ 0 tests aborted ]
[ 1 tests successful ]
[ 0 tests failed ]
Ou la version avec erreur d’un test :
.
+-- JUnit Jupiter [OK]
| '-- CalculTest [OK]
| '-- testDoublement() [X] expected: <2> but was: <1>
'-- JUnit Vintage [OK]
Failures (1):
JUnit Jupiter:CalculTest:testDoublement()
MethodSource [className = 'test.CalculTest', methodName = 'testDoublement', methodParameterTypes = '']
=> org.opentest4j.AssertionFailedError: expected: <2> but was: <1>
org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:150)
org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:145)
org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:527)
test.CalculTest.testDoublement(CalculTest.java:14)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:568)
[...]
Test run finished after 47 ms
[ 3 containers found ]
[ 0 containers skipped ]
[ 3 containers started ]
[ 0 containers aborted ]
[ 3 containers successful ]
[ 0 containers failed ]
[ 1 tests found ]
[ 0 tests skipped ]
[ 1 tests started ]
[ 0 tests aborted ]
[ 0 tests successful ]
[ 1 tests failed ]
Pour disposer seulement de cette réponse en cas d’erreur, il faut ajouter le paramètre « –details=none » qui n’affichera qu’en cas d’erreur.
À présent, on peut copier tout le dossier du projet dans le conteneur Jenkins, car il n’a pas accès au dossier c:\DEV20\eclipse-workspace-jee\JenkinsDemo\ mais on aurait pu monter dans le conteneur Jenkins le dossier.
docker cp C:\DEV20\eclipse-workspace-jee\JenkinsDemo jenkins:/home
Donc l’ensemble des fichiers du projet et l’outil junit-platform-console-standalone-1.8.2.jar de Console Launcher se trouve dans le dossier /home/JenkinsDemo. On peut donc ensuite tester dans le conteneur comme ceci.
docker exec --user=root --workdir=/home/JenkinsDemo/ -it jenkins /bin/bash
On peut donc ensuite tester notre test dans le conteneur :
java -jar /home/JenkinsDemo/junit-platform-console-standalone-1.8.2.jar -cp /home/JenkinsDemo/bin/ --scan-classpath --disable-banner --deta
ils=none
Passons maintenant dans Jenkins pour créer un job, « Construire un projet free-style » puis il faut utiliser le bouton « Avancé » pour avoir accès au dossier :

Puis, il faut indiquer le dossier de travail :

Maintenant, on va ajouter notre script comme critère de Build :

La commande testée précédemment doit être entrée pour valider le projet:

java -jar /home/JenkinsDemo/junit-platform-console-standalone-1.8.2.jar -cp /home/JenkinsDemo/bin/ --scan-classpath --disable-banner --details=none
On peut ensuite sauvegarder les modifications et lancer ce job via « Lancer ce build » et on peut vérifier l’exécution dans le résultat de la console :

Cela permet de vérifier que les opérations s’exécutent correctement. A l’inverse voici une sortie de console en erreur après un échec du test :

Pour conclure et simplifié, on aurait pu monter le dossier du projet Eclipse directement dans le /home du conteneur avec cette commande :
docker run -it -v C:\DEV20\eclipse-workspace-jee\JenkinsDemo\:/home/JenkinsDemo/ --name=jenkins -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk11
Le reste serait identique et grâce à Java portable entre Windows et Linux du conteneur, les commandes avec JUnit sont compatibles.
Publié dans Développement, IMT Mines Alès
Laisser un commentaire
Ajout d’un dossier de contenu statique à Tomcat 9
Cas pratique, un programme Tomcat doit produire un fichier de données à télécharger, par exemple un fichier backup.csv.
Produire ce dossier dans le dossier WebContent ou webapp n’est pas possible, car à chaque redémarrage d’une nouvelle version de notre application, le contenu d’un de ces dossiers serait régénéré.
La solution vient d’un dossier de contenu dit statique (static en VO), en modifiant le fichier server.xml de notre serveur Tomcat. On identifie le projet qui doit disposer d’un dossier statique (dans l’exemple, c’est le tag <Context> du projet DevWeb) et on peut y ajouter les instructions pour indiquer à Tomcat qu’un URL peut accéder à ce dossier.

Il faut changer le tag <Context/> en tag double <Context></Context> et y ajouter ces informations de ressources. (Les doubles slashs sont à adapter au type de système d’exploitation).
<Context docBase="DevWeb" path="/DevWeb" reloadable="true" source="org.eclipse.jst.jee.server:DevWeb"> <Resources> <PreResources base="C://Users//pierre.jean//Site-Web//data" className="org.apache.catalina.webresources.DirResourceSet" webAppMount="/static" /> </Resources> </Context>
L’URL pour accéder à la ressource est relative à l’URL du <Context> englobant, notre url est donc http://127.0.0.1:8080/DevWeb/static/backup.csv
Pour lister le contenu du dossier, la première solution est de modifier le fonctionnement général de Tomcat en modifiant le fichier web.xml. Il faut changer la valeur de la servlet par défaut gérant la liste des dossiers en passant à la valeur true la propriété listings comme indiqué ci-dessous.
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
La seconde option est de créer dans le dossier WebContent/WEB-INF/ un fichier tomcat-web.xml (ou web.xml mais Tomcat ne le conseille pas pour éviter de déployer ce fichier spécifique dans un serveur autre que Tomcat).
Le contenu du fichier tomcat-web.xml est donc le suivant pour surcharger les réglages par défaut du fichier web.xml généraliste au niveau du serveur Tomcat:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>default</servlet-name> <servlet-class> org.apache.catalina.servlets.DefaultServlet </servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Après, il n’est pas forcément recommandé en production de donner des accès à un dossier tout entier, mais dans le contexte du projet de recherche, Tomcat est prévu dans un container en local de la machine.
On peut aussi modifier le rendu par défaut de la liste des contenus d’un dossier dans TOmcat mais je vous renvoie sur la documentation, ce n’est pas un besoin que j’ai eu.

Publié dans Développement
Laisser un commentaire
Émission d’un email en Java via un hébergement OVH
Envoyer un email technique depuis un code Java via un compte configuré chez OVH est assez simple si on a trouvé la bonne combinaison de paramètres…
Voici la liste des réglages pour un compte que l’on va appeler publication@euromov.eu et dont le mot de passe a été généré par la console OVH. Attention, l’envoie d’un trop grand nombre d’emails entrainera le blocage de votre compte par OVH. L’entreprise surveille ce genre de fonctionnalité car régulièrement les sites web et autres serveurs de l’entreprise servent à des pirates pour envoyer des emails en masse souvent à l’insu du propriétaire du compte chez OVH.
Le réglage mail.debug est à mettre à true au besoin pour voir les messages d’échange entre le serveur et votre code Java:
Properties prop = new Properties();
prop.put("mail.debug", "false");
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.ssl.protocols", "TLSv1.2");
prop.put("mail.smtp.host", "ssl0.ovh.net");
prop.put("mail.smtp.starttls.enable", "true");
prop.put("mail.smtp.ssl.trust", "ssl0.ovh.net");
prop.put("mail.smtp.port", "587");
prop.put("mail.smtp.socketFactory.port", "587");
prop.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory"); Session session = Session.getInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("publication@euromov.eu", "MOT_DE_PASSE_A_GENERER_DANS_CONSOLE_OVH");}
});
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("publication@euromov.eu"));
message.setRecipients(
Message.RecipientType.TO, InternetAddress.parse("directeurs@toto.com"));
message.setSubject("Mail Subject");
String msg = "This is my first email using JavaMailer";
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(msg, "text/html; charset=utf-8");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
message.setContent(multipart);
Transport.send(message);
Pour rappel 2 JARS sont nécessaires pour ce code :
- javax.mail.jar depuis https://github.com/javaee/javamail/releases
- activation.jar depuis https://mvnrepository.com/artifact/javax.activation/activation/1.1.1
Bon email, mais encore une fois attention aux spams.
Publié dans Développement
Laisser un commentaire
Langage R liaison base de données
Installation de WAMP : https://www.wampserver.com/ ou MAMP : https://www.mamp.info/en/downloads/
Supposons un accès à un fichier « sante.accdb » contenant une table data de cette nature :
id date_analyse glycemie
1 2022-03-17 10
2 2022-03-18 20
On peut interroger en langage R en SQL vers Microsoft Accces.
En premier lieu il faut installer le module pour R pour accéder à Accces:
install.packages("RODBC")
library(RODBC)
Une fois l’installation réalisée de ce module, on peut ouvrir le fichier Accès et intérroger en SQL la base de données:
con <- odbcConnectExcel2007("C:/Users/utilisateur/Documents/sante.accdb")
resultat <- sqlQuery(con,"select date_analyse from data")
print( resultat )
On peut faire de manière similaire sur MySQL avec des commandes similaires, en premier lieu en installant le module pour la liaison avec le serveur de base de données MySQL :
install.packages("RMySQL")
library(RMySQL)
L’accès à un serveur de base de données Mysql suppose plusieurs informations techniques, l’adresse du serveur de base de données (ici 127.0.0.1), un compte sur cette base de données (ici root), un mot de passe correspondant à ce compte (ici « » pour indiquer mot de passe vide), un port de base de données (ici et par défaut 3306) et enfin une base de données (ici sante)
DB <- dbConnect(MySQL(), user="root", host="127.0.0.1", password="",dbname="sante" , port=3306)
Une fois la connexion réalisée, on peut lister les tables dans cette base de données sante.
dbListTables(DB)
Et enfin poser des questions en SQL
resultat <- dbGetQuery(DB, "SELECT * FROM data")
print( resultat )
Test unitaire en R
Installation de l’outil de test
install.packages("testthat") library(testthat)
Test d’une valeur égale via :
expect_equal( 95 , dbGetQuery(DB, "SELECT max(age) from import")[,1] )
Pas de réponse si tout va bien, mais si on test ceci :
expect_equal( 92 , dbGetQuery(DB, "SELECT max(age) from import")[,1] ) Error: 92 not equal to dbGetQuery(DB, "SELECT max(age) from import")[, 1]. 1/1 mismatches [1] 92 - 95 == -3
Publié dans Développement
Laisser un commentaire
Génération d’un PDF depuis une JSP avec iText5 et iText7
NOTA : la version utilisée dans cette première version est la iText5 une prochaine version utilisera la nouvelle version iText7
En premier lieu il faut récupérer les bibliothèques jar suivantes:
- itextpdf-5.5.13.3.jar
- log4j-1.2.16.jar
- slf4j-api-1.7.9.jar
- slf4j-log4j12-1.7.13.jar
Placer ces fichiers dans le dossier WebContent/WEB-INF/lib de votre application Dynamic Web Application , les sélectionner et faire click droit > Build Path > Add to Build Path

Vous pouvez maintenant coder une simple JSP pour générer un ficheir PDF. Attention, si vous cette erreur « getOutputStream() has already been called for this response » il faut retirer tout espace ou retour chariot qui pourrait être interprétés par la JSP comme du HTML à envoyer donc tout se trouve sur une seule ligne pour les tag JSP de type <%@page import %>:
<%@ page language="java" contentType="application/pdf; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%><%@page import="com.itextpdf.text.Document" %><%@page import="com.itextpdf.text.PageSize" %><%@page import="com.itextpdf.text.Paragraph" %><%@page import="com.itextpdf.text.pdf.PdfWriter" %><%
Document document = new Document(PageSize.A4, 36, 36, 36, 72);
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=\"todo.pdf\"");
document.open();
document.add( new Paragraph ("Hello world"));
document.add( new Paragraph ("Bonjour le monde"));
document.close();
writer.close();
%>
Version iText7
Pour la version iText7, après avoir ajouté les bilbiothèques suivantes en remplacement de celles de iText5:
- barcodes-7.2.1.jar
- commons-7.2.1.jar
- font-asian-7.2.1.jar
- forms-7.2.1.jar
- hyph-7.2.1.jar
- io-7.2.1.jar
- kernel-7.2.1.jar
- layout-7.2.1.jar
- log4j-1.2.16.jar
- pdfa-7.2.1.jar
- pdftest-7.2.1.jar
- sign-7.2.1.jar
- slf4j-api-1.7.9.jar
- slf4j-log4j12-1.7.13.jar
- styled-xml-parser-7.2.1.jar
- svg-7.2.1.jar
Du coup le code pour la JSP est similaire avec l’utilisation d’un ByteArrayOutputStream pour gérer le PDF en mémoire.
<%@ page language="java" contentType="application/pdf; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><%@ page import="com.itextpdf.io.source.ByteArrayOutputStream" %><%@ page import="com.itextpdf.kernel.pdf.PdfDocument" %><%@ page import="com.itextpdf.kernel.pdf.PdfWriter" %><%@ page import="com.itextpdf.layout.Document" %><%@ page import="com.itextpdf.layout.element.Paragraph" %><%
ByteArrayOutputStream memory = new ByteArrayOutputStream();
Document document = new Document(new PdfDocument(new PdfWriter(memory)));
document.add( new Paragraph ("Hello world"));
document.close();
ServletOutputStream servletOutputStream = response.getOutputStream();
servletOutputStream.write(memory.toByteArray());
servletOutputStream.flush();
servletOutputStream.close();
%>
Publié dans Développement
Laisser un commentaire
Alternative tcpdump windows 10 avec pktmon
L’outil pktmon.exe disponible par défaut dans Windows 10 Pro permet de faire un peu de dump de paquet TCP.
Bien sûr, la solution de npcap/winpcap/wireshark est beaucoup plus performant, mais avec quelques commandes on peut extraire l’information utile. Je me concentre surtout sur la partie HTTP qui me permet de vérifier les échanges de données même si la limitation de pktmon à ne pas pouvoir fonctionner sur la boucle locale 127.0.0.1 est clairement une limitation pour moi.
Démarrons par ajouter un filtre sur le protocole TCP sur le port 80
C:\Windows\system32\pktmon.exe filter add -t TCP -p 80
On peut lister ces filtres avec la commande suivante
C:\Windows\system32\pktmon.exe filter list
Filtres de paquet :
# Nom Protocole Port
- --- --------- ----
1 <vide> TCP 80
Et pour démarrer la capture, on voit le rappel de la liste des paquets
C:\Windows\system32\pktmon.exe start --etw --pkt-size 0
Filtres de paquet :
# Nom Protocole Port
- --- --------- ----
1 <vide> TCP 80
Un fichier PktMon.etl va donc être fabriqué contenant les opérations que l’on fait avec son navigateur vers un port 80 d’un serveur web par exemple.
Mais je vous propose cette version du filtrage pour se concentrer sur la partie Web des requêtes :
C:\Windows\system32\pktmon.exe filter add Port80 -t TCP PSH -p 80 -m 00-AA-BB-CC-DD-EE
On ajoute un nom Port80 et on va récupérer que les paquets marqués TCP de type PUSH (codé PSH) sur le port 80 en provenance de la Mac Address de ma carte réseau 00-AA-BB-CC-DD-EE à remplacer par votre valeur.
Il suffit maintenant d’arrêter la capture est de convertir le fichier PktMon.etl en format lisible à moins d’utiliser l’outil d’analyse de Microsoft Network Monitor.
Le fichier ftp.txt est assez clair pour être lu et vérifier les packets TCP
C:\Windows\system32\pktmon.exe stop
C:\Windows\system32\pktmon.exe format PktMon.etl -o file.txt
Exemple d’accès sur un site web en méthode GET en regardant le contenu du fichier file.txt :
00-AA-BB-CC-DD-EE > 00-11-12-13-14-15, ethertype IPv4 (0x0800), length 457: 192.168.1.1.49676 > 213.186.33.2.80: Flags [P.], seq 2764848503:2764848906, ack 3028623659, win 513, length 403: HTTP: GET /accueil/?s=test HTTP/1.1
On peut retirer le filtre au besoin pour revenir dans l’état initial
C:\Windows\system32\pktmon.exe filter remove
On peut aussi exporter dans un format plus verbeux avec l’option de formatage etl2txt:
C:\Windows\system32\pktmon.exe etl2txt .\PktMon.etl v 3 -m -o file.txt
Cela va produire les entête HTTP des contenus des requêtes HTTP par exemple avec le fichier JavaScript suivant :
HTTP/1.1 200 OK
date: Wed, 23 Feb 2022 15:11:35 GMT
content-type: application/javascript
content-length: 229
server: Apache
last-modified: Tue, 10 Dec 2019 18:53:39 GMT
accept-ranges: bytes
cache-control: max-age=900
expires: Wed, 23 Feb 2022 15:26:35 GMT
vary: Accept-Encoding
x-iplb-request-id: C1339D28:28B3_D5BA2102:0050_62164EA7_6F6E:1CD33
x-iplb-instance: 29005
var $j = jQuery.noConflict();
$j(document).ready(function() {
// Toggle Single Bibtex entry
$j('a.papercite_toggle').click(function() {
$j( "#" + $j(this).attr("id") + "_block" ).toggle();
return false;
});
});
Ensuite on pourra utiliser les outils de développements des navigateurs pour une lecture plus simple, mais la liaison TPC/IP sur le contenu est clairement lisible avec cet outil fourni par défaut.
L’option suivante est soit de faire plus de réseau avec tcpdump ou wireshark qui sont dédiés aux couches réseaux soit de partir en développement web avec les outils embarqués dans les navigateurs Web.
La partie que je chercherai à ajouter prochainement, est la capture de la boucle locale via des outils tierce comme indiqué sur cette page : https://wiki.wireshark.org/CaptureSetup/Loopback
Je pense que cette option semble prometteuse même si je n’arrive pas encore à la faire fonctionner : https://web.archive.org/web/20150726062624/http://ig2600.blogspot.com/2011/03/powershell-script-to-enable-windows-to.html
Publié dans Développement
Laisser un commentaire
Ajout de l’authentification One-Time-Password à taiga.io
La nouvelle version de taiga.io avec docker inclus un installateur bien simplifié.
Il me parait utile d’y ajouter simplement l’authentification OTP qui permet d’accepter le mot de passe ajouté avec 6 chiffres calculé par l’horloge à partir d’un code. Vous trouverez des explications sur ce processus dans cet article: https://en.wikipedia.org/wiki/One-time_password
Le seul fichier à éditer pour inclure l’OTP dans taiga est le fichier /taiga-back/taiga/users/services.py dans le containeur taiga-docker_taiga-back_1.
En premier lieu, il faut ajouter au containeur taiga-docker_taiga-back_1 le module pyotp:
docker exec -it taiga-docker_taiga-back_1 pip install pyotp
Ensuite on peut copier sur la machine hôte le fichier services.py pour y ajouter l’OTP:
docker cp taiga-docker_taiga-back_1:/taiga-back/taiga/users/services.py services.py
Nous pouvons donc éditer le fichier services.py pour y adjoindre et modifier le programme, en premier lieu en important le module pyotp avant toutes les fonctions:
import pyotp
Puis on va chercher la fonction get_and_validate_user qui a cette forme:
def get_and_validate_user(*, username: str, password: str) -> bool: """ Check if user with username/email exists and specified password matchs well with existing user password. if user is valid, user is returned else, corresponding exception is raised. """ user = get_user_by_username_or_email(username) if not user.check_password(password) or not user.is_active or user.is_system: raise exc.WrongArguments(_("Username or password does not matches user.")) return user
Nous allons ajouter l’extraction des 6 derniers symboles du mot de passe pour trouver le code PIN à valider par OTP avec le code fourni en paramètre. Donc la nouvelle version de la fonction get_and_validate_user
def get_and_validate_user(*, username: str, password: str) -> bool: """ Check if user with username/email exists and specified password matchs well with existing user password. if user is valid, user is returned else, corresponding exception is raised. """ user = get_user_by_username_or_email(username) """ PJE verification OTP """ totp = pyotp.TOTP("base32secret3232") passwordPIN = password password = passwordPIN[:-6] pin = totp.verify( passwordPIN[-6:] , valid_window=2 ) if pin is False: raise exc.WrongArguments(_("Username or password does not matches user PIN.")) """ / PJE verification OTP """ if not user.check_password(password) or not user.is_active or user.is_system: raise exc.WrongArguments(_("Username or password does not matches user.")) return user
En incluant dans la fonction d’authentification, l’extraction des 6 derniers symboles fournis par l’utilisateur, on peut ajouter une authentification avec code OTP. On note une nouvelle exception envoyé par le serveur en cas d’erreur sur le code PIN.
NOTA: je pensais avoir un problème de Timezone dans le containeur mais au final, je pense que c’est valide comme installation. J’ai testé quelques solutions de changement dans le containeur de timezone mais finalement je pense que je peux aussi m’appuyer sur l’argument for_time de la fonction verify : https://pyauth.github.io/pyotp/_modules/pyotp/totp.html#TOTP.verify
Publié dans Développement
Laisser un commentaire
Génération des classes Java Entity depuis un fichier JDL
Je trouve très pratique pour définir les entités l’outil en ligne de Jhipster JDL-Studio.
Prenons une application avec plusieurs liaisons OneToMany d’une liste de recette dont chaque recette a une liste de commentaires et une liste d’ingrédients.

À partir du fichier jhipster-jdl.jdl téléchargé depuis le JDL Studio, je souhaite fabriquer les entités en Java pour les intégrer dans un développement.
Je n’ai pas trouvé toutes les options d’automatisation, mais en ligne de commande après avoir installé Jhipster, on peut lancer les 2 lignes suivantes dans un dossier contenant le fichier jhipster-jdl.jdl.
La première permet de fabriquer le projet en répondant à 8 questions par validation automatique.
jhipster --skip-cache --skip-git --skip-install --skip-prompts --skip-client --skip-user-management --db sql --skip-checks --skip-fake-data --base-name App --application-type microservices --skip-checks
Les questions seront validées par la touche « entrée » automatiquement :
? What is your default Java package name? com.mycompany.myapp ? Which *type* of database would you like to use? SQL (H2, PostgreSQL, MySQL, MariaDB, Oracle, MSSQL) ? Which *production* database would you like to use? PostgreSQL ? Which *development* database would you like to use? H2 with disk-based persistence ? Which cache do you want to use? (Spring cache abstraction) Ehcache (local cache, for a single node) ? Do you want to use Hibernate 2nd level cache? Yes ? Would you like to use Maven or Gradle for building the backend? Maven ? Which other technologies would you like to use?
La seconde commande va fabriquer les entités en Java depuis le fichier jhipster-jdl.jdl :
jhipster jdl jhipster-jdl.jdl --skip-client
Repondez-yes aux 2 questions d’overwrite sans inquiétudes, nous n’allons pas exploiter d’autres fonctions que la génération des entités.
Vous trouverez dans le dossier src/main/java/com/mycompany/myapp/domain/ les fichiers java des entités avec les liaisons réalisées et les propriétés créées.
Il s’agit d’une utilisation d’une toute petite fonctionnalité de Jhipster mais je trouve cela très pratique.
Publié dans Développement
Laisser un commentaire