Deux approches Cloud (parmi d’autres)

DevoxxFr a été l’occasion d’une revue très large des technologies en connexion avec les sujets chauds du moment : le Mobile, les frameworks de haute productivité (Grails et Play par notamment), le futur de Java, les langages de la JVM présents et à venir (Scala, Groovy, Ceylon), le NoSQL, et bien entendu le CLOUD !

A ce titre, je reviendrais sur deux présentations qui montrent la diversité des solutions proposées quand on se penche sur les offres PAAS (Platform As A Service) :

  • Un retour d’expérience sur Google App Engine , par Didier Girard et Ludovic Champenois, mettant en avant la richesse de la solution, qui regroupe toutes les briques techniques susceptibles d’être exploitées ;
  • Une approche composite, menée par Cyrille Leclerc, qui s’est attaché à construire une application en choisissant un fournisseur différent pour chacun des aspect techniques (Base de données, moteur Web, Analyse de logs, ressources statiques, emails ).

Google app engine

L’approche Google a les avantages d’une solution entièrement propriétaire :

  • Tous les éléments sont réunis dans une plateforme (Mail, données, Moteur de servlet ).
  • Les outils de développements (sous eclipse) sont matures, vraiment opérationnels (de ma propre expérience) et demandent peu ou pas de configuration,
  • Les performances sont au rendez-vous, puisque les briques techniques sont optimisées entre elles (et qu’elles bénéficient du savoir-faire de Google en la matière qui n’est plus à démontrer). On peut même dire que, en respectant les bonnes pratiques (en utilisant autant que possible le cache par exemple), les temps de réponse sont excellents.
  • Et les inconvénients qui viennent avec :

    • Une obligation de se conformer à des standards spécifiques (notamment sur la persistance et le format BigTable de Google), avec des efforts notables d’abstraction vers des standards (JPA, JSR Cache).
    • Un seul fournisseur chez qui déployer son application ‘cloudisée’, par opposition à ce que VM Ware promeut au travers de cloud foundry.
    • Au global, une possibilité de se désengager peu aisée, notamment si la politique de tarif devait évoluer (ce sont des choses qui sont impérativement à envisager sur le long terme) ou bien si la structure du DataStore change.

    J’ai pu noter que, depuis mes premiers tests en 2009, cette plateforme avait évolué vers une solution vraiment complète et industrialisable; Par exemple les exécuteurs sont déclinés en ‘Front’ (traitant les requêtes Web) et ‘Back’ (qui peuvent supporter les traitements asynchrones, batch, plus gourmands en performance), avec la possibilité d’exporter les données.

    Un cloud composite

    Les offres sur le cloud sont pléthoriques et des offres dédiées pour chaque composant technique d’une application permettent d’envisager une construction sur-mesure.
    En partant des plateformes comme Heroku, Cloudbees, CloudFoundry et en se penchant sur les extensions possibles, on s’ouvre à des combinaisons très nombreuses ; On aura cependant à l’esprit des aspects structurants pour la bonne tenue de l’application en production et leur maîtrise à l’heure de faire le choix d’architecture:

    • La latence du réseau entre le serveur et la base de données (on les colocalisera, plutôt que d’avoir un serveur en Europe et une base de données aux Etats-Unis),
    • Le droit sous lequel les données sont stockées selon leur sensibilité (Cloud Français ; Cloud américain),
    • La gestion du cycle de vie des données (et les fonctionnalités d’export, pour des traitements BI dans ses infrastructures, par exemple),
    • La sécurité : ces offres sont forcément moins protégées que les DMZ personnalisées, et à chaque maillon de la solution cette question doit être posée,
    • De même pour les SLA (niveaux de service) : notre solution doit être résiliente, et supporter toutes les défaillances potentielles des chacun des différents fournisseurs,
    • Enfin, et non le moindre : la politique tarifaire ; les offres non bornées peuvent présenter des risques important lors de l’explosion de la charge de l’application.

    Sans décliner chacune des solutions techniques, on peut observer que les éléments suivants sont bien couverts par les offres cloud :

    • Database As A Service : Mongo HQ par exemple, avec des offres complémentaires de sauvegarde,
    • Stockage de fichiers : Amazon Web Service AWS S3 ou Microsoft Azure,
    • Search as a service :Solr avec WebSolr.
    • E-mail as a service : SendGrid , CritSend,
    • Monitorig as a service : AppDynamics

    Les projections de coûts d’utilisation sont vraiment bas, et servent notamment les petites structures ou celles qui démarrent, qui n’ont pas forcément à se poser la question de créer leur propre salle blanche et établir une équipe d’industrialisation. Attention cependant aux coûts cachés: la rareté des compétences, la maîtrise des données…

    Pour nos clients qui cherchent à mettre sur pied une application à forte volumétrie, sans forte pérennité (une campagne de publicité, une enquête à large spectre), ces approches semblent particulièrement appropriées et immédiatement disponilbes.

Généralités

Ceci est le retour (personnel) de la présentation de Cassandra faite par Nicolas Romanetti.

Le point d’accroche de Cassandra est d’adresser les systèmes de volumétrie gigantesque en mettant en avant des capacités de montée ne charge aussi linéaires que possible en ajoutant des nœuds. L’ambition est de l’être pour l’écriture et pour la lecture (ce qui est une gageure sur de tels volumes).

Cette solution motorise certains des géants du Web, dont Twitter et Netflix, ce qui est probant quand on se penche sur la question des retours d’expérience. (Remarque : nous n’aurons pas les éléments dimensionnant des architectures en place).

Autres éléments distinctifs : la une solution est construite sans responsabilité maître-esclave à même d’encaisser les défauts d’un ou plusieurs nœuds.

Ce qui est structurant, comme pour un certain nombre de solutions NoSQL, c’est l’organisation des données en colonnes, elles-mêmes regroupées en Rows, elle-mêmes…. Le but est de proposer la possibilité :

  • De changer sans aucune contrainte le « schéma » de la base de données,
  • De se donner très peu de limites dans la quantité de données stockées.

Patterns de modélisation spécifiques :

  • le nom est libre pour les colonnes : peut-être calculé dynamiquement ! (beaucoup utilisé pour des time series).
  • on peut se passer de valeurs dans une colonne !
  • on peut mettre deux notions dans un nom de colonne !

Tout peut avoir un sens quand on recherche la performance ultime.

Ensuite, le contenu d’une colonne peut être très diversifié, à l’exclusion de données binaires (pour des raisons d’engorgement mémoire et réseau) : XML, JSON , CSV…

On a également des briques qui serviront à la gestion des cycles de données (historisation, accès concurrentiel):

  • Colonne expirante : suppression automatique ? Colonne compteur, Colonne Tombstone pour la suppression d’une valeur.

Cette souplesse se prolonge dans les environnements de production dont les modèles peuvent évoluer sans véritable contrainte (autre que la cohérence globale de l’application…bien entendu)

Partie II : les requêtes

Il nous est précisé que l’on ne requête pas de la même manière les lignes (ou ROW) courtes (Skinny) et longues (WIDE… avec des séries temporelles…à 10 millions de colonnes) :

  • Sur les skinny rows : on effectue des requêtage en mode ‘tableau’
    • pays [‘Thailande’][‘monnaie’]
    • pays [‘Thailande’][‘population’]
    • etc…
  • Sur les Wide rows, on extrait des tranches (ou slices) : par exemple, la tranche des 100 derniers tweets d’un utilisateur.

En revanche, Cassandra ne dispose pas d’un arsenal de requêtage relationnel (oublier les GROUP BY…. )

Pour des usages spécifiques, on sera probablement amené à décliner les données selon plusieurs enregistrements (ou ROWS).

Partie III : l’architecture résiliante

La partie la plus conséquente de la présentation, et intéressante d’un point de vue des algorithmes entrant en jeu a été l’étude des mécanismes de cohérence de la base :

  • Détermination du nombre de nœuds initial, avec possibilité d’en ajouter autant que nécessaire,
  • Répartition uniforme des valeurs par hachage (token).
  • Facteurs de réplication sur un certain nombre de nœuds avec des approches plus ou moins restrictives.

Les différents cas de mise en défaut d’un nœud (en écriture, en lecture) mettent en évidence la capacité de Cassandra à se régénérer presque automatiquement, en utilisant de façon soutenue les échanges entre nœuds (qu’ils soient en possession de la donnée, ou bien qu’ils jouent le rôle d’orchestrateur le temps d’une requête).

Une préoccupation doit toujours être à l’esprit du concepteur pour des raisons de performance: Les requêtes ne devraient pas solliciter plusieurs nœuds à la fois; On favorisera donc une architecture basée sur des ROWs de grande taille plutôt que sur une multiplicité de ROWs qui se retrouveraient distribués

Cassandra dispose nativement de 3 niveaux de ‘réparation’ ou de ‘remise en état’ des données incohérente qui donnent un niveau de fiabilité très important pour un système scalable.

Dernier point, les Performances.

Cassandra jouit d’une excellente réputation pour ses temps d’écriture, par le biais d’un mécanisme de CommitLog et de mise en mémoire rapide et sure.

Les transactions sont enregistrées en commitLog et mémoire pour pouvoir rejouer les requêtes le cas échéant. Elles sont ensuite prises en charge par un mécanisme de flush, puis suppression des données dans le commitLog.

Les Performances en lecture sont optimisées au travers des approches complémentaires suivantes :

  • Accès direct en mémoire
  • Row cache (sur les skinny rows),
  • BloomFilter (Cf. WikiPedia)
  • Et enfin du keyCache (sorte d’index des clés) en mémoire
  • Et sur disque, de la compaction automatique

Nicolas Romanetti a fait un focus sur un point qui lui a paru nettement optimisable : la structure du code open source (et l’interdépendance des packages qui rendent peu lisible la responsabilité des composants).

Par ailleurs, les outils de monitoring semblent rudimentaires.

Et ensuite ?

Cassandra fait partie de la fondation Apache et connaît un développement soutenu, avec un certain nombre de fonctionnalités dans sa RoadMap (Intégration de Lucene pour les index secondaires, outillage, langage de requête CQL enrichi….).

Des efforts sont également faits pour utiliser Hadoop sur cette base, même si cette approche semble moins naturelle qu’avec HBase.

Est-ce pour cela que certains utilisateurs ont laissé de côté Cassandra ?

ou ‘Un coup d’œil aux gestionnaires de code source distribué’

Dans le domaine des solutions d’hébergement de projet autour du gestionnaire de source Git, deux solutions tiennent le devant de la scène aujourd’hui : Github et Bitbucket.

Voici un petit comparatif des forces et faiblesses pour vous aider à choisir, en fonction de vos attentes et de votre organisation.

Pour parler popularité, Github concentre la plus grande partie des dépôts de sources (plus de 2 millions, avec une grande représentation de projets ‘stars’ : Grails & spring sont sur Github). L’avance prise sur BitBucket s’explique notamment par les fonctionnalités et innovations apportées à ce qui est véritablement une plateforme de développement… BitBucket faisant surtout du suivisme.

Il est important de noter que BitBucket est supporté par Atlassian, qui a une certaine assise dans le monde open source (JIRA, Confluence ….)

Ils partagent une caractéristique commune et étonnante : la taille illimitée des espaces réservés au code source. Cela s’explique facilement par la nature décentralisée de Git et Mercurial et donc par la volumétrie intrinsèquement modeste du code et des méta-données.

Comparaison

Voici une grille de comparaison des tarifs et de caractéristiques structurantes prou des projets ‘Entreprise’

comparatif quantitatif Github BitBucket

(la soft limit pour github est là pour prévenir les abus, il n’y a pas de limite réelle sur la taille)

Sur ces données, les deux solutions sont relativement proches; l’écart se creuse en revanche sur la complétude des fonctionnalités couvertes, qui sont mieux adressées par GitHub:

comparatif qualitatif Github BitBucket

Plus éloquant, voici une liste des fonctionnalités intéressantes de Github dont ne dispose pas Bitbucket:

fonctionnalités supportées par GitHub uniquement

Pour aller plus loin

…ou la descente aux enfers d’une application JSF, RICHFACES, SPRING

Voici un retour d’expérience sur un événement projet comme on est appelé à en rencontrer beaucoup sur le cycle de vie d’une application, notamment lors de la maintenance, les enseignements à en tirer sont nombreux.

Il s’agissait de migrer de version une application développée en JSF1.2/RichFaces de navigateur Internet Explorer 8 (IE8) vers IE9.

Pour avoir passé il y a peu la redoutable montée de version de IE6 vers IE8, l’équipe en charge du développement, parfaitement rompue à ce contexte technique, avançait avec confiance sur ce sujet. Tout au plus devait-il s’agir d’ajustements cosmétiques isolés…. Mais ce petit battement d’aile de papillon a provoqué une belle tornade sur toute l’application, dont voici les détails.

Cadre technique: l’application en question est conçue selon une architecture multicouche avec les librairies & versions suivantes, qui ont leur importance pour la suite des événements :

dépendances JSF, Spring, RichFaces, JUnit

Après un premier test rapide, les comportements Ajax qui sont massivement utilisés par RichFaces ne fonctionnent pas sous IE9. C’est étonnant à double titre :

  • Les appels ajax sont motorisés par jQuery dont la portabilité est un gros point fort,
  • Les développements jQuery faits par ailleurs ne présentent aucune régression

RichFaces fonctionnant en ‘boîte noire’, il a été décidé de migrer en version 4.0, réputée compatible avec IE9.

Dépendances JSF, RichFaces, Spring, Junit 2

Des changements en cascade

Comme représenté ci-dessus, RichFaces 4 ne se branche que sur du JSF 2.0 : ce sera donc notre première étape de montée de version collatérale.

Puis s’enchainent les étapes suivantes :

  • JSF2.0 impose Spring Web Flow 2.3
  • Spring Web Flow nécessite Spring (Core & Security)>=3.0 et Spring Faces >=2.3.0
  • Spring 3.0 nécessite de passer JUnit en 4.9 ; en effet, le chargement du fichier de contexte applicatif bloquait lors des lancements de test.

En arrivant à la situation où les briques au cœur de notre application ont été remplacées… ainsi que celles qui sont plus ‘périphériques’ :

Dépendances JSF, RichFaces, Spring, JUnit 3

Il faut surtout se figurer que chacune de ces montées de version a provoqué de difficultés :

  • Bugs notoires ( a4j :commandLink non opérationnels dans Spring faces 2.3.0) : application d’un patch ou bien attente de la version corrective ? c’est selon vos priorités.
  • Changement de configuration xml (faces-config.xml, web.xml, tous ces fichiers au cœur de l’application sont impactés),
  • Incompatibilité de versions de servlet avec Tomcat,
  • Modification de certaines balises JSF : impact sur toutes les JSPs,
  • Perte des espaces de nom sous Eclipse (entrant en confilt au niveau des xsd préalablement utilisés : Une montée de version du plugin spring d’eclipse peut corriger ces problèmes
  • …et encore bien d’autres plus ou moins intrusives

De plus, ces incohérences étaient parfois à l’origine de problèmes rencontrés seulement à l’exécution du serveur au travers d’exceptions NoSuchMethodException et java.lang.UnsupportedOperationException pour lesquelles la difficulté était de trouver la librairie en cause. Elles survenaient au chargement de l’application ou bien au détour d’une page, ce qui exigeait de faire des tests exhaustifs.

Voici quelques conclusions que nous pouvons en tirer :

1) Basique : IE9 et RichFaces 3.3.3 ne font pas bon ménage !

2) Architecture : les applications composites sont une approche rationnelle pour tirer profit des innombrables librairies adressant chacune au mieux le rôle pour lequel elles ont été créées. Si elles mettent effectivement à disposition une grande richesse de fonctionnalités, elles peuvent se révéler instables quand on doit en modifier un élément technique.

3) JSF (et autres frameworks Web à forte cohésion avec le serveur): la structuration d’applications JSF est intrinsèquement orientée serveur (règles de navigation, de contrôle, cycle de vie des Beans…) et de ce fait entraîne des changements profonds dans les cas problématiques comme celui-ci. Les pistes désormais explorées vers une séparation plus nette entre client Web et un serveur orienté REST permettra de clarifier certaines pratiques et alléger la responsabilité du serveur dans la génération de l’interface utilisateur.

4) Gestion des dépendances : engagés dans une application composite, il faudra couvrir les versions parfois conflictuelles de librairies, d’implémentations. Même outillée avec Maven, cela reste difficile quand c’est à l’exécution, avec des erreurs absconses, que cela se caractérise.

5) Tests : sur une application riche fonctionnellement, qui va traverser malgré elle quelques générations techniques, un portefeuille de tests automatisés sera le garant d’une bonne maîtrise de la non régression (Unitaires, Fonctionnels) ; Dans ce cas présent, l’application dispose d’un riche panel de tests JUnit à connotation ‘Intégration’, faute de scripts Selenium exhaustifs (seuls quelques uns on été créés).

6) Projet : De la difficulté récurrente de connaître l’impact d’une évolution, même sur un environnement technique et fonctionnel bien maîtrisé.

7) Open source : à la fois riche et ouvert, il peut se rendre problématique pour des demandes de support. Nous sommes dans le cas de communautés très importantes, très réactives, ce qui facilite la prise en compte des anomalies / évolutions ; mais cela sera dommageable sur des librairies de niches, peu documentée ou suivies…. La pérennité est à prendre en compte.

Cet article a pour but de parcourir les étapes de création et de publication d’une application JEE dans la forge PAAS CloudFoundry. Celle-ci, supportée par VMWare, profite largement des nouveautés de Spring 3.1 (à ce jour encore en RC2).

La particularité est qu’elle se décline en une version portable (ou installable dans son infrastructure privée) au travers de sa version MicroCloudFoundry.

Pourquoi aller dans le Cloud ?

Les motivations peuvent être variées ; c’est sous l’axe suivant que nous avons mis en place nos applications dans la CloudFoundry :

  • La mise en ligne d’applications facilitée avec l’accès à des environnements en tant que services,
  • La simplification des démarches d’administrations afférentes,
  • La montée en charge, avec un ajout d’instances à la volée et une réserve de puissance illimitée … ou disons plutôt très importante.

… Mais tout d’abord, un petit tour de la forge de VM Ware :

Avec CloudFoundry, nous avons la possibilité de déclarer des services à partir d’un portefeuille déjà bien garni de briques techniques pour structurer notre socle applicatif adapté au cloud:

  • MySQL & PostgreSQL, pour les bases relationnelles,
  • RabbitMQ, un bus de message qui orchestrera les services et une part de la répartition de la charge,
  • MongoDB et Redis, des bases clé/valeurs très souples d’utilisation et très performantes.

Les applications sont packagées sous la forme de war et déployées par console sur un tomcat adapté à la sauce VMWare.

Remarque : celles-ci sont appelées à s’étoffer avec la version open-source sur cloudfoundry.org.

Se projeter vers une solution cloud, c’est se conformer à certains paradigmes techniques liés à la ‘dématérialisation’ des applicatifs : nous ne sommes pas figés sur un serveur physique ou une localisation arrêtée des données.
Ceci n’est pas sans conséquences sur la façon dont l’architecture de l’application est établie, ni sur le processus de publication. Par exemple :

  • Les ressources statiques ne sont pas enregistrées dans le système de fichier, mais sur sur une base clé / valeur,
  • Les sessions doivent gérées en fonction du load balancing,
  • Les transactions ne sont pas aussi nettement définie que sur une application classique, et on procède par solution approchante (exemple : http://www.mongodb.org/display/DOCS/Atomic+Operations)

Nous allons donner un aperçu des étapes de mise en place d’une application en utilisant les possibilités offertes par Spring pour orchestrer le tout.
La constellation Spring (Core, Data, Integration, Web-Services,…) est supportée par VM Ware qui en a fait son socle technique pour structurer les applications éligibles à son cloud, ce qui en fait une approche naturelle pour concevoir notre application.

Configuration du fichier de contexte Spring

Notre fichier applicationContext.xml est la pierre angulaire de notre configuration, et se distingue par :

  • 1- Les espaces de noms utilisés :
    1
    2
    3
    4
    5
    6
    7
    8
    
    	<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:cache="http://www.springframework.org/schema/cache"
    	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    	xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:cloud="http://schema.cloudfoundry.org/spring"
    	xmlns:mongo="http://www.springframework.org/schema/data/mongo"

    Ils représentent la multiplicité des technologies en jeu dans notre architecture: du jdbc (pour MySQL), du data (pour Mongo), du cache (nouveauté 3.1 apportant une abstraction de solutions de cache)…

  • 2- L’utilisation de profiles et des balises ‘cloud’ qui facilite le raccrochement aux services déclaré dans notre espace cloud
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    <beans profile="default">
    	<bean id="mongoDbFactory"  class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">
    			<constructor-arg name="mongo">
    				<mongo:mongo  host="127.0.0.1"/>
    			</constructor-arg>
    			<constructor-arg name="databaseName" value="mongoimages"/>
    		</bean>
    		<bean class="org.apache.commons.dbcp.BasicDataSource" 			destroy-method="close" id="dataSource"><property name="testOnBorrow" value="true" />
    		</bean>
    </beans>
     
    <beans profile="cloud">
    		<cloud:mongo-db-factory id="mongoDbFactory"  service-name="mongoimages" />
    		<cloud:data-source id="dataSource" service-name="masqlbase"/>
    </beans>

    Les dépendances maven correspondantes sont, entre autres :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    <properties><org.cloudfoundry-version>0.8.1</org.cloudfoundry-version>
    		<org.cloudfoundry-group>org.cloudfoundry</org.cloudfoundry-group>
    		<org.spring-data-mongo-version>1.0.0.M4</org.spring-data-mongo-version>
    		<spring.version>3.1.0.RC2</spring.version>
    	</properties>
    	<dependencies>
     
    		<dependency>
      			<groupId>org.cloudfoundry</groupId>
      			<artifactId>cloudfoundry-runtime</artifactId>
      			<version>${org.cloudfoundry-version}</version>
    		</dependency>
     
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-core</artifactId>
    			…
     
    		<dependency>
    			<groupId>org.springframework.data</groupId>
    			<artifactId>spring-data-mongodb</artifactId>
    			<version>${org.spring-data-mongo-version}</version>
    		</dependency>

Les bonnes pratiques de développement avec Spring pour le cloud:

  • 1) Séparer la définition de ses beans pour séparer le local du mode production

    On initialise un profile avec la découverte automatique de l’environnement :
    using-bean-profiles-on-cloud-foundry

  • 2) Utilisation des balises ‘cloud’
    Elles rattachent le service correspondant sous le nom de bean réservé, en toute transparence. Par exemple :

    1
    2
    3
    
    <beans profile="cloud">
    		<cloud:mongo-db-factory id="mongoDbFactory"  service-name="acimage" />
    		<cloud:data-source id="dataSource" service-name="acibase2"/>
  • 3) Utilisation de Spring-Data pour la persistance avec MongoDB
    Les objets MongoTemplate injectés par Spring offrent des facilités de requêtage et de transtypage des résultats.

    1
    2
    3
    4
    5
    6
    7
    8
    
    @Autowired
    MongoTemplate template;
     
    @Override
    public byte[] getImage(String nom) {
    	try {
    		final Acimage findOne = template.findOne(query(where("nom").is(nom)), Acimage.class,AppMongoConfig.MONGO_NOM_COLLECTION_IMAGE);
    ...
  • 4) Cacher les données peu volatiles avec Spring 3.1
    On définit des régions pour le cache de données pour y stocker les résultats de requêtes fréquentes et peu changeantes ; puis on attache aux méthodes susceptibles de changer les données les événements de nettoyage du cache.
    On sollicite d’autant moins les sources de données sous-jacentes.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    @Cacheable(value=MonAppCacheRegion.SUPER_CATEGORIE_REGION)
    	public List<SuperCategorie> toutesSuperCategoriesActives() {
    		final TypedQuery<SuperCategorie> requete = entityManager.createQuery(" select c from SuperCategorie c where c.etat = :status",SuperCategorie.class);
    		requete.setParameter("status", 'A');
    		return requete.getResultList();
    	}
     
    	@Cacheable(value=MonAppCacheRegion.CATEGORIE_ID)
    	public Categorie categorieParId(Integer id) {
    		return entityManager.find(Categorie.class, id);
    	}
     
    	@Override
    	@CacheEvict(value={MonAppCacheRegion.CATEGORIE_PAR_SUPER,MonAppCacheRegion.CATEGORIE_REGION,MonAppCacheRegion.SUPER_CATEGORIE_REGION,MonAppCacheRegion.CATEGORIE_ID},allEntries=true)
    	public Categorie merge(Categorie detachedInstance) {
    		return super.merge(detachedInstance);
    	}
  • 5) L’utilisation de Spring Tools Suite (>= 2.8) pour piloter les applications et leur déploiement.
  • Console CloudFoundry dans Spring Tools Suite

    Console CloudFoundry dans Spring Tools Suite

    Par ailleurs, CloudFoundry offre:

    • Un monitoring en cours d’ouverture au public (dans l’esprit de Spring Insight )
      Suivi des performances dans Cloud foundry

      Suivi des performances dans Cloud foundry

    • Un échange de données bi-directionnel entre le Cloud et l’entreprise au travers de Tunnels.
    • Une multiplicité de langages supportés au-delà de Java & Groovy : Scala, Ruby …

    Comme nous l’avons vu, les adhérences ne sont pas trop coercitives et la souplesse offerte par Spring se révèle très agréable quand il s’agit de jongler entre un environnement de développement partiellement représentatif du cloud et un environnement de production.
    Certains points, comme la mise en place de SSL restent un peu plus subtiles à mettre en place (Setup-SSL-on-cloudfoundry-landscape), ou en cours de construction (comme la cohabitation de la gestion des sessions et de répartition de la charge).

    , , ,