Crash + eXo Platform – sizeOf JCR content command

Crash est un outil qui permet de se connecter à une JVM et de profiter de toutes les librairies chargées par celle-ci pour exécuter des scripts Groovy, naviguer dans le JCR …

Cet outil peut fonctionner de différentes manières :

  • En stantalone
  • En mode web, déployé en tant que webapp
  • Directement injecté par Spring

Pour notre cas nous allons utiliser la version web déployée dans un Tomcat pour se connecter au JCR de eXo Platform. 2 versions du mode web existent, une configurée pour se connecter à eXoPlatform, une plus générique.

Généralités pour débuter

Dans un premier temps nous allons voir comment on fait pour se connecter à Crash une fois celui-ci déployé dans le Tomcat d’eXo Platform.

Crash écoute par défaut sur le port 2000 pour ssh et 5000 pour telnet. Ces deux possibilités sont permises pour se connecter. Dans notre cas nous ferons la connexion en ssh, avec l’utilisateur root (mot de passe : gtn) :

ssh -p 2000 -l root localhost

où « localhost » est le nom du serveur hébergeant Tomcat.

On tombe alors sur l’invite de commandes Crash

   ______
 .~      ~. |`````````,       .'.                   ..'''' |         |
|           |'''|'''''      .''```.              .''       |_________|
|           |    `.       .'       `.         ..'          |         |
 `.______.' |      `.   .'           `. ....''             |         | 1.2.8

Ensuite, il faut se connecter au repository :

repo use container=portal

Et il faut se connecter au workspace (ici collaboration) :

ws login -u root -p gtn collaboration

A partir de ce moment la on peut naviguer dans le JCR et faire tout un tas d’opérations comme créer, supprimer, déplacer des noeuds.

Créer une nouvelle commande Crash

La création d’une nouvelle commande se fait via un script Groovy.

Dans le war on trouve dans WEB-INF un répertoire crash/commands qui contient 2 répertoires pour accueillir les scripts Groovy le premier contient les commandes générales (system) et le deuxième les commandes JCR.

Nous allons donc réaliser un script Groovy nommé « sizeof.groovy » et le placer dans le répertoire JCR.

Les nouveaux scripts et les modifications de scripts existants sont pris en compte à chaud.

Cette nouvelle commande comporte des options :

-t (type) : permet de filtrer sur un « jcr:primaryType »
-l (limit) : permet de limiter le nombre de résultats
-f (outPutFile) : permet de donner un chemin et nom de fichier qui stockera les résultats

et un paramètre obligatoire qui est le « jcr:path » a partir du quel on veut lancer la recherche.

Voici le code du script :


package crash.commands.jcr

import javax.jcr.query.Query

import org.crsh.text.ui.UIBuilder
import org.crsh.cli.Usage
import org.crsh.cli.Command
import org.crsh.cli.Man
import org.crsh.cli.Argument
import org.crsh.cli.Option
import org.crsh.cli.Required

@Usage("sizeOf JCR nodes command")
class sizeof extends org.crsh.jcr.command.JCRCommand {

@Usage("size of a single content")
@Command
public Object list(
@Option(names=["t","type"]) @Usage("jcr:primaryType") String type,
@Option(names=["l","limit"]) @Usage("the result limit") @Man("The number of nodes displayed, by default this value is equals to 5") Integer limit,
@Option(names=["f","outPutFile"]) @Usage("Path with name of the output file") String outPutFile,
@Argument @Usage("JCR path") String path) {

    // Default limit set to 5
    limit = limit ?: 5;

    assertConnected();

    def queryMgr = session.workspace.queryManager;

    // JCR Query to retrieve all the subnodes of the given path
    def statement = "select * from " + (type != null ? type : "nt:base") + " where jcr:path like '" + path + "/%'";

    // Exceution of the query
    def select = queryMgr.createQuery(statement, Query.SQL);
    def result = select.execute()
    def nodes = result.nodes
    def total = nodes.size

    // output result
    def stream = new StringBuilder()

    def builder = new UIBuilder();
    builder.node("The query matched " + total + " nodes") {
    def index = 0;
    def contentMap = [:]

    while (nodes.hasNext()) {
      def n = nodes.next()
      def nodeSize = 0

      // calculate the node size
      if (n.hasProperty("jcr:content/jcr:data")) {
        nodeSize = n.getProperty("jcr:content/jcr:data").getLength() / 1024
      }

      contentMap.put(n.path,nodeSize)

      index++
      if (limit != null && index >= limit) {
        break;
      }
    }

    // Sort the new map from the biggest to the smallest
    contentMap = contentMap.sort{a,b -> b.value <=> a.value}
    def chaine
    def file

    for (item in contentMap){
      chaine = item.key + " : " + item.value + " Ko"
      stream.append(chaine + "\r\n")
      label(chaine)
    }
 }

 // Store in the file
 if (outPutFile != null) {
   System.out.println("Output file : " + outPutFile)

   file = new File(outPutFile)
   file.write(stream.toString())
 }

 return builder;
 }
}

Une fois ce script déployé, un lancement de la commande « help » permet de s’assurer qu’il est bien disponible dans Crash.


% help
Try one of these commands with the -h or --help switch:

NAME DESCRIPTION
cd : changes the current node
commit : saves changes
cp : copy a node to another
dashboard
env : display the term env
filter : A filter for a stream of map
help : provides basic help
java : various java language commands
jdbc : JDBC connection
jmx : Java Management Extensions
jndi : Java Naming and Directory Interface
jpa : Java persistance API
jvm : JVM informations
log : logging commands
ls : list the content of a node
man : format and display the on-line manual pages
mixin : mixin commands
mv : move a node
node : node commands
pwd : print the current node path
repo : repository interaction commands
rm : remove one or several node or a property
rollback : ollback changes
selec : execute a JCR sql query
shell : shell related command
sizeof : sizeOf JCR nodes command
sleep : sleep for some time
sort : Sort a map
system : vm system properties commands
thread : JVM thread commands
version : versioning commands
ws : workspace commands
xpath : execute a JCR xpath query

Maintenant on peut aisément exécuter la commande suivante :

sizeof list -t nt:file -l 10 "/sites content/live/Contenus/MonRepertoireDeContenus"

En retour nous allons avoir un tableau indiquant les chemins des contenus et leurs poids, allant du plus lourd au plus léger.

% sizeof content -t nt:file -l 10 "/sites content/live/Contenus/Footer
The query matched 8 nodes
+-/sites content/live/Contenus/Footer/Footer simple/footer/default.html : 2.556640625 Ko
+-/sites content/live/Contenus/Footer/Footer simple/footer-authentification/default.html : 2.3564453125 Ko
+-/sites content/live/Contenus/Footer/Footer simple/footer/js/default.js : 0 Ko
+-/sites content/live/Contenus/Footer/Footer simple/footer-authentification/js/default.js : 0 Ko
+-/sites content/live/Contenus/Footer/Footer simple/footer/css/default.css : 0 Ko
+-/sites content/live/Contenus/Footer/Footer simple/footer/medias/images/illustration : 0 Ko
+-/sites content/live/Contenus/Footer/Footer simple/footer-authentification/css/default.css : 0 Ko
+-/sites content/live/Contenus/Footer/Footer simple/footer-authentification/medias/images/illustration : 0 Ko

La documentation de Crash est très bien faite. Vous pouvez trouver toutes les infos sur http://www.crashub.org

Enjoy !

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s