Sur la route d'Oxiane digressions diverses

LeBlog OXiane

23 oct
2014

NgEurope : le chemin d’AngularJS 1.2 à 1.3 vers 2.0

NgEurope 2014 à l’espace charenton, Paris

Je sors tout juste de la conférence Angular 2.0 Core d’Igor Minar & Tobias Bosch au quatrième jour de l’excellente NgEurope 2014 qui a eu lieu cette semaine du 20-24 Octobre à Paris .

Le programme de ces 5 jours à Paris pour les 850 fondus du framework AngularJS n’était pas moins :

  • Premier jour : Formation EggHead.io
  • Deuxième jour : Formation EggHead.io, AngularJs et AngularJS Sprint
  • Troisième jour : 13 conférences + Lightning talks
  • Quatrième jour : 15 conférences + Lightning talks
  • Cinquième jour : Royal Hackathon

Un programme très intense et la présence de sociétés innovantes étaient de la partie.
Bien sur OXiane était présente avec:

  • la gestion des inscriptions de 70 français
  • un stand de présentation et d’échange
  • un test AngularJS pour les français aventureux

Lire la suite du bllet »

Julien Cheron

jcheron

8 oct
2014

Firebase sort une extension Chrome : Vulcan

Voilà encore un outil d’intégration pour nos développements front !
Firebase est une plateforme de services Cloud très efficace, fournissant un système de services REST pour stocker ses données ainsi que de multiples systèmes d’authentifications à des services tiers comme Facebook, Twitter ou Google+.
Le développement front avec AngularJS est aujourd’hui fortement accéléré par l’utilisation d’une plateforme comme Firebase.
En effet, AngularJS nous permet de monter notre modèle de données via de simples appels à des « resources », autrement dit … des services REST.

Avec Angular, je peux facilement gérer mes requêtes REST de cette façon :

.factory('FriendsBase', function ($firebase, FIREBASE_URL) {
var ref = new Firebase(FIREBASE_URL + 'friends');
var friends = $firebase(ref);
var FriendsBase = {
all: friends,
create: function(friend){
return friends.$add(friend);
},
...

Il me suffit d’appeler la méthode :create de mon service Angular pour voir le résultat en base :

Le seul hic, c’est que si je dois inspecter ma base pour vérifier la bonne insertion / édition de mes données, je dois aller sur le site de Firebase et m’identifier et garder un onglet ouvert dans un coin.
Avec Vulcan, l’éditeur va nous permettre de manipuler notre base directement dans le web developper !
Voici la configuration de la base à utiliser :

Une fois connecté à la base, l’interface apparait et on peut manipuler nos données directement !

Si notre service REST est correctement utilisé, l’API Firebase effectue la synchronisation des données automatiquement, il suffit donc de mettre à jour sa base pour voir le résultat dans son application.
Ici, nous avons testé avec une application Ionic, affichée en direct via la commande « serve » ajoutée récemment aux outils de commande.

A bientôt sur les conférences ngEurope !

Alain Boudard

aboudard

2 oct
2014

JUG Montpellier sur Cassandra

Après la très bonne présentation sur Java 8 en juin par José Paumard, c’était la rentrée pour le JUG Montpellier avec Cassandra.

Nous avions pour présenter ce JUG Sylvain Lebresne de DataStax (la société qui est derrière Cassandra) et Alain Rodriguez de Teads qui gère cette solution depuis 3 ans avec des retours d’expérience très intéressantes.

Cassandra est un base de données distribuée.

C’est un projet Apache depuis 5 ans qui s’est inspiré de Dynamo ou encore de BigTable pour le modèle de données.

Les grands intérêts de cette solution sont :

- la possibilité de réaliser un scaling horizontal des données sur des machines à faible coût. Le principe est de préférer avoir de nombreux serveurs avec un bon 

rapport prix / puissance qu’un gros serveur très cher. Sachant qu’il y a des exemples d’anneau comprenant 1000 serveurs en parallèle,

- la possibilité de gérer de très gros volume de données,

- la disponibilité : on peut atteindre les 100% de disponibilité (upgrade sans arrêt du serveur, tolérance aux pannes, …) sans avoir une architecture hors de prix,

- un des principes de Cassandra est qu’il n’y a pas de serveur maître ou de hiérarchie de serveurs entraînant souvent des SPOF,

- le déploiement est possible assez facilement sur différentes régions géographiques,

- une haute performance notamment avec des écritures à faible coût.

Cela vient répondre aux limitations des bases relationnelles dans lesquelles il est difficile et très coûteux de scaler notamment liés aux limitations suivantes :

- les jointures ne permettent pas de bien scaler

- les contraintes ACID (très utiles pour les développeurs) ne permettent pas de bien scaler

- le design des bases relationnelles a été réalisé pour être mono-instance (cluster possible mais très coûteux et au final limité, le sharding des données est possible mais la gestion des pannes est délicate).

Le principe de la solution HD de Cassandra est que la réplication est réalisée de manière asynchrone sans maître.

Les données sont répliquées sur plusieurs serveurs (configuration possible du nombre de réplicas par le Replication Factor) garantissant ainsi un accès aux données même si un serveur est down (de manière voulu ou non).

Chaque donnée stockée possède un ID (hachage). Cet ID permet de localiser les données sur les différentes serveurs, chaque serveur gérant plusieurs plages de données connues par tous le serveurs.

Un des principes de Cassandra est de réaliser le travail pour faciliter la récupération des données à l’écriture, optimisant ainsi le travail de lecture « pré-maché ».

La soirée c’est poursuivie sur la présentation de CQL (Cassandra Query Language) et du Java driver.

CQL est un sous ensemble de SQL pour la dé-normalisation des données adapté pour la distribution des données et le cluster.

Le Java Driver permet de se connecter vers un base Cassandra avec une gestion automatique et transparente des noeuds (load balacing et fail-over automatique).

Et enfin quelques conseils utiles pour finir la soirée :

monitorer les logs, l’état up/down des serveurs, la latence du cluster, le heap du GC, l’espace disque disponible, …

- toujours avoir de la marge sur les serveurs et ne pas attendre qu’il n’y ait plus de ressources pour ajouter un nouveau serveur car cela serait contre productif à cause de la surcharge liée à l’ajout d’un nouveau serveur sur l’anneau (copie des données sur le nouveau serveur)

- réaliser les opérations de maintenance lorsque la charge est faible

- tester les upgrade avant et ne pas faire d’upgrade si l’anneau est instable

- regarder les anti-patterns : http://www.datastax.com/documentation/cassandra/1.2/cassandra/architecture/architecturePlanningAntiPatterns_c.html 

Donc voilà encore un soirée du JUG très instructive …

Emmanuel Pavaux

epavaux

29 sept
2014

DroidCon 2014 – Death to passwords

Encore une conférence à laquelle nous avons assisté à OXiane lors de ce droidcon 2014.
L’enjeu ici : parler de sa stratégie d’authentification au sein d’une application mobile. Pas de notion précise de sécurité applicative mais surtout un talk autour de trois notions :

  • Approche de sécurité développeur / utilisateur
  • Expérience utilisateur (UX le mot à la mode depuis 2 ans)
  • Différences entre authentification et autorisations

Sécurité

Tout d’abord, quelques réflexions générales de sécurité : 91% des gens ont un des 1000 mots de passe les plus répandus.
Ce qui ouvre pas mal de possibilités aux hackers, avec en tête les derniers piratages de masses de comptes consultables sur le site https://haveibeenpwned.com/. Quel type de mot de passe choisir, le mieux serait un mélange de mots aléatoire, en évitant les remplacements évidents, comme un 3 pour un E.
Ajoutons un autre site : heartbleed

Expérience utilisateur

De ce côté, une pratique répandue, en particulier quand on saisit une clé wi-fi, laisser l’utilisateur voir le mot qu’il tape, particulièrement utile pour de longs mots de passe. En commun, savoir afficher le niveau de sécurité approximatif est un plus.
En fonction de la popularité de son application, il peut être bon de donner accès à celle-ci avant de restreindre l’accès par login, il sera décevant de ne rien voir d’une appli inconnue, surtout si le seul login proposé est lié à un compte social type facebook.

Le développement

Que faire des informations reçues ? Le stockage est essentiel pour assurer une connexion aux services transparente, mais quelle stratégie adopter ?
Stocker le mot de passe sur le device : utiliser sqlcypher pour Android, un moyen simple. On peut citer également l’utilisation d’un librairie pour sécuriser les Préférences, ainsi que l’utilisation encore assez peu répandue de l’API Android KeyChain.

Les alternatives aux passwords

Que faire pour offrir une authentification simple dans son app :

  • Le combo email/password, un lien généré et un token de sécurité valable « un certain temps » !
  • La techno oAuth2, qui apporte un confort de développement important par rapport à la version 1, et que l’on peut utiliser avec une librairie comme Scribe, qui simplifie beaucoup les appels et la gestion des requêtes.
  • La stratégie de plus en plus répandue : un ou plusieurs réseaux sociaux. Après la mort de OpenID en 2012 suite à un hack, il n’y a pas vraiment aujourd’hui de standard, mais les plus grand réseaux offrent leurs API simplement : Google+, Facebook, Twitter, Yahoo et autres.

Note :
Pour l’authentification au sein de son application, la génération des clés est l’étape la plus simple. En revanche, être capable de réaliser les requêtes correctement peut vite devenir un casse tête, surtout si on veut offrir le choix de 3 ou 4 réseaux sociaux. Pour simplifier ces appels, nous utilisons, aussi bien en natif qu’en hybride, les librairies FireBase pour Android. Pour assurer un accès sécurisé aux données qu’ils hébergent dans le cloud et exposent en REST, ils ont inclut tout le nécessaire pour faciliter l’authentification sur ces grands réseaux.

Au final un talk intéressant de Tim Messerschmidt sur un sujet qui continuera à prendre de l’importance avec la montée en puissance des services « cloud ».

Alain Boudard

aboudard

24 sept
2014

Droidcon 2014 – Android Wear

Une superbe conférence de Mario Viviani, simple et efficace pour comprendre rapidement comment utiliser l’API Wear de Google.
Lorsqu’on veut faire communiquer un smartphone et un « wearable », c’est à dire une montre, un bandeau de mesure du pouls etc, il y’a deux classes essentielles:

DataItem

Comme son nom l’indique, cette classe peut contenir des données (jusqu’à 100kb)et fonctionne sur le principe très simple de la réplication. On crée un objet sur le smartphone et il se synchronise sur le wearable. Le tout avec un simple listener, qui permet de savoir quand le nouveau contenu est disponible.
En quelques lignes…
Il faut tout d’abord initialiser le GoogleApiClient, qui va se connecter à Google Services pour faire la connexion:

mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

Il est important de bien faire attention à appeler mGoogleApiClient.start() et mGoogleApiClient.stop() dans les méthodes onStart() et onStop() de nos contextes.

Puis, d’écrire, côté émetteur:

    //On crée une requête basée sur un path et une valeur
    PutDataMapRequest dataMap = PutDataMapRequest.create("/count");
    dataMap.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest request = dataMap.asPutDataRequest();
    // On indique à l'API Wear que notre DataItem que l'on a wrappé
    // dans une PutDataMapRequest est prêt à être synchronisé
    PendingResult<DataApi.DataItemResult> pendingResult =
        Wearable.DataApi.putDataItem(mGoogleApiClient, request);

Côté récepteur:

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    //On écoute simplement les événements "onDataChanged"
    for (DataEvent event : dataEvents) {
        //selon le type d'événement reçu, on traite
        if (event.getType() == DataEvent.TYPE_DELETED) {
            Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
        } else if (event.getType() == DataEvent.TYPE_CHANGED) {
             Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
        }
    }
}

Les Messages

De la même façon, pour envoyer un message, on a besoin d’initialiser le GoogleApiClient. Généralement, on veut envoyer le message à une Node, c’est à dire un wearable. Pour récupérer la liste des objets connectés, on peut appeler cette méthode utilitaire:

private Collection<String> getNodes() {
    HashSet <String>results= new HashSet<String>();
    NodeApi.GetConnectedNodesResult nodes =
        Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
    for (Node node : nodes.getNodes()) {
        results.add(node.getId());
    }
    return results;
}

Puis il suffit d’envoyer le message!

...
byte[] message = new String("Hello Oxiane!").getBytes();

SendMessageResult result = Wearable.MessageApi
    .sendMessage(mGoogleApiClient, node, "path_defini_pour_mon_message", message).await();

if (!result.getStatus().isSuccess()) {
    Log.e(TAG, "ERROR: failed to send Message: " + result.getStatus());
}
...

Une petite précision pour compliqué ce qui semble un peu trop facile: la méthode sendMessage est synchrone! Elle ne retourne pas avant d’avoir envoyé le message.

Côté récepteur, on n’a plus qu’à implémenter la méthode onMessageReceived:

@Override
public void onMessageReceived(MessageEvent messageEvent) {
    if (messageEvent.getPath().equals("path_defini_pour_mon_message")) {
       //j'ai reçu mon message!
    }
}

Pour terminer, Mario nous a présenté une petite librairie de sa conception qui facilite encore plus l’utilisation de l’API wear. Sans avoir pu la tester moi-même,

Johann Hilbold

jhilbold