如何在DAG中使用Apache Apex Malhar RabbitMQ运算符

时间:2017-02-13 15:20:03

标签: rabbitmq inputstream spring-rabbit apache-apex

我有一个Apache Apex应用程序DAG,它从队列中读取RabbitMQ消息。我应该使用哪个Apache Apex Malhar操作符?有几个运营商,但不清楚使用哪一个以及如何使用它。

3 个答案:

答案 0 :(得分:4)

答案 1 :(得分:2)

https://github.com/apache/apex-malhar/blob/master/contrib/src/main/java/com/datatorrent/contrib/rabbitmq/AbstractRabbitMQInputOperator.java

这是主要的操作符代码,其中元组类型是泛型参数,emitTuple()是子类需要实现的抽象方法。

AbstractSinglePortRabbitMQInputOperator是一个简单的子类,它提供单个输出端口,并使用另一个需要在其子类中实现的抽象方法getTuple()来实现emitTuple()。

Sanjay指出的测试显示了如何使用这些类。

答案 2 :(得分:0)

我也在查找如何从RabbitMQ到Apache Apex读取消息时遇到了问题。在Sanjay的回答(https://stackoverflow.com/a/42210636/2350644)提供的链接的帮助下,我终于设法让它运行起来。以下是它们如何协同工作:

1。设置RabbitMQ服务器

安装RabbitMQ的方法很多,如下所述:https://www.rabbitmq.com/download.html
对我来说最简单的方法是使用docker(参见:https://store.docker.com/images/rabbitmq

docker pull rabbitmq

docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management  

要检查RabbitMQ是否正常工作,请打开浏览器并导航至:http://localhost:15672/。您应该看到RabbitMQ的管理页面。

2。写一个制片人节目

要将消息发送到队列,您可以编写一个简单的JAVA程序,如下所示:

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.util.ArrayList;

public class Send {
    private final static String EXCHANGE = "myExchange";

    public static void main(String[] args) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(EXCHANGE, BuiltinExchangeType.FANOUT);

        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, EXCHANGE, "");

        List<String> messages = Arrays.asList("Hello", "World", "!");
        for (String msg : messages) {
            channel.basicPublish(EXCHANGE, "", null, msg.getBytes("UTF-8"));
            System.out.println(" [x] Sent '" + msg + "'");
        }

        channel.close();
        connection.close();
    }
}

如果执行JAVA程序,您应该在RabbitMQ的管理UI中看到一些输出。

3。实施示例Apex应用程序

3.1引导样本顶点应用程序

按照官方顶级文档http://docs.datatorrent.com/beginner/

3.2向pom.xml

添加其他依赖项

要使用malhar提供的类,请添加以下依赖项:

<dependency>
  <groupId>org.apache.apex</groupId>
  <artifactId>malhar-contrib</artifactId>
  <version>3.7.0</version>
</dependency>
<dependency>
  <groupId>com.rabbitmq</groupId>
  <artifactId>amqp-client</artifactId>
  <version>4.2.0</version>
</dependency>

3.3创建消费者

我们首先需要使用InputOperator中的可用代码创建一个使用来自RabbitMQ的消息的apex-malhar

import com.datatorrent.contrib.rabbitmq.AbstractSinglePortRabbitMQInputOperator;

public class MyRabbitMQInputOperator extends AbstractSinglePortRabbitMQInputOperator<String> {
    @Override
    public String getTuple(byte[] message) {
        return new String(message);
    }
}

您只需覆盖getTuple()方法。在这种情况下,我们只返回从RabbitMQ收到的消息。

3.4设置Apex DAG

为了测试应用程序,我们只需添加一个消耗来自RabbitMQ的数据的InputOperator(我们之前实现的MyRabbitMQInputOperator)和一个打印接收消息的ConsoleOutputOperator

import com.rabbitmq.client.BuiltinExchangeType;
import org.apache.hadoop.conf.Configuration;

import com.datatorrent.api.annotation.ApplicationAnnotation;
import com.datatorrent.api.StreamingApplication;
import com.datatorrent.api.DAG;
import com.datatorrent.api.DAG.Locality;
import com.datatorrent.lib.io.ConsoleOutputOperator;

@ApplicationAnnotation(name="MyFirstApplication")
public class Application implements StreamingApplication
{

  private final static String EXCHANGE = "myExchange";


  @Override
  public void populateDAG(DAG dag, Configuration conf)
  {

    MyRabbitMQInputOperator consumer = dag.addOperator("Consumer", new MyRabbitMQInputOperator());
    consumer.setHost("localhost");
    consumer.setExchange(EXCHANGE);
    consumer.setExchangeType(BuiltinExchangeType.FANOUT.getType());

    ConsoleOutputOperator cons = dag.addOperator("console", new ConsoleOutputOperator());

    dag.addStream("myStream", consumer.outputPort, cons.input).setLocality(Locality.CONTAINER_LOCAL);
  }
}

3.5测试应用程序

要简单地测试创建的应用程序,我们可以编写UnitTest,因此无需设置Hadoop / YARN群集。 在bootstrap应用程序中,我们可以使用UnitTest即ApplicationTest.java

import java.io.IOException;
import javax.validation.ConstraintViolationException;
import org.junit.Assert;
import org.apache.hadoop.conf.Configuration;
import org.junit.Test;
import com.datatorrent.api.LocalMode;

/**
 * Test the DAG declaration in local mode.
 */
public class ApplicationTest {

  @Test
  public void testApplication() throws IOException, Exception {
    try {
      LocalMode lma = LocalMode.newInstance();
      Configuration conf = new Configuration(true);
      //conf.addResource(this.getClass().getResourceAsStream("/META-INF/properties.xml"));
      lma.prepareDAG(new Application(), conf);
      LocalMode.Controller lc = lma.getController();
      lc.run(10000); // runs for 10 seconds and quits
    } catch (ConstraintViolationException e) {
      Assert.fail("constraint violations: " + e.getConstraintViolations());
    }
  }

}

由于我们不需要此应用程序的任何属性,因此此文件中唯一更改的内容是取消注释该行:

conf.addResource(this.getClass().getResourceAsStream("/META-INF/properties.xml"));

如果执行ApplicationTest.java并使用Producer程序向{@ 1}}中的描述发送消息,则测试应输出所有消息。 您可能需要增加测试时间以查看所有消息(当前设置为10秒)。