{"id":1068,"date":"2020-05-06T14:59:41","date_gmt":"2020-05-06T12:59:41","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/?p=1068"},"modified":"2020-05-06T18:53:02","modified_gmt":"2020-05-06T16:53:02","slug":"j-ai-teste-java-google-cloud-functions-aplha","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/j-ai-teste-java-google-cloud-functions-aplha\/","title":{"rendered":"J&rsquo;ai test\u00e9 Java Google Cloud Functions Alpha"},"content":{"rendered":"<p>J&rsquo;ai test\u00e9 les Java Google Cloud Functions en Alpha.<\/p>\n<p>Jusqu&rsquo;ici, les Cloud Functions de Google n&rsquo;\u00e9taient impl\u00e9mentables qu&rsquo;en NodeJs, Go ou Python. Mais Google est en train de pr\u00e9parer l&rsquo;ouverture d&rsquo;un runtime Java (8 et 11), que j&rsquo;ai pu tester en alpha release priv\u00e9e (pour s&rsquo;inscrire, c&rsquo;est <a href=\"https:\/\/docs.google.com\/forms\/d\/e\/1FAIpQLScC98jGi7CfG0n3UYlj7Xad8XScvZC8-BBOg7Pk3uSZx_2cdQ\/viewform\" rel=\"noopener noreferrer\" target=\"_blank\">ici<\/a>). Apr\u00e8s inscription \u00e0 l&rsquo;alpha priv\u00e9e, vous aurez acc\u00e8s \u00e0 un document de tutoriel pas \u00e0 pas, et \u00e0 un forum d&rsquo;aide en ligne.<\/p>\n<p>On peut \u00e9crire deux types de fonctions : les fonctions HTTP et les fonctions \u00ab\u00a0t\u00e2che de fond\u00a0\u00bb ou background (pour r\u00e9agir \u00e0 un \u00e9v\u00e9nement Pub\/Sub ou Cloud Storage par exemple). Ici je vais vous pr\u00e9senter uniquement les fonctions HTTP.<\/p>\n<p>En pr\u00e9-requis, il faut installer le <a href=\"https:\/\/cloud.google.com\/sdk\/install\" rel=\"noopener noreferrer\" target=\"_blank\">SDK Google Cloud<\/a> qui comprend la ligne de commande <code>gcloud<\/code>, puis s&rsquo;authentifier \u00e0 Google Cloud et installer les composants alpha :<\/p>\n<pre>\ngcloud auth login\ngcloud components install alpha\n<\/pre>\n<p>Une fois ceci fait, vous voici pr\u00eat pour votre premi\u00e8re fonction en Java !<\/p>\n<h2>Hello Google Function in Java<\/h2>\n<p>Un projet Cloud Function en Java est un projet Maven (ou Gradle) classique qui contient la librairie <code>com.google.cloud.functions:functions-framework-api<\/code>.<\/p>\n<p>Voici ce qu&rsquo;il faut mettre dans votre <code>pom.xml<\/code>.<\/p>\n<pre>\n   \n    com.google.cloud.functions\n     functions-framework-api\n     1.0.0-alpha-2-rc3\n     provided\n   \n<\/pre>\n<p>Nous allons ensuite cr\u00e9er notre premi\u00e8re fonction, celle-ci est une simple classe qui impl\u00e9mente l&rsquo;interface <code>com.google.cloud.functions.HttpFunction<\/code>, cette interface contient une m\u00e9thode <code>service<\/code> qui nous permet d&rsquo;acc\u00e9der \u00e0 un objet <code>HttpRequest<\/code> et un objet <code>HttpResponse<\/code>. Nous allons utiliser le <code>writer<\/code> de le l&rsquo;objet <code>response<\/code> pour \u00e9crire le traditionnel <em>Hello World!<\/em>.<\/p>\n<p>Voici ce que \u00e7a donne, rien de compliqu\u00e9. Pour plus de facilit\u00e9 j&rsquo;ai mis cette classe dans le package par d\u00e9faut, mais libre \u00e0 vous de la placer o\u00f9 bon vous semble.<\/p>\n<pre>\nimport com.google.cloud.functions.HttpFunction;\nimport com.google.cloud.functions.HttpRequest;\nimport com.google.cloud.functions.HttpResponse;\nimport java.io.BufferedWriter;\nimport java.io.IOException;\n\npublic class Example implements HttpFunction {\n    @Override\n    public void service(HttpRequest request, HttpResponse response)\n            throws IOException {\n        var writer = response.getWriter();\n        writer.write(\"Hello world!\");\n    }\n}\n<\/pre>\n<p>Nous allons ensuite d\u00e9ployer notre fonction. Comme celle-ci est une simple classe sans d\u00e9pendance, on peut directement la d\u00e9ployer sans n\u00e9cessit\u00e9 de packaging pr\u00e9alable via Maven.<\/p>\n<p>Le d\u00e9ploiement se fait, \u00e0 la racine du projet, via la commande suivante :<\/p>\n<pre>\ngcloud alpha functions deploy helloworld --entry-point Example --runtime java11  \\\n        --trigger-http\n<\/pre>\n<p>Cette ligne de commande va d\u00e9ployer une fonction HTTP nomm\u00e9e <strong>helloworld<\/strong>, en utilisant le runtime <strong>java11<\/strong>, dans le projet GCP en cours, et utilisant le point d&rsquo;entr\u00e9e <code>Example<\/code> qui est notre fonction pr\u00e9c\u00e9demment cr\u00e9\u00e9e.<\/p>\n<p>La commande prend pas mal de temps \u00e0 s&rsquo;ex\u00e9cuter, voici son r\u00e9sultat :<\/p>\n<pre>\nDeploying function (may take a while - up to 2 minutes)...done.                                                                                                                                            \navailableMemoryMb: 256\nentryPoint: Example\nhttpsTrigger:\n  url: https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/helloworld\ningressSettings: ALLOW_ALL\nlabels:\n  deployment-tool: cli-gcloud\nname: projects\/methodical-mesh-238712\/locations\/us-central1\/functions\/helloworld\nruntime: java11\nserviceAccountEmail: ...\nsourceUploadUrl: ...\nGoogleAccessId=...\nstatus: ACTIVE\ntimeout: 60s\nupdateTime: '2020-05-06T08:50:23.833Z'\nversionId: '2'\n<\/pre>\n<p>Pour appeler notre fonction, il faut utiliser la valeur de <code>httpsTrigger.url<\/code>, ici <code>&lt;a href=&quot;https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/helloworld&quot;&gt;https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/helloworld&lt;\/a&gt;<\/code><\/p>\n<pre>\ncurl https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/helloworld\n&gt; Hello world!\n<\/pre>\n<p>Et voil\u00e0, notre premi\u00e8re fonction ! Facile non ?<\/p>\n<h2>Un exemple un peu plus complexe<\/h2>\n<p>Bon, une fonction sans librairie c&rsquo;est pas super pratique, surtout si on veut r\u00e9aliser un endpoint REST. A minima il nous faudrait une librairie JSON.<\/p>\n<p>Essayons donc un exemple plus complexe. Comme pr\u00e9c\u00e9demment, nous allons cr\u00e9er un projet Maven standard avec la d\u00e9pendance <code>com.google.cloud.functions:functions-framework-api<\/code>.<\/p>\n<p>Puis, on va ajouter la librairie Gson pour pouvoir g\u00e9rer de la repr\u00e9sentation JSON :<\/p>\n<pre>\n   \n       com.google.code.gson\n       gson\n       2.8.5\n   \n<\/pre>\n<p>Ensuite, on va cr\u00e9er une fonction <code>FruitRestFunction<\/code> qui va impl\u00e9menter un POST pour cr\u00e9er un Fruit, et un GET pour r\u00e9cup\u00e9rer la liste des Fruits ou un seul, via le param\u00e8tre <code>name<\/code>. Le tout s\u00e9rialis\u00e9 en JSON.<\/p>\n<p>Voici ce que \u00e7a donne (croyez-le ou pas mais j&rsquo;ai \u00e9crit \u00e7a en une fois sans faute et j&rsquo;en suis fi\u00e8re ;) ).<\/p>\n<pre>\npublic class FruitRestFunction implements HttpFunction {\n    private Gson gson = new Gson();\n    private Map fruits = new HashMap();\n\n    @Override\n    public void service(HttpRequest request, HttpResponse response)\n            throws Exception {\n        String data = null;\n        if(request.getMethod().equalsIgnoreCase(\"POST\")){\n            \/\/create a fruit\n            Fruit fruit = gson.fromJson(request.getReader(), Fruit.class);\n            fruits.put(fruit.name, fruit);\n            data = \"{\\\"status\\\" : \\\"created\\\"}\";\n        }\n        else if (request.getMethod().equalsIgnoreCase(\"GET\")){\n            if(request.getQueryParameters().containsKey(\"name\")){\n                \/\/get a fruit\n                Fruit fruit = fruits.get(request.getQueryParameters().get(\"name\").get(0));\n                data = gson.toJson(fruit);\n            }\n            else {\n                \/\/get all fruits\n                data = gson.toJson(fruits.values());\n            }\n        }\n\n        \/\/write to the response\n        response.setContentType(\"application\/json; charset=utf-8\");\n        response.getWriter().write(data);\n    }\n}\n<\/pre>\n<p>Et pour la classe Fruit tout simplement :<\/p>\n<pre>\npublic class Fruit {\n    public String name;\n    public String color;\n    public String description;\n}\n<\/pre>\n<p>M\u00eame si cet exemple contient une librairie de plus, et deux classes dans deux fichiers diff\u00e9rents, on peut quand m\u00eame le d\u00e9ployer directement sans devoir le packager. Et \u00e7a, on peut l&rsquo;avouer, c&rsquo;est quand m\u00eame top !<\/p>\n<p>Si vous voulez le packager comme un JAR, il faudrait alors r\u00e9aliser un JAR de type uber jar (ou fat jar) en utilisant le plugin maven shade, copier le JAR dans un r\u00e9pertoire, et utiliser l&rsquo;option de ligne de commande <code>--source=directory<\/code>.<\/p>\n<p>Mais ici, on peut d\u00e9ployer tout simplement via cette commande (toujours \u00e0 la racine de votre projet) :<\/p>\n<pre>\ngcloud alpha functions deploy fruit-rest \\\n        --entry-point fr.loicmathieu.gcp.function.FruitRestFunction \\\n        --runtime java11 --trigger-htt\n<\/pre>\n<p>Et voici un petit exemple d&rsquo;utilisation via curl :<\/p>\n<pre>\ncurl -X POST -d '{\"name\":\"apple\", \"color\":\"green\", \"description\":\"Delicious\"}' \\\n        https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/fruit-rest\n&gt; {\"status\" : \"created\"}\n\ncurl -X POST -d '{\"name\":\"banana\", \"color\":\"yellow\", \"description\":\"Yummy\"}' \\\n        https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/fruit-rest\n&gt; {\"status\" : \"created\"}\n\ncurl https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/fruit-rest\n&gt; [{\"name\":\"banana\",\"color\":\"yellow\",\"description\":\"Yummy\"},{\"name\":\"apple\",\"color\":\"green\",\"description\":\"Delicious\"}]\n\ncurl https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/fruit-rest?name=banana\n&gt; {\"name\":\"banana\",\"color\":\"yellow\",\"description\":\"Yummy\"}\n<\/pre>\n<p><strong>Attention<\/strong> : si Google d\u00e9ploie une nouvelle instance de votre fonction pendant vos tests, comme les Fruits sont stock\u00e9s dans une <code>HashMap<\/code>, celle-ci sera vide. Il vous faudra donc recommencer vos tests &#8230;<\/p>\n<h2>Micronaut<\/h2>\n<p>La future version de Micronaut a un support pour les Cloud Functions de GCP. Celui-ci permet d&rsquo;utiliser toutes les fonctionnalit\u00e9s de Micronaut (dont l&rsquo;injection de d\u00e9pendances) pour \u00e9crire vos fonctions.<\/p>\n<p>Pour d\u00e9marrer mon projet Micronaut, j&rsquo;ai utilis\u00e9 <a href=\"https:\/\/micronaut.io\/launch\/\" rel=\"noopener noreferrer\" target=\"_blank\">Micronaut Launch<\/a>. Comme il cr\u00e9\u00e9 un <code>pom.xml<\/code> un peu complexe, le mieux est d&rsquo;aller voir directement dans l&rsquo;exemple disponible sur GitHub : <a href=\"https:\/\/github.com\/loicmathieu\/cloud-function-tests\/tree\/master\/fruit-micronaut\" rel=\"noopener noreferrer\" target=\"_blank\">fruit-micronaut<\/a>.<\/p>\n<p>Nous allons reprendre l&rsquo;exemple pr\u00e9c\u00e9dent, et le r\u00e9-\u00e9crire via un <code>Controller<\/code> Micronaut.<\/p>\n<p>Tout d&rsquo;abord, externalisons la gestion des fruits dans un service :<\/p>\n<pre>\n@Singleton\npublic class FruitService {\n    private Map fruits = new HashMap();\n\n    public Collection list(){\n        return fruits.values();\n    }\n\n    public void add(Fruit fruit){\n        fruits.put(fruit.name, fruit);\n    }\n\n    public Fruit get(String name){\n        return fruits.get(name);\n    }\n}\n<\/pre>\n<p>Puis, \u00e9crivons un <code>Controller<\/code> standard Micronaut, qui sera utilis\u00e9 par notre fonction pour r\u00e9pondre \u00e0 chaque requ\u00eate HTTP :<\/p>\n<pre>\n@Controller(\"\/\")\npublic class FruitController {\n    @Inject\n    private FruitService fruitService;\n\n    @Get(produces = MediaType.APPLICATION_JSON)\n    public Collection list() {\n        return fruitService.list();\n    }\n\n    @Get(\"\/{name}\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Fruit get(String name) {\n        return fruitService.get(name);\n    }\n\n    @Post(processes = MediaType.APPLICATION_JSON)\n    @Status(HttpStatus.CREATED)\n    public ResponseStatus savePet(@Body Fruit fruit) {\n        fruitService.add(fruit);\n        return new ResponseStatus(\"created\");\n    }\n\n   public static class ResponseStatus {\n        public String status;\n\n       public ResponseStatus(String status) {\n           this.status = status;\n       }\n   }\n}\n<\/pre>\n<p>Pour d\u00e9ployer notre fonction, il faut d&rsquo;abord la packager via Maven, puis la copier dans un r\u00e9pertoire dans lequel le JAR doit \u00eatre le seul fichier.<\/p>\n<pre>\nmvn clean package\n\nmkdir deployment\n\ncp target\/fruit-micronaut-0.1.jar deployment\/\n\ngcloud alpha functions deploy fruit-micronaut \\\n        --entry-point io.micronaut.gcp.function.http.HttpFunction \\\n        --runtime java11 --trigger-http --source deployment\/ --memory 512MB\n<\/pre>\n<p>Notez ici qu&rsquo;il faut allouer 512m pour que la fonction fonctionne.<br \/>\nLe support ne semble pas encore parfait (ou je n&rsquo;ai pas bien suivi les instructions), car on voit dans les logs que Micronaut ouvre le port 8080 ce qui ne devrait pas \u00eatre le cas.<\/p>\n<p>Mais il faut avouer que le fait que le packaging par d\u00e9faut fonctionne, et qu&rsquo;on puisse \u00e9crire des fonctions HTTP aussi simplement qu&rsquo;un simple <code>Controller<\/code>, est un vrai plus. Le support est bien pens\u00e9 et fonctionne sans trop de soucis.<\/p>\n<p>Voici ensuite un exemple d&rsquo;utilisation avec curl :<\/p>\n<pre>\ncurl -X POST -d '{\"name\":\"apple\", \"color\":\"green\", \"description\":\"Delicious\"}' \\\n        -H \"Content-Type: application\/json\" \\\n        https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/fruit-micronaut\n&gt; {\"status\" : \"created\"}\n\ncurl -X POST -d '{\"name\":\"banana\", \"color\":\"yellow\", \"description\":\"Yummy\"}' \\\n        -H \"Content-Type: application\/json\" \\\n        https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/fruit-micronaut\n&gt; {\"status\" : \"created\"}\n\ncurl https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/fruit-micronaut\n&gt; [{\"name\":\"banana\",\"color\":\"yellow\",\"description\":\"Yummy\"},{\"name\":\"apple\",\"color\":\"green\",\"description\":\"Delicious\"}]\n\ncurl https:\/\/us-central1-methodical-mesh-238712.cloudfunctions.net\/fruit-micronaut?name=banana\n&gt; {\"name\":\"banana\",\"color\":\"yellow\",\"description\":\"Yummy\"}\n<\/pre>\n<p><strong>Attention<\/strong> : si Google d\u00e9ploie une nouvelle instance de votre fonction pendant vos tests, comme les Fruits sont stock\u00e9s dans une <code>HashMap<\/code>, celle-ci sera vide. Il vous faudra donc recommencer vos tests &#8230;<\/p>\n<p>Pour aller plus loin avec Micronaut : le <a href=\"https:\/\/micronaut-projects.github.io\/micronaut-gcp\/2.0.x\/guide\/#httpFunctions\" rel=\"noopener noreferrer\" target=\"_blank\">guide des fonctions HTTP<\/a> et l&rsquo;<a href=\"https:\/\/github.com\/micronaut-projects\/micronaut-gcp\/tree\/master\/examples\/hello-world-cloud-function\" rel=\"noopener noreferrer\" target=\"_blank\">exemple officiel<\/a>.<\/p>\n<h2>Comment \u00e7a marche<\/h2>\n<p>Il n&rsquo;y a pas beaucoup de documentation expliquant comment \u00e7a marche. En regardant les logs on comprend qu&rsquo;une fonction, c&rsquo;est un d\u00e9ploiement dans AppEngine.<\/p>\n<p>Si vous d\u00e9ployez une fonction sans la packager au pr\u00e9alable, la ligne de commande va d&rsquo;abord la packager en utilisant Maven de mani\u00e8re transparente (je l&rsquo;ai vu car j&rsquo;avais un test qui ne passait pas et j&rsquo;ai eu un joli message d&rsquo;erreur Maven), avant de l&rsquo;envoyer \u00e0 Google AppEngine. Si vous buildez votre fonction, la ligne de commande va se contenter de prendre le JAR build\u00e9 et de l&rsquo;envoyer \u00e0 AppEngine.<\/p>\n<p>Par d\u00e9faut, notre fonction a 256m de m\u00e9moire allou\u00e9es, et ses logs sont disponibles directement depuis la console GCP.<\/p>\n<p>Apr\u00e8s, comme c&rsquo;est du <em>serverless<\/em>, on ne g\u00e8re ni le nombre de fonctions, ni quand une autre est d\u00e9ploy\u00e9e. M\u00eame en testant seul via curl, j&rsquo;ai eu des re-d\u00e9ploiement de fonction (ou re-d\u00e9marrage). Comme toujours, attention donc au cold start !!!<\/p>\n<h2>Conclusion<\/h2>\n<p>Le support de Java dans Google Cloud Function \u00e9tait attendu de longue date, AWS et Azure supportant d\u00e9j\u00e0 Java.<\/p>\n<p>L&rsquo;impl\u00e9mentation est assez propre, une simple interface qui donne acc\u00e8s aux requ\u00eates et r\u00e9ponses HTTP et c&rsquo;est tout ! J&rsquo;aime \u00e7a ;)<\/p>\n<p>Au niveau outillage, le build automatique de votre projet Maven est vraiment pratique, apr\u00e8s tout, une fonction est cens\u00e9e \u00eatre simple, et \u00e7a peut donc suffire pour pas mal d&rsquo;utilisation. Pour des projets plus complexes, un simple uber JAR cr\u00e9\u00e9 avec le plugin shade suffit. On appr\u00e9cie de n&rsquo;avoir rien de sp\u00e9cifique \u00e0 faire pour builder nos fonctions.<\/p>\n<p>Le support de Java 8 et 11 est un plus, ce sont les deux versions les plus utilis\u00e9es. Par comparaison, Azure ne supporte toujours par Java 11 au jour d&rsquo;\u00e9criture de cet article !<\/p>\n<p>Google r\u00e9-utilise AppEngine pour faire tourner nos fonctions, et \u00e7a c&rsquo;est bien car AppEngine est un outil stable, et qui fonctionne tr\u00e8s bien (certains diront que c&rsquo;est le premier outil serverless &#8230; il est effectivement tr\u00e8s vieux).<\/p>\n<p>Vous pouvez retrouver tous les exemples de cet article dans mon repository <a href=\"https:\/\/github.com\/loicmathieu\/cloud-function-tests\" rel=\"noopener noreferrer\" target=\"_blank\">cloud-function-tests<\/a>.<\/p>\n<p>P.S. &#8211; Ceux qui me connaissent savent que je contribue r\u00e9guli\u00e8rement \u00e0 Quarkus et se poseront donc la question, <em>et Quarkus<\/em> ? Quarkus est en train de refactorer son support des fonctions via <strong>Funqy<\/strong>, une nouvelle librairie qui permettra de d\u00e9velopper les fonctions de la m\u00eame mani\u00e8re pour AWS et Azure (les deux Clouds support\u00e9s par Quarkus pour le moment). J&rsquo;ai commenc\u00e9 \u00e0 travailler sur un support pour Google Cloud Function via Funqy &#8230; stay tuned ;)<\/p>\n<p>Un remerciement tout sp\u00e9cial \u00e0 Logan pour sa relecture et la correction des nombreuses fautes d\u2019orthographe \ud83d\ude09<\/p>","protected":false},"excerpt":{"rendered":"<p>J&rsquo;ai test\u00e9 les Java Google Cloud Functions en Alpha. Jusqu&rsquo;ici, les Cloud Functions de Google n&rsquo;\u00e9taient impl\u00e9mentables qu&rsquo;en NodeJs, Go ou Python. Mais Google est en train de pr\u00e9parer l&rsquo;ouverture d&rsquo;un runtime Java (8 et 11), que j&rsquo;ai pu tester en alpha release priv\u00e9e (pour s&rsquo;inscrire, c&rsquo;est ici). Apr\u00e8s inscription \u00e0 l&rsquo;alpha priv\u00e9e, vous aurez acc\u00e8s \u00e0 un document de tutoriel pas \u00e0 pas, et \u00e0 un forum d&rsquo;aide en ligne. On peut \u00e9crire deux types de fonctions : les&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/j-ai-teste-java-google-cloud-functions-aplha\/\">Lire la suite<span class=\"screen-reader-text\"> Lire la suite<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[181,179,11,180,182],"class_list":["post-1068","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-function","tag-gcp","tag-java","tag-micronaut","tag-serverless"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":1440,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/google-cloud-functions-2nd-gen\/","url_meta":{"origin":1068,"position":0},"title":"Google Cloud Functions 2nd gen","author":"admin","date":"mardi 29 mars 2022","format":false,"excerpt":"Google vient de sortir en beta la seconde g\u00e9n\u00e9ration des Google Cloud Functions. Pour ceux qui ne connaissent pas encore les Google Cloud Functions vous pouvez lire mes articles J\u2019ai test\u00e9 Java Google Cloud Functions et Quarkus et les Google Cloud Functions. Cette seconde g\u00e9n\u00e9ration apporte : Un temps de\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1532,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/tester-une-java-google-cloud-function\/","url_meta":{"origin":1068,"position":1},"title":"Tester une Java Google Cloud Function","author":"admin","date":"mardi  4 octobre 2022","format":false,"excerpt":"Jusqu'il y a peu de temps, tester une Google Cloud Function \u00e9crite en Java pouvait se faire via l'invoker fournit par le SDK des Google Cloud Functions mais pas via un test unitaire. Mais cela \u00e0 chang\u00e9 r\u00e9cemment ! Prenons comme exemple la fonction HTTP suivante : public class HelloHttpFunction\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1560,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-tip-tester-une-fonction-google-cloud\/","url_meta":{"origin":1068,"position":2},"title":"Quarkus Tip : Tester une fonction Google Cloud","author":"admin","date":"jeudi 29 d\u00e9cembre 2022","format":false,"excerpt":"J'ai r\u00e9cemment contribu\u00e9 une PR \u00e0 Quarkus qui contient un framework de test pour les fonctions Google Cloud. Quarkus supporte la cr\u00e9ation de fonction Google Cloud de trois mani\u00e8res diff\u00e9rentes : En utilisant l'API de Google Cloud. En utilisant une extension HTTP de Quarkus : RESTEasy, Reactive routes, Servlet, Spring\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1345,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-et-les-google-cloud-functions\/","url_meta":{"origin":1068,"position":3},"title":"Quarkus et les  Google Cloud Functions","author":"admin","date":"mardi  2 novembre 2021","format":false,"excerpt":"Quarkus est un framework de d\u00e9veloppement de microservice pens\u00e9 pour le cloud et les conteneurs. Il est pens\u00e9 pour avoir une utilisation m\u00e9moire r\u00e9duite et un temps de d\u00e9marrage le plus court possible. Il se base principalement sur des standards (Jakarta EE, Eclipse MicroProfile, \u2026) et permet l'utilisation de librairies\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":966,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/1-an-chez-zenika\/","url_meta":{"origin":1068,"position":4},"title":"1 an chez Zenika","author":"admin","date":"mardi  3 septembre 2019","format":false,"excerpt":"Aujourd'hui est un jour sp\u00e9cial, cela fait un an que je suis arriv\u00e9 chez Zenika, apr\u00e8s 9 ans en tant qu'architecte logiciel dans la DSI d'un grand groupe de retail. Et apr\u00e8s un an, quel est donc le bilan ? Tout d'abord, Zenika m'a surpris. Lors des \u00e9changes que j'ai\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":377,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/session-chti-jug-sur-les-technologies-google\/","url_meta":{"origin":1068,"position":5},"title":"Ch&rsquo;ti Jug: les technologies Google","author":"admin","date":"mercredi 11 novembre 2009","format":false,"excerpt":"Hello, Lundi j'ai \u00e9t\u00e9 \u00e0 la session du Ch'ti Jug sur les technologies Google qui s'est pass\u00e9 \u00e0 l'ISEN et \u00e9tait sponsoris\u00e9e par SII. C'\u00e9tait la premi\u00e8re fois que j'assistais \u00e0 un \u00e9v\u00e8nement organis\u00e9 par le Ch'ti Jug et comme c'\u00e9tait int\u00e9ressant, j'aimerais partager avec vous l\u00e0 dessus. Ch'ti Jug?\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"Google Wave","src":"https:\/\/i0.wp.com\/loicmathieu.free.fr\/wordpress\/wp-content\/uploads\/google-wave.jpg?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.free.fr\/wordpress\/wp-content\/uploads\/google-wave.jpg?resize=350%2C200 1x, https:\/\/i0.wp.com\/loicmathieu.free.fr\/wordpress\/wp-content\/uploads\/google-wave.jpg?resize=525%2C300 1.5x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1068","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/comments?post=1068"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1068\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/media?parent=1068"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/categories?post=1068"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/tags?post=1068"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}