Piloter Camel avec Quartz et JMX

Cette fois-ci, le besoin est d'ordonnancer l'exécution d'une application Camel via le gestionnaire de tâches Quartz tout en laissant la possibilité de démarrer manuellement les routes à la demande.

Commençons par l'ordonnancement. Admettons que le programme ne doit se lancer qu'à partir de 5 heures du matin en fin de semaine. La syntaxe CRON correspondante est :

* * 5 ? * SAT-SUN

Pour configurer la route initiale avec cette règle, il faut lui spécifier une routePolicy :

@Override
public void configure() throws Exception {
  
 // Quartz
 CronScheduledRoutePolicy startPolicy = new CronScheduledRoutePolicy();
 // ne démarre que le weekend à partir de 5h du matin
 startPolicy.setRouteStartTime("* * 5 ? * SAT-SUN");
 ...
 from("file://...").routePolicy(startPolicy).noAutoStartup().routeId("firstRoute")...
}

Ainsi donc, la route n'est pas démarrée au lancement du contexte mais délègue cette tâche à l'ordonnanceur. (Ne pas oublier d'ajouter la dépendance camel-quartz)

Passons à la mise en place de JMX pour piloter à distance Camel.

Au démarrage de l'application, il faut référencer un bean particulier ayant connaissance du contexte Camel auprès du server JMX de la JVM :

MBeanServer server = ManagementFactory.getPlatformMBeanServer();
MyAgentManagerMXBean mbean = new MyCamelMBean(camelContext);
ObjectName name = new ObjectName("my.jmx.domain.MyDomain:type=MyCamelMBean,name=myCamelMBean");
server.registerMBean(mbean, name);

La paramètre camelContext du bean est une instance du context Camel, par exemple de org.apache.camel.main.Main. Je précise au passage qu'afin de rendre disponible l'interface à JMX, le nom de celle-ci doit être suffixé par MXBean (il s'agit d'une convention JMX). Et voici comment sont écrites l'interface et l'instance du bean mbean

public interface MyAgentManagerMXBean {
 
 /**
  * Start Camel manually, overriding quartz schedule
  * @throws Exception
  */
 public void camelManualStart() throws Exception;

}
public class MyCamelMBean implements MyAgentManagerMXBean {

 private Main camel;
 
 public MyCamelMBean(Main context) {
  camel = context;
 }

 @Override
 public void camelManualStart() throws Exception {
  camel.getRouteBuilders().get(0).getContext().startRoute("firstRoute");
 }
}

Avec cette configuration, il est alors possible, avec n'importe quelle console JMX (ici la JConsole) de démarrer manuellement la route configurée avec Quartz :

J'en profite pour ajouter un exemple permettant de récupérer des informations directement de Camel, par exemple ici le nombre de message traités sur une route :

public long getSourceFilesManagedNb() {
 long result = 0;
 try {
  JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1616/jmxrmi");
  JMXConnector jmxc = JMXConnectorFactory.connect(url);
  MBeanServerConnection server = jmxc.getMBeanServerConnection();
  ObjectName objName = new ObjectName("org.apache.camel:type=routes,name=\"firstRoute\",*");
  List<ObjectName> cacheList = new LinkedList<ObjectName>(server.queryNames(objName, null));
  for (ObjectName objName2 : cacheList) {
   result = (Long) server.invoke(objName2, "getExchangesCompleted", null, null);
  }
 } catch (Exception e) {
  e.printStackTrace();
 }
 return result;
}

Voilà tout!


Fichier(s) joint(s) :

0 commentaires: