%JM_START% %JM_LAUNCH% %JVM_ARGS% %ARGS%
-jar "%JMETER_BIN%ApacheJMeter.jar"
%JMETER_CMD_LINE_ARGS% -H hostname -P 80
mardi 19 février 2008
Utiliser JMeter à travers un proxy
Dans le fichier jmeter.bat ajouter à la ligne de commande les paramètre -H et -P pour l'hôte et le port de proxy.
Tester un Web Service à l'aide de JMeter
Pour tester un Web service à l'aide de JMeter. Il est possible de se servir soit d'un appel SOAP (C'est à dire que la couche d'abstraction Web Service n'est pas utilisée) soit d'utiliser les service en version Beta de test d'un Service Web
Ce post décrit la méthode utilisant un type SOAP
Dans le scénario ajouter un échantillon de Requete SOAP/XML-RPC pour ne pas
Le corps du message est le suivant, il peut être récupéré en mode debug dans une IDE. Il s'agit du SOAPEnvelope du requestMessage du Message envoyé dans le call. Mis le plus simple consite à utiliser le moniteur de AXIS pour voir la requête qui est envoyée.
Le SOAP Enveloppe ressemble à ceci.
Ce post décrit la méthode utilisant un type SOAP
Dans le scénario ajouter un échantillon de Requete SOAP/XML-RPC pour ne pas
Le corps du message est le suivant, il peut être récupéré en mode debug dans une IDE. Il s'agit du SOAPEnvelope du requestMessage du Message envoyé dans le call. Mis le plus simple consite à utiliser le moniteur de AXIS pour voir la requête qui est envoyée.
java -cp axis.jar org.apache.axis.utils.tcpmon
Le SOAP Enveloppe ressemble à ceci.
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<soapenv:Body>
<ns1:RechercherListeDossiers
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://www.agriculture.gouv.fr/AIDA/2007">
<identifiant xsi:type="xsd:string">
${pacage}</identifiant>
<typeIdentifiant xsi:type="xsd:string">
PACAGE
</typeIdentifiant>
<annee xsi:type="xsd:string">
0</annee>
</ns1:RechercherListeDossiers>
</soapenv:Body>
</soapenv:Envelope>
vendredi 1 février 2008
Deployer avec les sources à l'aide de maven
Cette commande effectue le javadoc et la mise à disposition des sources.
mvn -DperformRelease=true deploy
mvn -DperformRelease=true deploy
jeudi 31 janvier 2008
JMeter et JFaces
Afin de tester une application, je suis en train de préparer un test de performances à l'aide de l'outils JMETER.
JMETER à l'aide de son proxy enregistre toutes les requêtes avec paramètres d'entête et de corps. Parmi eux, le paramètre com.sun.faces.VIEW comporte l'état de la vue encodé d'une manière complexe. La valeur de ce champs dépend de l'état des composants et de la structure de l'arbre de composants qui représente la page courante.
L'implémentation de JSF sauvegarde l'arbre de composant et les états associés à chaque composant dans un flux de byte qui est ensuite encodé en base64.(C'est une sérialisation.)
La méthode
Lorsque l'utilisateur soumet la page ce champs est décodé par la méthode getTreeStructureToRestore de la même classe.
Si cette valeur est incorrecte, cela ne peut pas fonctionner il n'est pas possible de reconstituer l'objet qui a été sérialisé. C'est comme d'ouvrir un fichier exe avec un
éditeur hexadécimal et de supprimer ou d'ajouter des bytes par ci par là, et d'espèrer que le programme va s'éxécuter correctement. En général, si ce champs est incorrect JSF plante.
JMETER à l'aide de son proxy enregistre toutes les requêtes avec paramètres d'entête et de corps. Parmi eux, le paramètre com.sun.faces.VIEW comporte l'état de la vue encodé d'une manière complexe. La valeur de ce champs dépend de l'état des composants et de la structure de l'arbre de composants qui représente la page courante.
L'implémentation de JSF sauvegarde l'arbre de composant et les états associés à chaque composant dans un flux de byte qui est ensuite encodé en base64.(C'est une sérialisation.)
La méthode
com.sun.faces.renderkit.ResponseStateManagerImpl.writeState :
public void writeState(FacesContext context, SerializedView
view)
throws IOException {
ByteArrayOutputStream bos = null;
String hiddenField = null;
bos = new ByteArrayOutputStream();
ObjectOutput output = new ObjectOutputStream(bos);
output.writeObject(view.getStructure());
output.writeObject(view.getState());
hiddenField = " <input type=\"hidden\" name=\""
+ RIConstants.FACES_VIEW + "\"" + " value=\"" +
(new String(Base64.encode(bos.toByteArray()),
"ISO-8859-1")) +
"\" />\n ";
context.getResponseWriter().write(hiddenField);
}
Lorsque l'utilisateur soumet la page ce champs est décodé par la méthode getTreeStructureToRestore de la même classe.
public Object getTreeStructureToRestore(FacesContext
context,
String treeId) {
Object structure = null;
Object state = null;
Map requestParamMap = context.getExternalContext()
.getRequestParameterMap();
String viewString = (String) requestParamMap.get(
RIConstants.FACES_VIEW);
if (viewString == null) {
return null;
}
byte[] bytes = Base64.decode(viewString.getBytes());
try {
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(bytes));
structure = ois.readObject();
state = ois.readObject();
Map requestMap =
context.getExternalContext().getRequestMap();
// store the state object temporarily in request
scope until it is
// processed by getComponentStateToRestore which
resets it.
requestMap.put(FACES_VIEW_STATE, state);
ois.close();
} catch (java.io.OptionalDataException ode) {
log.error(ode.getMessage(), ode);
} catch (java.lang.ClassNotFoundException cnfe) {
log.error(cnfe.getMessage(), cnfe);
} catch (java.io.IOException iox) {
log.error(iox.getMessage(), iox);
}
return structure;
}
Si cette valeur est incorrecte, cela ne peut pas fonctionner il n'est pas possible de reconstituer l'objet qui a été sérialisé. C'est comme d'ouvrir un fichier exe avec un
éditeur hexadécimal et de supprimer ou d'ajouter des bytes par ci par là, et d'espèrer que le programme va s'éxécuter correctement. En général, si ce champs est incorrect JSF plante.
jeudi 17 janvier 2008
Générer un projet web service
Sous eclipse pour axis 1
New -> Dynamic Web Project pour créer le projet web
New -> Web Service
A partir d'un WSDL, on génère un top-down Web service.
A partir d'une classe java on fait une génération down-top
Pour vérifier son installation, taper http://localhost:8080/nom_application/services/
Le service doit apparaitre
Sous eclipse pour axis2
Télécharger Eclipse Eurapa pour J2EE
Télécharger la runtime (ws.apache.org/axis2/) en version WAR et en version BIN.
Dézipper le BIN et référencer le dossier extrait dans Eclipse -> Window -> Preferences -> Web services -> Axis Preferences
Reprendre les étapes précédente en choisissant cette fois la runtime axis 2
New -> Dynamic Web Project pour créer le projet web
New -> Web Service
A partir d'un WSDL, on génère un top-down Web service.
A partir d'une classe java on fait une génération down-top
Pour vérifier son installation, taper http://localhost:8080/nom_application/services/
Le service doit apparaitre
New -> Dynamic Web Project pour créer le projet web
New -> Web Service
A partir d'un WSDL, on génère un top-down Web service.
A partir d'une classe java on fait une génération down-top
- Choisir cette option dans la combo box.
- Choisir l'url du WSDL (WS definition)
- Choisir le WS server
- Choisir le projet web
- Générer le WS dans notre nouveau projet.
- Déployer sur le serveur d'application
Pour vérifier son installation, taper http://localhost:8080/nom_application/services/
Le service doit apparaitre
And now... Some Services
Il reste à implementer la classe suffixée par ImplSous eclipse pour axis2
Télécharger Eclipse Eurapa pour J2EE
Télécharger la runtime (ws.apache.org/axis2/) en version WAR et en version BIN.
Dézipper le BIN et référencer le dossier extrait dans Eclipse -> Window -> Preferences -> Web services -> Axis Preferences
Reprendre les étapes précédente en choisissant cette fois la runtime axis 2
New -> Dynamic Web Project pour créer le projet web
New -> Web Service
A partir d'un WSDL, on génère un top-down Web service.
A partir d'une classe java on fait une génération down-top
- Choisir cette option dans la combo box.
- Choisir l'url du WSDL (WS definition)
- Choisir le WS server
- Choisir le projet web
- Générer le WS dans notre nouveau projet.
- Déployer sur le serveur d'application
Pour vérifier son installation, taper http://localhost:8080/nom_application/services/
Le service doit apparaitre
And now... Some Services
Il reste à implementer la classe suffixée par ImplSubversion proxy
Si jamais vous êtes dans un réseau d'entreprise, derrière un proxy, et que vous souhaitez accéder à un serveur SVN distant, vous risquez d'être confronté à des messages d'erreurs impliquant "PROPFIND...".
Voici un petit guide pour résoudre le problème (merci Guillaume), en se basant sur le SVN de Copix pour l'exemple.
Il faut modifier le fichier "servers" de subversion.
- sous Linux, c'est : $HOME/.subversion/servers.
- sous Windows, c'est : %USERPROFILE%\Application Data\Subversion\servers.
Dans la section [group], ajoutez "copixorg=svn.copix.org", i.e. :
[group]
copixorg=*.copix.org
Puis ajoutez la section suivante :
[copixorg]
http-proxy-host = xxx.xxx.xxx.xxx
http-proxy-port = 8080
http-proxy-username = login
http-proxy-password = mot_de_passe
En utilisant tortoise SVN, il est également possible de le configurer directement dans les setting
jeudi 3 janvier 2008
Configurer ses datasources tomcat ou jonas et Spring
Récupérer la datasource dans le code
Une connexion est obtenue à partir du DataSource. Cette connexion est une implémentation particulière puisque son appel à la méthode close() ne la ferme pas réellement mais la rend à nouveau disponible au pool de connexion. Sans cette action permet la connexion ne se libère pas. Pour cette raison, il est très important que la méthode close soit appelée et même en cas d'exception. Sans cela, sans cela le pool de la database perd des connections et il peut résulter une insiponibilité de la database.
Le mieux est de faire close() de la session dans un bloc finally pour garantir son appel.
Le fichier context.xml définit cette data source. Il peut être placé dans le répertoire META-INF/context.xml, dans ce cas, il est rechargé à chaque déploiement. La ressource peut aussi être définie au niveau du Host en créant un fichier context.xml.default dans le répertoire conf/Catalina/localhost de tomcat. Dans ce cas le déploiement ne reconfigure pas la datasource. Le fichier de context s'écrit :
Au moment de récuppérer l'URL on pourra avoir de problèmes de classpath, dans ce ca le mettre dans les librairies commns de tomcat
Dans le cas d'une utilisation au sein de Spring. Le fichier dao-context.xml a été modifié pour utiliser les datasources
Cette datasource se définit dans le fichier context.xml de votre serveur tomcat de eclipse, préciser la datasource.
Ensuite copier la librairie connector-mysql (Z:\00-DOSSIER_PROD\DEquipe\Produits\Poste dev\mysql-connector-java-5.0.5.jar ). Dans votre répertoire lib de tomcat
A l'issue de ces manipulations, un clean et une publication seront prudent.
Dans le fichier conf/jonas.properties de votre serveur d'application, ajouter les datasources séparée par des virgules :
Créer le fichier
my_datasource1.properties dans votre répertoire conf et y ajouter les propriétés de votre datasources
Créer un fichier jonas-web dans le répertoire WEB-INF de votre application
Context initialContext = null;
log.error("Initializing supervision servlet");
try {
initialContext = new InitialContext();
DataSource dataSource = (DataSource) initialContext
.lookup("java:comp/env/jdbc/Journal");
connection = dataSource.getConnection();
} catch (Exception e) {
log.error("Cannot get initial context for JNDI: ");
e.printStackTrace();
log.error(e);
}
Une connexion est obtenue à partir du DataSource. Cette connexion est une implémentation particulière puisque son appel à la méthode close() ne la ferme pas réellement mais la rend à nouveau disponible au pool de connexion. Sans cette action permet la connexion ne se libère pas. Pour cette raison, il est très important que la méthode close soit appelée et même en cas d'exception. Sans cela, sans cela le pool de la database perd des connections et il peut résulter une insiponibilité de la database.
Le mieux est de faire close() de la session dans un bloc finally pour garantir son appel.
try{
connection=getConnection(); // Permet de récupérer une connexion à partir du DataSource
...
traitement
...
resultSet.close();
connection.close();
logger.debug(infoDossiers.size() + " dossiers retournés");
return infoDossiers;
} catch (SQLException e) {
try {
logger
.error(
"Erreur lors de la requête de récupération des infos du dossier pour l'identifiant : "
+ identifiant
+ " de type : "
+ typeIdentifiant
+ " pour l'année :"
+ annee, e);
if (connection != null) {
connection.close();
}
} catch (SQLException e1) {
logger.error("Erreur lors de fermeture de la connection");
}
Le fichier context.xml définit cette data source. Il peut être placé dans le répertoire META-INF/context.xml, dans ce cas, il est rechargé à chaque déploiement. La ressource peut aussi être définie au niveau du Host en créant un fichier context.xml.default dans le répertoire conf/Catalina/localhost de tomcat. Dans ce cas le déploiement ne reconfigure pas la datasource. Le fichier de context s'écrit :
<Context displayName="Calam-WS" path="/calam-ws">
<Resource name="jdbc/MyDataSource" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="2" maxWait="5000"
username="myuser" password="mypass" driverClassName="com.sybase.jdbc3.jdbc.SybDriver"
url="jdbc:sybase:Tds:ouaga:5000/MyBase</Context>
Au moment de récuppérer l'URL on pourra avoir de problèmes de classpath, dans ce ca le mettre dans les librairies commns de tomcat
Dans le cas d'une utilisation au sein de Spring. Le fichier dao-context.xml a été modifié pour utiliser les datasources
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
destroy-method="close">
<property name="jndiName" value="java:comp/env/jdbc/my-datasource" />
</bean>
Cette datasource se définit dans le fichier context.xml de votre serveur tomcat de eclipse, préciser la datasource.
<Context path="/myapp" docBase="myapp-ihm"
debug="5" reloadable="true" crossContext="true">
<Resource name="jdbc/my-datasource" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="user" password="password" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb"/>
</Context>
Ensuite copier la librairie connector-mysql (Z:\00-DOSSIER_PROD\DEquipe\Produits\Poste dev\mysql-connector-java-5.0.5.jar ). Dans votre répertoire lib de tomcat
A l'issue de ces manipulations, un clean et une publication seront prudent.
Installer des datasources sous JONAS
Dans le fichier conf/jonas.properties de votre serveur d'application, ajouter les datasources séparée par des virgules :
jonas.service.dbm.datasources my_datasource1
Créer le fichier
my_datasource1.properties dans votre répertoire conf et y ajouter les propriétés de votre datasources
#This file is generated by JOnAS
#Fri Feb 26 14:16:50 CET 2010
jdbc.maxconpool=-1
jdbc.connmaxage=1440
jdbc.maxwaittime=10
datasource.url=\ jdbc\:mysql\://my-db\:3306/mydb
datasource.description=no desc
datasource.mapper=rdb
jdbc.minconpool=0
jdbc.connteststmt=SELECT 1
datasource.username=myuser
datasource.name=ftjobs_1
datasource.classname=com.mysql.jdbc.Driver
jdbc.maxwaiters=1000
datasource.password=mypassword
jdbc.connchecklevel=1
jdbc.maxopentime=1440
Créer un fichier jonas-web dans le répertoire WEB-INF de votre application
<jonas-web-app>
<jonas-resource>
<res-ref-name>jdbc/my-datasource</res-ref-name>
<jndi-name>mydatasource_1</jndi-name>
</jonas-resource>
</jonas-web-app>
Inscription à :
Articles (Atom)