Saturday July 7, 2007 20:20

Probando ActiveMQ – Parte II

Posted by admin as JMS

Necesitaba consolidar mi escenario HA logrando arrancar un servidor master y que luego este arrancara el broker slave en un servidor JBoss remoto (en otra maquina).

JBoss viene preparado para ello y permite exponer a un servicio MBean para ser ejecutado por via remota a traves de un proceso bastante tricky el cual me costo bastante descubrir.

En primera medida hay que crear un interface para el servicio que necesitamos exponer:

 
public interface ActiveMQNetworkMBean {
 
    public void start() throws Exception;
 
    public void stop() throws Exception;
 
    public void startSlave() throws Exception;
 
    public void stopSlave() throws Exception;
 
    Object invoke(org.jboss.invocation.Invocation mi) throws Exception;
}

Luego hay que crear la implementación de dicho servicio:

 
public class ActiveMQNetwork implements ActiveMQNetworkMBean {
    private String propertiesResource;
    private BrokerService service = null;
    private BrokerService serviceSlave = null;
    private boolean started = false;
    private boolean startedSlave = false;
    private static Logger log =         Logger.getLogger(ActiveMQNetwork.class);
 
    public void start() throws Exception {
        started = true;
        log.info("BROKER SERVICE: Starting ActiveMQNetwork ... " + propertiesResource);
        createNetwork();
    }
 
    public void stop() throws Exception {
        started = false;
        log.info("BROKER SERVICE: Stoping ActiveMQNetwork ...");
        if (service != null) {
            service.stop();
            service = null;
        }
        // do what you want ...
    }
 
    private void createNetwork() {
        log.info("BROKER SERVICE: trying to crete broker");
 
        try {
            URI brokerURI = new URI("xbean:" + System.getProperty("jboss.server.config.url") + "activemq_master.xml");
            service = BrokerFactory.createBroker(brokerURI);
            if (service != null) {
                service.start();
            }
        } catch (Exception e) {
            log.error("BROKER SERVICE: createNetwork Exception: " + e.getMessage());
            e.printStackTrace();
        }
    }
 
    public void startSlave() throws Exception {
        startedSlave = true;
        log.info("BROKER SERVICE: Starting ActiveMQNetwork Slave Broker... ");
        createNetworkSlave();
    }
 
    public void stopSlave() throws Exception {
        startedSlave = false;
        log.info("BROKER SERVICE: Stoping ActiveMQNetwork Slave Broker...");
        if (serviceSlave != null) {
            serviceSlave.stop();
            serviceSlave = null;
        }
        // do what you want ...
    }
 
    private void createNetworkSlave() {
        log.info("BROKER SERVICE: trying to crete broker slave");
 
        try {
            URI brokerURI = new URI("xbean:" + System.getProperty("jboss.server.config.url") + "activemq_slave.xml");
            serviceSlave = BrokerFactory.createBroker(brokerURI);
            if (serviceSlave != null) {
                serviceSlave.start();
            }
        } catch (Exception e) {
            log.error("BROKER SERVICE: createNetwork Slave Exception: " + e.getMessage());
            e.printStackTrace();
        }
    }
 
 
    public Object invoke(Invocation mi) throws Exception {
        log.info("BROKER SERVICE: MyService.invoke> method=" + mi.getMethod().getName());
        return "invoke";
    }
}

Una vez hecho esto, se define el fichero jboss-service.xml:

 
<mbean code="com.bs.activemq.mbean.service.ActiveMQNetwork"
	       name="jms.ActiveMQ:service=ActiveMQNetwork">
        <depends>jboss:service=Naming</depends>
	</mbean>
   <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"      name="jboss.jmx:type=adaptor,name=MyActiveMQNetworkInvokeTarget,protocol=jrmp,service=proxyFactory">
      <depends optional-attribute-name="InvokerName">jboss:service=invoker,type=jrmp</depends>
 
      <depends optional-attribute-name="TargetName">jms.ActiveMQ:service=ActiveMQNetwork</depends>
 
      <attribute name="JndiName">MyActiveMQNetworkInvokeTarget</attribute>
 
      <attribute name="InvokeTargetMethod">true</attribute>
 
      <attribute name="ExportedInterfaces">com.bs.activemq.mbean.service.ActiveMQNetworkMBean</attribute>
 
 
      <attribute name="ClientInterceptors">
          <interceptors>
             <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
             <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
             <interceptor>org.jboss.jmx.connector.invoker.client.InvokerAdaptorClientInterceptor</interceptor>
             <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
          </interceptors>
      </attribute>
   </mbean>

Dentro de ese fichero esta la definición del servicio creado y la definición del proxy que expondrá nuestro servicio para su acceso remoto.

Esto se empaqueta como un fichero .sar y se hace un deploy en el directorio deploy del server de JBoss que estemos usando.

A partir de alli viene el desafio de crear un cliente que funcione. :)

Un cliente simple seria algo asi:

 
try {
            Hashtable env = new Hashtable();
            env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
            env.put("java.naming.provider.url", "jnp://172.31.112.9:1099");
            env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
            //env.put("java.naming.factory.url.pkgs", "org.jnp.interfaces");
 
            InitialContext ic = new InitialContext(env);
            ActiveMQNetworkMBean myService = (ActiveMQNetworkMBean) ic.lookup("MyActiveMQNetworkInvokeTarget");
            //String res = myService.myTestAction();
 
 
        } catch(Exception e) {
            e.printStackTrace();
        }

Dado que estoy accediendo por via remota y no estoy dentro de JBoss, debo definir los parametros de configuracion para el InitialContext.

Luego el tema pasa por, simplemente, buscar el proxy que nuestro servicio guardó en el JNDI de JBoss y luego llamar al metodo de nuestro servicio que deseamos probar.

Es todo.

Comment Form