Pouvons nous par nous même intégrer des librairies java tierces ou elle doivent êtres dans le socle applicatif ?
Dans notre cas, nous avons besoin d’utiliser le sdk AWS pour faire appel à des mécanismes de cryptage.
L’ajout de JARs n’est jamais “plug and play” car il peut potentiellement y avoir des conflits avec d’autres JARs déjà embarqués dans la plateforme, et donc avoir des effets de bord imprévisibles. C’est pour cela qu’on préfère regarder d’abord de quoi il retourne précisément.
En l’occurrence l’ajout de cette dépendance ne semble pas ajouter trop de choses ni induire de conflits, voilà l’écart vs les dépendances de la plateforme dans sa version de dev courante (5.3-alpha):
Cette lib pourrait donc être éligible à être intégrée à terme à la plateforme (car elle est sous licence Apache 2.0).
Je regarderai plus tard ce que ça donne sur la 5.2-beta et sur la 5.1 mais on évite des les intégrations de nouvelles libs ailleurs que sur la version de dev courante.
En tout état de cause, il existe 2 manières d’ajouter manuellement les libs:
soit au niveau du paramétrage par ajout de “shared codes” de type “JAR” (c’est le plus souple quand il n’y a pas 50 dépendances indirectes)
soit au niveau de l’image Docker en buildant une image enrichie à partir de la notre:
FROM simplicite:platform:<tag>
ADD --chown=simplicite:simplicite *.jar /usr/local/tomcat/webapps/ROOT/WEB-INF/lib
Attention de ne bien ajouter que les libs additionnelles et de proscrire absolument les JARs “bundle” qui embarquent plusieurs JAR fusionnés dans un seul JAR car il y a alors 99% de chances que ça embarque des classes en conflit.
Bon, en 5.1 ce sont aussi les même 2 libs qu’ajoute la dépendance
Analyse faite, on va les intégrer au socle, y compris en 5.1 pour vous simplifier les choses car :
on a déjà la lib bcprov, or si j’en crois bouncycastle.org la bcprov-ext contient tout ce qu’il y a dans bcprov plus un algo additionnel (NTRU). On va donc remplacer la bcprov par la bcprov-ext (en passant de 0.68 à 0.69)
il ne reste alors que la lib aws-encryption-sdk-java qui ne contient rien d’autre que des classes en com.amazonws.* donc ça ne peut pas poser de pb de l’ajouter
Ce sera fait dans le cadre de la prochaine révision 5.1.35 qui devrait arriver rapidement pour d’autres sujets.
En attendant (si vous n’utilisez pas l’algo NTRU)je pense vous pouvez juste ajouter manuellement le JAR aws-encryption-sdk-java-2.3.3.jar (cf. ma réponse précédente) ça devrait marcher avec la bcprov déjà présente mais il faudra de toute façon la supprimer quand vous upgraderez en 5.1.35.
La 5.1.35 avec la lib en question a été releasée le 19/03/22, quand vous upgraderez sur cette révision, n’oubliez pas de supprimer l’ajout spécifique de cette lib au risque de vous retrouver tôt ou tard avec des conflits de version car on maintiendra cette lib à jour.
Je teste aujourd’hui l’utilisation de KMS mais cela ne fonctionne pas à priori. Je n’ai pas essayé d’intégrer de lib à la main et je n’en ai pas la possibilité.
java.lang.NoClassDefFoundError: com/amazonaws/auth/AWSCredentialsProvider
at com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider.builder(KmsMasterKeyProvider.java:371)
at com.simplicite.commons.name.NamHealthcareDataTools.kmsEncrypt(NamHealthcareDataTools.java:73)
at com.simplicite.commons.name.NamHealthcareDataTools.encrypt(NamHealthcareDataTools.java:65)
at com.simplicite.objects.name.NamJeune.encryptHealthData(NamJeune.java:1175)
at com.simplicite.objects.name.NamJeune.preSave(NamJeune.java:810)
at com.simplicite.util.ObjectHooks.preSave(ObjectHooks.java:664)
at com.simplicite.util.engine.ObjectManager.save(ObjectManager.java:3327)
at com.simplicite.util.engine.ObjectDirect.save(ObjectDirect.java:478)
at com.simplicite.util.ObjectDB.save(ObjectDB.java:1315)
at com.simplicite.webapp.tools.JSONServletTool.update(JSONServletTool.java:1224)
at com.simplicite.webapp.ObjectJson.update(ObjectJson.java:343)
at com.simplicite.webapp.tools.JSONServletTool.businessObjectService(JSONServletTool.java:626)
at com.simplicite.webapp.servlets.AbstractJSONServlet.service(AbstractJSONServlet.java:89)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.simplicite.webapp.filters.HTTPHeadersFilter.doFilter(HTTPHeadersFilter.java:39)
at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.simplicite.webapp.filters.AuthMethodFilter.doFilter(AuthMethodFilter.java:174)
at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.simplicite.webapp.filters.RewriteFilter.doFilter(RewriteFilter.java:86)
at com.simplicite.webapp.filters.AbstractFilter.doFilter(AbstractFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:183)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at com.simplicite.tomcat.valves.APISessionValve.invoke(APISessionValve.java:231)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ClassNotFoundException: com.amazonaws.auth.AWSCredentialsProvider
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1407)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1215)
… 49 more
Nous n’avons pas intégré sa dépendance optionnelleaws-java-sdk : https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk/1.12.54 car celle-ci tire des centaines de libs AWS qui, de part leur volume et leur caractère propriétaire, n’ont pas vocation à faire partie de la plateforme Simplicité.
Votre classe manquante doit être dans une de ces libs.
Une bonne approche est donc d’identifier les libs nécessaires et suffisantes dans votre cas d’usage précis puis de les ajouter comme décrit plus haut:
soit en construisant une image Docker custom en partant de la notre,
soit, s’il n’y en a pas des dizaines/centaines, en les ajoutant en shared code de type JAR
Ici aussi indiquez nous la liste de ces libs pour qu’on s’assure qu’elles n’induisent pas de conflits, faute de quoi il peut y avoir de effets de bord imprévisibles.
Vous pouvez aussi raisonner différemment pour éviter tout conflit de dépendances :
ajouter à nos images une webapp indépendante de la webapp Simplicité en charge du cryptage/décryptage via appel de services ad hoc,
packager un JAR de type “module Java” qui isole les dépendances et expose des méthodes de cryptage/décryptage et l’ajouter dans l’image ou en shared code de type JAR
etc.
Cela dit, la classe helper EncryptionTool (cf. EncryptionTool) offre nativement des mécanismes de cryptage/décryptage certes plus simples mais qui évitent des travaux d’intégrateur plus complexes
Du coup je m’interroge sur l’intérêt de conserver la lib aws-encryption-sdk-java dans la plateforme sachant que celle-ci est un wrapper des libs Bouncy Castle et ne peut visiblement pas, dans la “vraie vie”, être utilisé sans tout sa grappe d’autres libs AWS “optionnelles”
Si vous n’y voyez pas d’inconvénient je propose de la retirer dans la prochaine révision.
Pour info, nous réfléchissons actuellement à un processus plus simple pour le check et l’ajout de dépendances complexes dans le cadre de build d’images customs car c’est clairement de ça qu’on parle dans ce contexte (la notion paramétrable de shared code de type JAR n’a de sens que pour les cas simples où on ne parle que d’un - ou de qques - JAR qu’on a checké préalablement vs le POM effectif de la plateforme qui, pour mémoire, disponible sur le /maven de l’instance, ce n’est pas un mécanisme adapté pour de l’ajout de dépendances). Cela reposera sans doute sur une image Docker plus riche/spécifique qui embarquera notamment Maven.
Effectivement la solution avec un docker qui embarque maven serait bien pratique.
Aussi, peut-on laisser la dépendance aws-encryption ? Le jar n’est pas en ligne contrairement à aws-sdk que j’ai pu ajouter directement a notre dockerfile.
Nous avons supprimé la lib car ça n’a pas de sens de conserver dans la plateforme une lib inutilisable sans le SDK complet. Celle -ci est tout autant disponible en ligne sur le registry Maven central que le SDK:
Et quelle est la procédure pour récupérer le jar depuis maven dans le dockerfile ? J’ai pas de lien aws pour telecharger le jar aws-encryption directement contrairement à la dépendance que je viens d’intégrer de cette manière.
D’autre par, aws-encryption peut fonctionner sans le SDK complet sauf pour la fonctionalité KMS (je cherche aussi la logique aussi d’avoir inégrer KMS là dedans si le SDK est nécessaire alors qu’elle nest pas en dépendance)
Nous travaillons actuellement à la conception/implémentation de la procédure d’ajout de dépendances “assistée” par Maven dans le cadre de build d’une image custom. Ce sera documenté d’ici peu le temps de finaliser et de roder tout ça.
D’ici là la recopie de vos JAR additionnels peut se faire par des ADD explicites comme décrit plus haut.
bonjour et merci !
J’ai fait le modifications nécéssaires dans le dockerfile et dans la construction de l’image.
Une question
adddeps.sh est bien un script sur votre image ?
Présicions:
J’ai du ajouter l’option pipefail au début pour respecter le lint.
J’ai mis le user root au début car il me mettait des permission denied sur des créations de repertoitre ?!
Et j’ai mis le user simplicite a la fin car hadolint bloque le build si on laisse root a la fin du dockerfile