vendredi 24 août 2012
Clarification sur le Datawarehousing
mardi 26 juin 2012
Exercice 1.C
- definitions :<definitions>- namespaces- types <wsdl:types><xsd:schema xmlns>
data type definition : décrits les types des paramètres impliqués dans le message
</xsd:schema></wsdl:types> - on définit le message : <wdsl:message>
xsd décrivant la forme du message (data contract). Un peu comme les paramètres d'une fonction
</wsdl:message> - On décrit un porttype :
<portType>
décrit les opérations et les message impliqués
</portType> - Binding : on associe le message à un port type comme opération (le porttype sera utilisé dans le binding)
<binding>
protocoles et format de données
</binding>
</definitions>
- One-way : pas de réponse attendue (uniquement input est défini
- Request-response : web request classique (stateless) : input / output
- Solicit-response : l'appli va attendre la réponse (statefull?)
- Notification : le serveur envoie un message mais n'attend pas de réponse
- name : nom du binding
- type : pointe sur le port (une instance de porttype)
- style : rpc/document
- transport : HTTP (mais pourrait-être autre chose : JMS)
- binding qui indique au client comment invoker l'opération
- service qui dit au client où la trouver (le binding sera utilise dans le port du service)
mvn archetype:create -DarchetypeGroupId=org.springframework.ws -DarchetypeArtifactID=spring-ws-archetype -DarchetypeVersion=1.5.9 -DgroupId=be.sdlg.ws -DartifactId=anovaWS On obtien un répertoire src/main/webapp
Web services en Spring WS 3
Spring WS repose JAX-WS car X-Fire et JAX RPC sont devenus obsoletes
Utiliser Spring service exporter (Web Service Last Contract) : Spring va construire le WSDL après que le service ai été défini.
Construire un Web service last contract avec Spring 3
Il faut utiliser le bean SimpleJaxWsServiceExporter
@WebService (serviceName="AnnovaService")
public class AnovaServiceEndPoint extends SpringBeanAutowiringSupport {
@Autowired
AnovaService anovaService;
@WebMethod
public AnovaTable getAnova(List
return anovaService.getAnova(response, regressor);
}
}
Dans le fichier sybil-servlet.xml
<bean class="org.springframework.remonting.jaxws.SimpleJaxWsExporter" p:baseAddress="http://localhost:8888/service/" / >
Ce bean publie automatiquement les pojo contenant l'annotation @WebService
l'adresse de base est /localhost:8080/AnovaService
Consommation de web service par les clients:
ProxyBeanFactory => crée un objet client à partir du WSDL
(La partie message du WSDL décrit les types de données, les types complexes sont défnis via des types xsd: simples)
(Le portType décrit les différentes opérations supportées)
=> Le proxy bean crée par le ProxyBeanFactory va simplement invoker les méthodes sur le serveur distant, comme les types de données sont connus, il est tout à fait possible pour le ProxyBean de recréer les classes correspondantes...
Toutefois, si l'on définit un classe de type AnovaTable, il serait tout de même bon d'avoir sa définition complète côté client pour pouvoir utiliser ce type de données ailleurs dans l'appli...
Là il est possible d'utiliser JDom ou mieux JAXB pour populer ces classes.
Sécuriser les accès au Web service:
utiliser JaaS (Java authentication & authorization Service) : (à mettre à jour)
vendredi 22 juin 2012
Rappels sur XSD
Rappel de XML (Extended Markup Language):
XML Base de données Programmation Orienté Objet
Xml Schema Table Structure Class
Xml Document Table Data Instance (Object)
Un schéma ou fichier .xsd permet de définir la structure du contenu d'un document XML. Il existe différentes approches: DTD (Document Type definition), XSD, XDR
DTD: compliqué et pas basé sur XML
XDR: propriété de Microsoft (on oublie)
XSD : relativement répandu et sera notre choix:
caractéristiques:
- xml based
- support inheritance
- ability to define its own type (Complex-type)
- specify data types for element & attributes
1) Schema : Pour pouvoir utiliser un document pour valider d'autre document il faut qu'il soit lui même validé !
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
Notre document devra donc suivre la structure et les types décrits dans www.w3.org/2001/XMLSchema
2) Element: spécifie le type d'informations
argument :
@name : nom de l'info ex: name="RESPONSE"
@type : refère à un type simple ou complexe
@minoccurs : par défaut 0 mais peut forcer 1 ou n occurrence de l'élément pour que le doc xml soit valide
@maxoccurs : nombre d'occurence max, pour dire que c'est indéfini ou utilise maxoccurs="unbound"
@ref : allows to refer an element defined in an othr xsd don't forget
3) Complex Type
ATTENTION les simpleType ou complexType peuvent être globaux ou locaux.
Element containing other child elements or attributes
spécifie l'ordre dans lequel doivent se suivrent les éléments apparaissant dans le doc XML. Si l'ordre n'est pas respecté le validateur va gueuler.
<xsd:sequence>
</xsd:sequence>
spécifie l'ordre dans lequel doivent se suivrent les éléments apparaissant dans le doc XML. Si l'ordre n'est pas respecté le validateur va gueuler.
<xsd:complexType>
<xsd:extension base="xsd:Employee"> <!-- permet de faire un véritable héritage d'élement -->
</xsd:complexType>
4) Simple Type
User Defined type: crée à partir d'un type de base:
Principaux types de base (primitve types) supporté par XSD
- xsd:string
- xsd:int
- xsd:date
- xsd:datetime
- xsd:boolean
- xsd:float
- xsd:double
Il est possible de créer un "simple type" sur base d'un type primitif et de lui ajouter des restrictions (ex: valeur interdites via une regexp)
<xsd:simpleType name="ssnumber"> <xsd:restriction base="xsd:string"> <!-- hérite de xsd:string--> <xsd:length value="11" /> <xsd:pattern value="\d{3}\-\d{2}-\d{4} /< <!-- securité sociale --> </xsd:restriction> </xsd:simpleType>ou
<xsd:simpleType name="emp-type"< >xsd:restriction base="xsd:string"> <!-- hérite de xsd:string--< <xsd:enumeration value = "fulltime"/> <xsd:enumeration value = "parttime"/> </xsd:restriction> </xsd:simpleType> En XSD on appelle les différentes restrictions: "enumeration, length, pattern" sur un type de base, des "Facets"
5) Documenter un schéma:
<xsd:annotation> <xsd:documentation> <!-- donne des infos sur les fonctionalités pour lesquelles les éléments sont définis --> </xsd:documentation> <xsd:appInfo> <!-- donne des infos sur l'application qui utilise les éléments--> </xsd:appInfo> </xsd:annotation>
- valider un document XML par rapport à son xsd
- concevoir directement des classes java à partir d'un xsd
jeudi 31 mai 2012
Exercice de statistiques combinant Spring3.1, R et ExtJS 4.
- Créer une DB simple avec 4 tables:
- Sujet
- ItemGroup
- Variables
- Instances
Créer 3 variables qui représente les résultats d'un test de mesure d'une appli web dans différents environnements:
- Temps de réponse [s]
- Environnement {A = Server 2003 + Sql Server 2005 + App V1,
B = Server 2008 + Sql Server 2008 + App V2,
C = Server 2008 + Sql Server 2008 + App V1}
- Concurrent users : [#]
Ces variables peuvent être chargées manuellement dans la DB.
A) Créer une application ExtJS 4 MVC
A.1) Stocker ces variables au format json
A.2) Afficher une grid permettant d'éditer (CRUD) les résultats pour les différentes variables par sujet. Les sujets ici, étant les tests effectués.
A.3) Afficher un écran permettant de sélectionner les variables à analyser au moyen de drag & drop.
B) Implémenter les fonctionalités CRUD pour connecter la grid ExtJS à la base de donnée en utilisant Spring MVC REST.
B.1) Utiliser Hibernate pour connecter le modèle (Sujet, ItemGroup, Variables, Instances) à la DB.
B.2) Utiliser JBoss comme server d'application
B.4) implémenter une fonctionalité d'analyse ANCOVA dans un service en utilisant R.
B.5) Sortir les résultats de l'analyse dans une page web en appelant le service
B.6) sortir les graphes de diagnostic (toujours au moyen du service) :
- normalité des résidus
- leverage (ou distance de Cook)
C) Créer et exposer un WS Service utilisant le service développé pour MVC
Utiliser JRI & R
samedi 31 mars 2012
Un peu de REST
Ce billet est une très brève introduction à la technologie REST et sera complété ultérieurement.
Depuis plusieurs années déjà les WebServices sont à la mode, pour rappel simpliste, un web service est en général une unité de code exposée au monde extérieur. La manière d'utiliser et de communiquer avec cette unité de code est décrite par une enveloppe SOAP (Simple Object Access Protocol). L'enveloppe SOAP décrit un contrat contenant les end-points (ou point d'accès), ainsi que le format des messages pouvant être transférés.
Les web services mettent l'accent sur le process des données, en général on accède à une fonctionalité.
REST (REpresentational State Transfer) donne une autre approche, ici on ne s'intéresse pas aux résultats d'un processing sur les données mais aux données elle même. D'un certain point de vue cette approche est intéressante puisqu'elle rejoins la définition originale des URI
Une URI (Uniform Resource Indentifier) permet d'identifier une ressources
Elle peut être soit une URN (Uniform Resource Name) : ex hello.html ou une URL (Uniform Resource Locator) : http://www.domain.be/hello.html
En général la plupart des URI ne servent pas à identifier ou localiser une resources mais a effectuer des actions:
ex: http://www.sdlg.be/sibyl/updateStudyItem?studyId=123
Ici on désigne clairement une action à effectuer sur une ressource en l'occurrence une study.
En technologie REST l'url aurait plutôt cette forme
http://www.sdlg.be/sibyl/studies/123
Un verbe sera également utilisé : GET, POST, PUT, DELETE.
La représentation des données peut se faire de diverses manières : HTML, XML, JSON
Le framework Spring utilise l'annotation @PathVariable pour récupérer le paramètre 123
De plus pour retourner du json, il faudra modifier le HTTP-HEADER en utilisant un bean de type:
ContentNegotiatingViewResolver et en le paramétrant pour json. Il faudra aussi installer l'artefact:
MappingJacksonHttpMessageConverter pour convertir les objets en flux json.
En PERL, on peut faire cela assez facilement avec JSON::PP (pure perl) ou JSON::XS (compilé en natif) qui contient la fonction to_json qui transforme une map ou une list de map en flux json.
Une rêquete GET en REST pourrait donc renvoyer un flux json représentant l'étude 123.
PUT permettrait de faire juste le contraire renvoyé l'état de l'étude 123 du client vers le serveur.
Avec l'utilisation de plus en plus fréquente de framework javascript basé sur AJAX une approche REST peut avoir quelques avantages non négligeables.
On peut bien sûr aller plus loin, comme SOAP, REST est basé sur HTTP (à la différence de SOAP, il se focalise sur l'état des objets, les données), donc il est possible de créer des clients REST n'ayant rien à voir avec un browser classique.
Il faut aussi noter que REST est nettement moins lourd que SOAP à la mise en oeuvre, maintenant Spring WS fait déjà beaucouop pour nous quant à la mise en place de WebService.
jeudi 29 mars 2012
Cross Tab queries en Oracle 10
Je sais qu'Oracle 11 introduit la notion de Pivot table qui permette de créer des cross tab queris (affichage d'une réponse classée dans un tableau par valeur d'une variable catégorielle). Les adorateurs de SAS connaissent cela via la procedure PROC TABLE qui peut faire un tantinet plus qu'afficher un simple tableau, puisque l'on peut aussi calculer un test de Khi carré mais bon même si mon blog est dédié au stat là n'est pas le sujet du billet d'aujourd'hui.
Par contre les utilisateurs d'Oracle 10 ne peuvent pas bénéficier de cette avancée (bien fait...). Il faut donc trouver un palliatif.
Je prends un cas usuel, nous avons des sujets et ces sujets on différentes propriétés 3 en l'occurrences dans notre exemple. Chaque sujet possède une valeur par propriété. En gros j'ai deux tables, une table sujet et une table propriété.
Une jointure entre les tables nous donne le tableau suivant: V1 et V2 sont des variables numériques, V3 est une variable de type texte.
Sujets
Sujet DOB
1 15/01/2000
2 1/1/1992
Variables
Sujet Nom Valeur
1 V1 15
1 V2 2
1 V3 test
1 V1 17
1 V2 3
1 V3 subj2
La jointure des tables sujets - variables nous donnent ceci
Sujet DOB Nom Valeur
1 15/01/2000 V1 15
1 15/01/2000 V2 2
1 15/01/2000 V3 test
2 1/1/1992 V1 17
2 1/1/1992 V2 3
2 1/1/1992 V3 subj2
Cette approche n'est pas très commode et souffre même d'un certain gigantisme tabulatoire.
Une approche simplificatrice consiste à utiliser une combinaison judicieuse de MAX et de DECODE afin de produire un tableau de type
Sujet V1 V2 V3
1 15 2 test
2 17 3 subj2
Ce que permet le bout de SQL suivant:
select Sujet, MAX(DECODE(Nom, 'V1', VALEUR, NULL)) IV1,
MAX(DECODE(Nom, 'V2', Valeur, NULL)) IV2,
MAX(DECODE(Nom, 'V3', Valeur, NULL)) IV3
FROM Variables
group by Sujet
order by Sujet;
Explication rapide : le DECODE affiche
Select Sujet, DECODE(Nom, 'V1', VALEUR, NULL) IV1,
DECODE(Nom, 'V2', Valeur, NULL) IV2,
DECODE(Nom, 'V3', Valeur, NULL) IV3
FROM Variables
Nous donne un tableau constitué du sujet auquel on concatène chaque valeur de V1, V2, V3. si la variable vaut V1 et qu'elle a une valeur alors sa valeur est affichée, sinon on affiche NULL
Cela nous donne
Sujet V1 V2 V3
1 15 null null
1 null 2 null
1 null null test
2 17 null null
2 null 3 null
2 null null subj2
On remarque que par sujet on obtient une matrice diagonale. L'utilisation d'un regroupement sur MAX permet d'éliminer les valeurs nulles.
Vous remarquerez qu'Oracle a une drôle d'interprétation de la nullité. Nous savons en effet que null signifie que l'on ne connaît pas la valeur. Si Alain à un age de 30 ans et Philippe un age inconnu que vaut le MAX(Age) entre Alain et Philippe. La réponse est normalement je ne sais pas. Pour Oracle la réponse est Alain. C'est assez divinatoire (sans mauvais jeu de mot) comme approche mais ça marche pour notre exemple, nous ne nous en plaindrons donc pas !
dimanche 25 mars 2012
Maven 2
est équivallent à la procédure de build management (produire un logiciel à partir de ses sources en automatisant certaines tâches)
Il gère aussi les dépendances (external jar).
Nomenklatura
artefact: élément spécifique de la construction du projet (en général des jar) mais ça peut -être des war, des ear, ...
dépendance: c'est une dépendance du projet vers un artefact
snapshot : version du projet en cours de développement.
POM : Project Object Model : paradigme qui décrit le projet logiciel, ses dépendances et l'ordre des tâches à effectuer pour le produire. Basé sur XML (pom.xml) mais un peu plus simple qu'ANT.
Ils fonctionnent en réseau, peut télécharger des jar venant de répository connus et gère aussi les dépendances récursives.
Le fichier POM.xml contient les propriétés du projet parent, il est possible de redéfinir ces propriétés (héritage).
Convention de répertoire MAVEN
/src
/src/main
/src/main/java
/src/main/resources (images, fichiers, annexe, ...)
/src/main/webapp
/src/test
/src/test/java
/src/test/resources
/src/site : information relative au projet généré
/src/target : executables, jar, ...
Cycle de vie
compile
test
package (crée le jar dans target)
install
deploy
Ces opérations sont des opérations basiques de building, et fonctionnent sous forme de plugins que l'on peut ajouter dans le project object model. On est donc pas figé à ces seules étapes du cycle de vie.
Limitations
Certains artefacts ont des license agreement et ne sont donc pas directement résolvable par maven.
Ex: javax.naming.jndi
Référence
http://java.developpez.com/faq/maven/?page=terminologie
lundi 13 février 2012
Binary Tree in JavaScript
L'avantage étant qu'une recherche ne demande plus que n*log(n) plutôt que n*n...
// Simple Binary Tree
// This binary tree is containing a numeric value (or string)
// and is used to optimize search in list.
// Usage:
// tree = new BTree();
// tree.add(value);
//
// BTree.add() Method
// add a new value in the tree (if value is lesser than the current values a new child is created at the left,
// otherwise a new child is created at the right)
// INPUT: value : integer
// OUTPUT: true : if the value has been added (was not existing in the tree)
// false : value already exist in the Tree.
function BTreeNode (value, left, right) {
this._value=value;
this._left=left;
this._right=right;
}
function BTree() {
this.root=null;
this.add=function (value) {
var node;
if (this.root!=null) {
var lastNode=null;
lastNode=this.getNode(value, this.root);
if (lastNode._value==value)
return false; // if exist is not added
node=new BTreeNode(value, null, null);
if (value
if (node._right!=null)
return this.getNode(value, node._right);
else
return node;
}
}
this.getNode=function (value, node) {
if (node==null)
return null;
if (value
if (node._right!=null)
return this.getNode(value, node._right);
else
return node;
}
}
}
mardi 3 janvier 2012
Regexp en PERL
s'utilise avec les commandes suivantes:
m (match)
s (substitute) :/i (case insensitive)/g global
tr ou y (translation) /ex s/ba/ab/g ne marche pas par contre y/ba/ab/ lui fonctionne bien.
charactère spéciaux:
\s : space
\S : non space
\d : digit
\D : non digit
\w : word
Exemple : récupérer et supprimer le dernier espace dans une chaine de caracètre:
$str=~s/(\s+\S*$)//;
print $1;
Je recherche au moins un espacedans une chaine qui se termine par 0 ou 1 non espace.
Perl stocke le contenu de la paranthèse (\s+\S*$) dans la variable $1
Trim d'une chaine de caractère
$str=~s/^\s+//; # éliminie les espaces de débuts
$str=~s/\s+$//; # élimine les espaces de fins
Vérification d'une adresse mail (simple):
$str~=m/[a-zA-Z0-9-.]+\@[a-zA-Z0-9-.]+
Vérifier qu'une chaine de caractère contient un opérateur:
$str~=m/\*|\+|\/|\\|\(|\)|\s|\^|#|\||'|\"|=|!