C# – Soit 2 tableaux de n entiers chacun, trouvez une paire d’éléments issue des 2 tableaux {n1,n2} dont la somme se rapproche le plus d’une cible n.

Par défaut

Ce petit problème fort intéressant peut etre résolu de divers manières, mais j’ai voulu montrer comment on pouvait créer un dictionnaire en C# qui contient 2 clés, en utilisant les tuples.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace Exercises

{

	class Program

	{

		static void ClosestToTarget(int[] array1, int[] array2, int target)

		{

			int i,
			j = 0;

			var dictionary = new Dictionary < Tuple  ,
			int > ();

			int x = 0;

			int[, ] totals = new int[array1.Length, array2.Length];

			for (i = 0; i < array1.Length; i++)

			{

				for (j = 0; j < array2.Length; j++)

				{

					int total = array1[i] + array2[j];

					totals[i, j] = total;

					var key = new Tuple  (i, j);

					dictionary.Add(key, array1[i] + array2[j]);

				}

			}

			foreach(KeyValuePair < Tuple  , int > kvp in dictionary)

			{

				Console.WriteLine("Clé = {0},{1}", kvp.Key, kvp.Value);

			}

			var bestMatch = dictionary.OrderBy(e = >Math.Abs(e.Value - target)).FirstOrDefault();

			i = bestMatch.Key.Item1;

			j = bestMatch.Key.Item2;

			Console.WriteLine("Elément issu du premier tableau : {0} , Elément issu du deuxième tableau : {1}, La Somme = {2} qui se rapproche le plus de la cible : {3}", array1[i], array2[j], array1[i] + array2[j], target);

		}

		static void Main(string[] args)

		{

			Console.WriteLine("Ce programme prend en entré 2 tableau de taille n et vous donne quel pairs d'éléments des 2 tableaux se rapproche le plus d'une cible x");

			Console.WriteLine("Veuillez entrer la taille des tableaux:");

			int size = 0;

			while (!int.TryParse(Console.ReadLine(), out size))

			Console.Write("Attention, la valeur doit être un entier. Veuillez réessayer");

			int[] array1 = new int[size];

			int[] array2 = new int[size];

			int i;

			Console.WriteLine("Entrez les {0} chiffres pour le premier tableau:", size);

			for (i = 0; i < size; i++)

			{

				while (!int.TryParse(Console.ReadLine(), out array1[i]))

				Console.Write("Attention, la valeur doit être un entier. Veuillez réessayer");

			}

			Console.WriteLine("Entrez les {0} chiffres pour le deuxième tableau:", size);

			for (i = 0; i < size; i++)

			{

				while (!int.TryParse(Console.ReadLine(), out array2[i]))

				Console.Write("Attention, la valeur doit être un entier. Veuillez réessayer");

			}

			Console.WriteLine("Entrez la cible:");

			int target = Convert.ToInt32(Console.ReadLine());

			ClosestToTarget(array1, array2, target);

			Console.ReadLine();

		}

	}

}

https://dotnetfiddle.net/4cKdGc

Elastic Paris Meetup : Malt

Par défaut

Ce Mardi 22 Janvier 2019 se tenait dans les locaux de Malt à Paris, le 35ème meet-up du groupe ElasticFR, un groupe composé d’environ 2800 membres. C’est un groupe qui a pour vocation d’organiser des rencontres entre les passionnés francophones des projets Elastic (Elasticsearch, Logstash, Beats, and Kibana et leurs plugins).

 

IMAG1972

Déroulement de la soirée :

19h00 : ouverture des portes (food and drinks)
19h30 : accueil par Elastic et Malt
19h45 : Talk 1: Les différents cas d’usage d’Elasticsearch chez Malt
20h15 : Talk 2: Nouveautés de Lucene 8 et Elasticsearch 7
20h45 : Social discussions (food and drinks)
22h00 : fin du meetup

Talk 1: Les différents cas d’usage d’Elasticsearch chez Malt

Présentateur : Hugo Lassiège

Hugo Lassiège est CTO et co fondateur chez Malt. Il officie dans l’informatique depuis 18 ans principalement en tant qu’ingénieur en développement. Il apprécie discuter d’architecture technique ou d’organisation (qui n’est rien d’autre que de l’architecture sociale), de moteur de recherche, de science des données.

IMAG1946

Elasticsearch est utilisé depuis 2012 chez Malt. Cette première présentation avait pour but de montrer un apercu de son usage au sein du moteur public mais aussi sur certaines parties privées du site.

Pour ceux qui ne connaissent pas ElasticSearch, c’est un serveur utilisant Lucene pour l’indexation et la recherche des données. Elle fournit un moteur de recherche distribué et multi-entité à travers une interface REST. C’est un logiciel libre écrit en Java et publié en open source sous licence Apache. Au début Janvier 2019, elle était classé au 8ème rang selon le classement DB-Engines Ranking, en progression (+2) par rapport à Janvier 2018.

Ranking.png

Il existe plein d’informations  sur le net sur Elasticsearch et je vous invite à les lire.

Pour revenir au talk, Hugo Lassiège a aussi pris le temps d’expliquer le concept de scoring à travers les fonctions de gauss decay et functions script, de boost par proximité géographique mais aussi d’ontologie, d’analyseur multi langue ou de migration de mapping.

Bien qu’Elasticsearch offre un algorithme de scoring efficace, il peut souvent s’avérer insuffisant dans les contextes de commerce électronique. La plupart des utilisateurs ont tendance à se préoccuper uniquement du nombre de résultats le plus élevé. ce qui signifie qu’il est très important d’avoir un mécanisme de notation flexible. Si vous pouvez présenter les meilleurs résultats en fonction des préférences de l’utilisateur, votre taux de conversion augmentera probablement de manière significative.

Talk 2: Nouveautés de Lucene 8 et Elasticsearch 7

Présentateur : Jim Ferenczi

Jim Ferenczi est développeur dans l’équipe Elasticsearch. Il est également committeur sur le project Lucene.

IMAG1948

Il a ensuite abordé les nouveautés d’Elasticsearch7, abordant rapidement les changements sur les indices, et sur les analyses.

Il est aussi revenu sur le concept du scoring, notamment sur la formule BM25.

Il a donné plus de détails sur le fonctionnement, en expliquant les scoring factors, IDF(qi),tf(qi),Field length ( norm). Il a ensuite donné l’exemple du MaxScore ou comment ce scoring particulier pouvait permettre de rendre le scoring plus efficient. L’idée réside dans le fait de booster les disjonctions en évitant les documents non compétitifs. Il est aussi revenu sur la limitation du MaxScore, en expliquant que ce scoring dépend directement de la fréquence du terme dans tous les segments, et que celui pouvait changer lors de l’indexation de nouveaux documents. Il a aussi montré un exemple pratique du WAND ( Weak AND ).  Il a ensuite expliqué brièvement les autres optimizations, comme les Phrase queries, Synonym query, Boolean query.

Il a conclu en expliquant le Feature query, son intégration dans Elasticsearch 7 et comment ca pouvait améliorer significativement les performances.

Le Meet up s’est terminé avec la distribution de pizzas et de bières !

Docker – Les Conteneurs

Par défaut
  • Les Images vs Les Conteneurs
  • Démarrer, arreter, enlever les conteneurs
  • Vérifier les logs et les process des conteneurs

 

Les Images vs Les Conteneurs

Une image est l’application que nous voulons lancer.

Un conteneur est un processus qui est une instance de cette image.

On peut avoir plusieurs conteneurs qui tournent sous la meme image.

On va utiliser le serveur web Nginx comme image

Le registre par défaut de Docker est appelé le Docker Hub ( hub.docker.com). On peut considérer que les registres sont l’équivalent de Github, mais pas pour le code mais pour les images.

docker container run –publish 80:80 nginx

Explication

  1. Téléchargement de l’image ’nginx’ depuis DockerHub
  2. Démarre un nouveau conteneur depuis cette image
  3. Activation du port 80 sur le hote
  4. Dirige le traffic vers ce conteneur IP, port 80

On peut ensuite faire la commande suivante, qui va permettre au serveur Nginx de continuer de s’éxécuter mais dans l’arrière plan

docker container run –publish 80:80 –detach nginx

Si vous avez une erreur de ce type,

docker: Error response from daemon: driver failed programming external connectivity on endpoint infallible_hofstadter (0c100b5e21cc9f4db69491134180e23fa402a200c359c6a238842c516cded7d4): Error starting userland proxy: Bind for 0.0.0.0:80: unexpected error (Failure EADDRINUSE).

C’est du au fait que le port 80 est utilisé par un autre process, très certainement apache.

Vous pouvez essayer de lancer la commande suivante pour vérifier

sudo lsof -nP | grep LISTEN

Essayez de faire ca si vous n’utilisez pas Apache pour le moment

sudo apachectl stop

Ensuite relancez

docker container run –publish 80:80 –detach nginx

docker container ls

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                        NAMES

0989f8e7eadb        nginx               « nginx -g ‘daemon of… »   7 seconds ago       Up 6 seconds        80/tcp, 0.0.0.0:80->90/tcp   practical_keller

practical_keller est un nom choisi aléatoirement par Docker.

docker container run –publish 80:90 –detach –name TestDockerAjmal nginx

86902e9a10357286a0e27c89e8b7235f7f3353dbeb124763c70201cd89dcd847

docker container ls -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                        NAMES

86902e9a1035        nginx               « nginx -g ‘daemon of… »   54 seconds ago      Created                                          TestDockerAjmal

0989f8e7eadb        nginx               « nginx -g ‘daemon of… »   8 minutes ago       Up 8 minutes        80/tcp, 0.0.0.0:80->90/tcp   practical_keller

Up 8 minutes signifie que le conteneur a bien été lancé.

J’ai ensuite remarqué que Docker n’aime pas que les noms des conteneurs soient en majuscules. J’ai donc renommé le conteneur

docker container rename TestDockerAjmal test_docker_ajmal

sudo lsof -nP | grep LISTEN

Adobe\x20   589                  ajmal   32u     IPv4 0xd33f2473fd1896e9         0t0        TCP 127.0.0.1:15393 (LISTEN)

node        628                  ajmal   15u     IPv4 0xd33f2473fdda36e9         0t0        TCP 127.0.0.1:49270 (LISTEN)

node        628                  ajmal   21u     IPv4 0xd33f2473fdda23e9         0t0        TCP 127.0.0.1:49274 (LISTEN)

com.docke  1874                  ajmal   23u     IPv4 0xd33f2473f5a0a069         0t0        TCP *:80 (LISTEN)

Faites cette commande pour supprimer tout conteneur qui n’est pas démarré.

docker rm $(docker ps -a -q)  ou

docker container rm -f 896

Relancez la commande pour recréer le conteneur en spécifiant un port différent

docker container run –publish 90:90 –detach –name test_docker_ajmal nginx

Ajmals-MacBook-Pro:~ ajmal$ docker container ls -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                        NAMES

c87f189f8fb4        nginx               « nginx -g ‘daemon of… »   4 seconds ago       Up 3 seconds        80/tcp, 0.0.0.0:90->90/tcp   test_docker_ajmal

0989f8e7eadb        nginx               « nginx -g ‘daemon of… »   34 minutes ago      Up 34 minutes       80/tcp, 0.0.0.0:80->90/tcp   practical_keller

Les 2 conteneurs sont UP, c’est à dire qu’ils sont bien démarrés.

Pour stopper les conteneurs, faites ensuite

docker container stop practical_keller

docker container stop test_docker_ajmal

docker container ls -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES

c87f189f8fb4        nginx               « nginx -g ‘daemon of… »   23 minutes ago      Exited (0) 3 seconds ago                        test_docker_ajmal

0989f8e7eadb        nginx               « nginx -g ‘daemon of… »   About an hour ago   Exited (0) 31 seconds ago                       practical_keller

Les statuts ont changé à ’’Exited’’.

Rappel: Lancement d’un conteneur

  1. Recherche l’image localement dans l’Image Cache, s’il le trouve pas, etape 2
  2. Recherche l’image dans le repo image ( Docker Hub )
  3. Télecharge l’image et le sauvegarde
  4. Crée un nouveau conteneur basé sur cette image et le prépare au démarrage
  5. L’assigne un addresse IP virtuel sur le réseau privé à l’intérieur du moteur Docker
  6. Ouvre le port 80 sur l’hote et redirige vers le port 80 dans le conteneur
  7. Démarre le conteneur en utilisant le CMD dans l’image Dockerfile

Docker – Mise en route sur Mac

Par défaut

Docker est une plateforme permettant aux développeurs, et aux administrateurs système de développer, déployer et d’exécuter des applications avec des conteneurs. L’utilisation de conteneurs pour déployer des applications s’appelle la conteneurisation. Les conteneurs ne sont pas nouveaux, mais leur utilisation pour déployer facilement des applications l’est.

La conteneurisation est de plus en plus populaire car les conteneurs sont:

Flexible: Même les applications les plus complexes peuvent être conteneurisées.
Léger: les conteneurs exploitent et partagent le noyau hôte.
Interchangeable: vous pouvez déployer des mises à jour et des mises à niveau à la volée.
Portable: vous pouvez créer localement, déployer sur le cloud et exécuter n’importe où.
Évolutif: vous pouvez augmenter et distribuer automatiquement les réplicas de conteneur.
Empilable: Vous pouvez empiler des services verticalement et à la volée.

Dans ce petit tuto, on va voir comment mettre en place un environment de développement sur Mac pour commencer avec Docker

Il faut tout d’abord télécharger l’application qui se trouve à l’adresse suivante

https://www.docker.com/products/docker-desktop

Téléchargez la version pour Mac et l’installer ( la version CE ou Edge)

Une fois que c’est fait, vous devriez voir l’icone Docker comme ici.

Docker

 

Ouvrez un terminal en ligne de commande et essayez quelques commandes de Docker.

Exécutez

docker version

pour vérifier que la dernière version est installée.

Ensuite exécutez

docker hello-world

pour vérifier que Docker extrait les images et s’exécute comme prévu.

Docker requiert au moins Yosemite 10.10.3 ( 2014 )

Il n’est pas nécessaire d’avoir un mac très récent car Docker supporte Yosemite.

Idéalement il est bien sur nécessaire d’avoir un mac plus récent pour bénéficier des atouts de Docker Toolbox et aussi d’etre à l’aise avec la performance.

Il ne pas faut utiliser HomeBrew pour installer Docker, car en le faisant de cette facon, seules les utilitaires en lignes de commandes seront installés.

Docker pour Mac : les étapes de Installation

-Installez Docker ( l’étape précédente )

-Adaptez Docker en fonction des paramètres du Mac

-Récupérer un éditeur de code

-Adaptez le terminal

 

Installez Visual studio code pour Mac

https://code.visualstudio.com/docs/?dv=osx

Installez l’extension Docker sur Visual Studio Code

Screenshot 2018-12-06 at 11.09.25

Installez le bash-completion à l’aide de Homebrew ( ca permet de faire l’auto-complétion des commandes sur le terminal )

Pour bien vérifier que cela a été fait, vous devrez voir

Bash completion has been installed to:

  /usr/local/etc/bash_completion.d

==> Summary

Maintenant il faut lier le bash completion aux ressources suivantes

ln -s /Applications/Docker.app/Contents/Resources/etc/docker.bash-completion /usr/local/etc/bash_completion.d/docker

ln -s /Applications/Docker.app/Contents/Resources/etc/docker-machine.bash-completion /usr/local/etc/bash_completion.d/docker-machine

 ln -s /Applications/Docker.app/Contents/Resources/etc/docker-compose.bash-completion /usr/local/etc/bash_completion.d/docker-compose

Ensuite modifiez le bash profile

Dans le terminal faites

touch ~/.bash_profile

open ~/.bash_profile

Rajoutez ce bout de code

if [ -f $(brew –prefix)/etc/bash_completion ]; then
. $(brew –prefix)/etc/bash_completion
fi

Sauvegardez et relancer le terminal

Essayez

docker container run —

et appuyez 2 fois sur la tabulation

Vous devrez voir une liste de commandes qui s’affichent automatiquement. Si c’est ok, le bash completion est correctement configuré.

Vous etes donc pret pour commencer à utiliser Docker sur votre Mac !

 

Règlement européen sur la protection des données : Comment cette réglementation impact l’environment Big Data ?

Par défaut

Le jeudi 29 novembre 2019, je suis parti à un meet-up organisé par Matem, une SSII basé à Neuilly sur Seine. Le thème du meetup était le suivant « RGPD : Comment cette réglementation impact l’environment Big Data ?« 

Ce fut une occasion pour moi d’en apprendre un peu plus sur cette législation qui impact  tous les sociétés qui gèrent le traitement des données et de leur conservation, transmission et transformation. Les intervenants furent

Abdesatar Hammedi : Practice Manager BI et Big Data chez Matem

Sébastien Oueslati : Directeur adjoint du pole sécurité chez Humanis

Javier Franco Contreras : Président de Watoo

Je vais me concentrer sur les 2 premières interventions dans ce post.

Meetup RGPD

Arrivée dans les locaux : Le meet-up a débuté vers 19.30

imag1469

 

L’Agenda : 

Pourquoi gouverner les données ? – L’impact du Big Data et du cloud

Programme de mise en conformité – Quand et de quel manière traiter la problématique et les difficultés rencontrées

Présentation des solutions – Axé sur le tatouage numérique

 

1ère partie : Pourquoi gouverner les données ? – L’impact du Big Data et du cloud

imag1470

Présentation par Abdesatar Hammedi

Pourquoi gouverner les données ?

Avec la transformation numérique, notamment avec la collecte d’informations de divers sources que sont les mobiles, les équipements connectés entre autres, il est devenu indispensable de penser à la mise en place d’une gouvernance des données.

Le data est devenu indispensable pour beaucoup d’entreprises, d’organismes et de gouvernements. La collecte de données privés entrainent des conséquences dans la manière dont le partage de ces données se fait.

imag1472

Pourquoi gouverner les données ?

La valorisation du patrimoine data entraine des usages qui doivent respecter un périmètre bien défini sur les points suivants
Partage des données
Sémantique
Propriété
Confidentialité
Accès
Sécurité
Evolution

imag1473

On a ensuite eu un rappel sur les grands principes du RGPD, notamment sur les fondements que sont

La loi de 1978

La Directive 95 – 86 europe

imag1474

L’importance des acteurs participant dans la gouvernance fut décrit, aussi bien les acteurs internes qu’externes à l’entreprise. Le Chief Data Officer a un role essentiel à jouer dans ce registre.

 

imag1476

Une liste d’étapes pour se préparer à la GDPR fut décrit, comme un rappel aux entreprises qui ne sont pas encore en conformité

Désigner, Cartographier, Prioriser, Gérer, Organiser, Documenter

Le bilan après 6 mois fut discuté notamment avec des chiffres sur le nombre de controles et de violations notifiés à la CNIL.

imag1479

 

imag1481

Centralisation des données – une stratégie ?

Avec la diversité de sources, une stratégie de centralisation peut etre une solution.

Recuperation des données de l’application référentiel, des applications métiers et des sources externes. Passer par une étape de Data Ingestion. Ensuite récupérer les données brutes ’’Le Raw Data’’. Viennent ensuite les étapes de normalisation et d’optimisation de ces données.

imag1483

Avoir une SI Data Centric est aussi essentielle dans la mise en oeuvre de cette réglementation, qui englobe les domaines suivants

L’organisation

Roles, les responsibilités, les socles logiciels et données, usages projets.

Pratiques

Architecture, développements, tests

Pratiques d’exploitation ( multi-usage, multi-tenant,DevOps,sauvegardes..)

Gouvernance

Données ( connaissance, cycle de vie, accès, qualité )

Socle ( cycle de vie initier-construire-run, financer, Roadmap )

Usages ( connaissances, réutilisation,évolutions..)

Conformité et règles éthiques

Sécurité

Accès à la donnée, habilitations, usages

Anonymisation, archivage

Technologies

Compétences logiciels ’’Big Data’’

Pratiques de conception-dev associées

Infrastructures

Architecture

Architecture fonctionnelle SI

imag1484

Le thème de la gouvernance des données fut discuté en peu plus en profondeur, notamment sur les nouveaux savoir-faire et process au niveau SI, les usages et la maitrise de l’information.

imag1485imag1487

La plateforme de conformité, une architecture conceptuelle

imag1489

 

2ème partie : Programme de mise en conformité – Quand et de quel manière traiter la problématique et les difficultés rencontrées

Présentation par Sébastien Oueslati

Cette deuxième partie fut consacré à un retour d’expérience sur la mise en place du RGPD, au sein du groupe Humanis.

Le contexte fut décrit, notamment sur les métiers du groupe et ses filiales

imag1492

 

 

imag1494

 

imag1495

Un inventaire des données sensibles traités par l’entreprise fut présenté, notamment

Le NIR, l’appartenance syndicale, les données de santé, les données de sécurité, les données relative aux effractions et condamnations pénales et mesure de sureté, conditions de ressources financières ou matérielles, les données relatives aux difficultés sociales des personnes, les données d’identification, les situations de famille et statut, le dossier professionnel, les données relatives aux recrutement et les dossiers d’embauche, la géolocalisation, les données de badgeage, les enregistrements des conversations téléphoniques, correspondances privés.

imag1496

La Démarche

imag1502

Les résultats obtenus et une définition des prioritées

imag1504

 

Le programme : De quel manière il a été traité ?

imag1505

 

Le programme : ses thématiques

Les droits des personnes, notamment la gestion du consentement, la gestion des cookies sur les sites et applications, la revue des mentions d’informations

imag1508

 

 

imag1509

La responsabilité des acteurs ( Accountability )

imag1510

 

Le programme et les difficultés rencontrésimag1511

Le cas du consentement des données de santé

imag1513

Comment concilier RGPD et Big Data ?

imag1514

Conclusion

Assez simple…celles qui étaient conformes aux lois informatique et libertés de 1978 et celles qui ne l’ètaient pas.

Dans le premier cas, le RGPD est une évolution réglementaire et dans le deuxième cas, c’est une révolution !

imag1515

 

Expérience personnelle de la mise en place du RGPD

J’ai eu à participer activement dans la mise d’une partie de cette réglementation au sein du groupe Fnac Darty. J’ai participé à l’évolutions d’une solution web pour la prise en compte de la gestion et du cryptage des mots de passes, la réinitialisation et la récupération du mot de passe et les techniques de blocage et de vérrouillages des comptes.

React – Installation et mise en route rapide

Par défaut

React est un framework très en vogue en ce moment.

Sur internet on peut trouver des tutoriels sur l’installation de ce framework mais beaucoup sont déjà obsoletes à l’heure du publication de ce blog. En effet, au lieu d’utiliser webpack et avoir des soucis de dépendances liés aux différents packages, on peut facilement installer ce framework en suivant juste les étapes suivantes. Il faut avoir préalablement installés node et npm. Les dernières version sont recommandés.

Dans votre repertoire de travail, faites

npm install -g create-react-app

Une fois terminée, faites

create-react-app monapplireact

Si vous avez le message Success, alors l’installation s’est correctement passé !

npm va vous conseiller de lancer l’appli en utilisant les commandes suivantes

cd monapplireact

npm start

Screen Shot 2018-04-19 at 01.15.32

Le navigateur va se lancer automatiquement

Screen Shot 2018-04-19 at 01.16.16

Voila, vous pouvez commencer à coder ! Avec un éditeur comme Atom, ajouter le repertoire du projet .

Screen Shot 2018-04-19 at 01.21.18

 

Normes ISO 20022 : Génération d’un XML avec C# en suivant le schéma xsd pain.001.001.03 , « Customer Credit Transfer Initiation »

Par défaut

La norme ISO 20022 une norme ISO régissant l’échange de données informatisé entre les institutions financières. Standard international et ouvert, ISO 20022 n’est pas contrôlé par un seul intérêt: il peut être utilisé par n’importe qui dans l’industrie et implémenté sur n’importe quel réseau. Il a des processus entièrement établis pour sa maintenance, son évolution et sa gouvernance.

Première publication en 2004, l’ISO 20022 est largement reconnue comme la norme du futur. En plus d’être assez flexible pour travailler avec les dernières technologies,
ISO 20022 peut également s’adapter aux nouvelles technologies à mesure qu’elles emergent.

La norme ISO 20022 est décrite dans le document «ISO 20022 Financial Services – Système de messages de l’industrie financière universelle».

L’édition actuelle de la norme comprend huit parties, publiées en mai 2013:

ISO 20022-1: Métamodèle
ISO 20022-2: profil UML
ISO 20022-3: Modélisation
ISO 20022-4: Génération de schémas XML
ISO 20022-5: Ingénierie inverse
ISO 20022-6: Caractéristiques de transport des messages
ISO 20022-7: Enregistrement
ISO 20022-8: génération ASN.1
Les commandes d’ISO 20022 et d’autres normes internationales ou publications ISO peuvent être obtenues sur http://www.iso.org. Dans la zone Rechercher, tapez 20022, puis Rechercher. Les huit parties de la norme sont disponibles à l’achat en format PDF ou papier

Dans l’example qui va suivre, nous allons voir comment générer un XML sur C# en utilisant plus spécifiquement le message « Customer Credit Transfer Initiation » : pain.001.001.03

Je vous invite à consulter le lien ci dessous de la CFONB ( Comité Francais d’Organisation et de Normalisation Bancaire ) pour avoir plus de details sur le virement SEPA (Single Euro Payments Area ) et les instructions de paiements.

http://www.cfonb.org/Default.aspx?lid=1&rid=122&rvid=144

Pour commencer, prenons l’example ci-dessous.

Nous avons une table Emetteur avec les informations suivantes.

em

Nous avons aussi une table Recepteur qui a  la meme structure que la table Emetteur.

re

Les données à partir de ces 2 tables peuvent etre assignees dans une DataTable à partir de la requete sql suivante.

Emeteur.

select Libelle_Emetteur,BIC_Emetteur_IBAN_Emetteur from Emetteur

Recepteur

select Libelle_Recepteur,BIC_Recepteur,IBAN_Recepteur from Recepteur

La generation du XML

public void WriteXML()
{

DateTime DateXml = Global.GetImportDate.AddDays(1);

string namespace_xml = "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03";
xmlDoc.InsertBefore(xmlDoc.CreateProcessingInstruction("xml", "version='1.0' encoding='UTF-8'"), xmlDoc.ChildNodes.Item(0));
XmlNode objXMLRootelement = xmlDoc.CreateNode(XmlNodeType.Element, "Document", namespace_xml);
xmlDoc.AppendChild(objXMLRootelement);

XmlAttribute attribute = xmlDoc.CreateAttribute("xsi:schemaLocation");
attribute.Value = @"urn:iso:std:iso:20022:tech:xsd:pain.001.001.03\\REPERTOIRE OU SE TROUVE LE SCHEMA\pain.001.001.03.xsd";
objXMLRootelement.Attributes.Append(attribute);
XmlAttribute attribute_1 = xmlDoc.CreateAttribute("xmlns:xsi");
attribute_1.Value = "http://www.w3.org/2001/XMLSchema-instance";
objXMLRootelement.Attributes.Append(attribute_1);

XmlAttribute attribute_2 = xmlDoc.CreateAttribute("xmlns:xsd");
attribute_2.Value = "http://www.w3.org/2001/XMLSchema";
objXMLRootelement.Attributes.Append(attribute_2);
XmlNode objXMLelement = xmlDoc.CreateNode(XmlNodeType.Element, "CstmrCdtTrfInitn", namespace_xml);
objXMLRootelement.AppendChild(objXMLelement);

//#####################################
//#           En Tête                 #
//#####################################

 

CreateNode("GrpHdr", namespace_xml, "CstmrCdtTrfInitn");

CreateNode("MsgId", namespace_xml, "GrpHdr", RandomString(3) + "/" + RandomString(2) + "/" + RandomInt(8));
CreateNode("CreDtTm", namespace_xml, "GrpHdr", DateXml.ToString("yyyy-MM-ddThh:mm:ss"));

CreateNode("NbOfTxs", namespace_xml, "GrpHdr", "1");
// Le montant du virement
CreateNode("CtrlSum", namespace_xml, "GrpHdr", MontantVirement());

CreateNode("InitgPty", namespace_xml, "GrpHdr");

CreateNode("Nm", namespace_xml, "InitgPty", "XXXXX");

//#####################################
//#           LOT Banque               #
//#####################################

CreateNode("PmtInf", namespace_xml, "CstmrCdtTrfInitn");

CreateNode("PmtInfId", namespace_xml, "PmtInf", "0000001");

CreateNode("PmtMtd", namespace_xml, "PmtInf", "TRF");

CreateNode("NbOfTxs", namespace_xml, "PmtInf", "1");

CreateNode("CtrlSum", namespace_xml, "PmtInf", MontantVirement());

CreateNode("PmtTpInf", namespace_xml, "PmtInf");

CreateNode("SvcLvl", namespace_xml, "PmtTpInf");

CreateNode("PmtTpInf", namespace_xml, "PmtInf");

CreateNode("Cd", namespace_xml, "SvcLvl", "SEPA");

CreateNode("ReqdExctnDt", namespace_xml, "PmtInf", DateXml.ToString("yyyy-MM-dd"));

CreateNode("Dbtr", namespace_xml, "PmtInf");
// GetDataTableEmetteur est une methode qui retourne un DataTable
// Le libelle_Emetteur dans la Table Emetteur
CreateNode("Nm", namespace_xml, "Dbtr", GetDataTableEmetteur.Rows[0].ItemArray[0].ToString());

CreateNode("DbtrAcct", namespace_xml, "PmtInf");

CreateNode("Id", namespace_xml, "DbtrAcct");
//Le IBAN_Emetteur dans la Table Emetteur
CreateNode("IBAN", namespace_xml, "Id", GetDataTableEmetteur.Rows[0].ItemArray[2].ToString());

CreateNode("DbtrAgt", namespace_xml, "PmtInf");

CreateNode("FinInstnId", namespace_xml, "DbtrAgt");
//Le BIC  dans la Table Emetteur
CreateNode("BIC", namespace_xml, "FinInstnId", GetDataTableEmetteur.Rows[0].ItemArray[1].ToString());

CreateNode("ChrgBr", namespace_xml, "PmtInf", "SLEV");

//#####################################
//#           Lot Transaction         #
//#####################################

CreateNode("CdtTrfTxInf", namespace_xml, "PmtInf");

CreateNode("PmtId", namespace_xml, "CdtTrfTxInf");

CreateNode("InstrId", namespace_xml, "PmtId", "XXXXXX-1");

CreateNode("EndToEndId", namespace_xml, "PmtId", "XX000");

CreateNode("Amt", namespace_xml, "CdtTrfTxInf");

CreateNode("InstdAmt", namespace_xml, "Amt", MontantVirement(), "Ccy=EUR");

CreateNode("Cdtr", namespace_xml, "CdtTrfTxInf");
//GetDataTableRecepteur est une méthode qui retourne une DataTable
CreateNode("Nm", namespace_xml, "Cdtr", GetDataTableRecepteur.Rows[0].ItemArray[0].ToString());

CreateNode("CdtrAcct", namespace_xml, "CdtTrfTxInf");

CreateNode("Id", namespace_xml, "CdtrAcct");
//
CreateNode("IBAN", namespace_xml, "Id", GetDataTableRecepteur.Rows[0].ItemArray[2].ToString(), "", 1);

CreateNode("RmtInf", namespace_xml, "CdtTrfTxInf");

CreateNode("Ustrd", namespace_xml, "RmtInf", "XXXXXXXXXXXXXXX XX" + GetDataTableEmetteur.Rows[0].ItemArray[2].ToString() + " COM " + Global.GetImportDate.ToString("MM/yyyy") + GetDataTableEmetteur.Rows[0].ItemArray[0].ToString());

string targetPath = @"\DOSSIER_SORTIES\" + Global.GetImportDate.ToString("yyyy MM dd");
// Creation d'un dossier pour sauvegarder le XML
if (!System.IO.Directory.Exists(targetPath))
{
System.IO.Directory.CreateDirectory(targetPath);
}

xmlDoc.Save(targetPath + "\\DOSSIER_XML" + Global.GetImportDate.ToString("yyyyMM") + "_1.xml");

}