Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 卡夫卡流-根据流数据发送不同主题_Java_Apache Kafka_Apache Kafka Streams - Fatal编程技术网

Java 卡夫卡流-根据流数据发送不同主题

Java 卡夫卡流-根据流数据发送不同主题,java,apache-kafka,apache-kafka-streams,Java,Apache Kafka,Apache Kafka Streams,我有一个kafka streams应用程序正在等待在主题用户活动上发布记录。它将接收json数据,并根据键的值将该流推送到不同的主题中 这是我的streams应用程序代码: KStream<String, String> source_user_activity = builder.stream("user_activity"); source_user_activity.flatMapValues(new ValueMapper<String, Iterabl

我有一个kafka streams应用程序正在等待在主题
用户活动
上发布记录。它将接收json数据,并根据键的值将该流推送到不同的主题中

这是我的streams应用程序代码:

KStream<String, String> source_user_activity = builder.stream("user_activity");
        source_user_activity.flatMapValues(new ValueMapper<String, Iterable<String>>() {
            @Override
            public Iterable<String> apply(String value) {
                System.out.println("value: " +  value);
                ArrayList<String> keywords = new ArrayList<String>();
                try {
                    JSONObject send = new JSONObject();
                    JSONObject received = new JSONObject(value);

                    send.put("current_date", getCurrentDate().toString());
                    send.put("activity_time", received.get("CreationTime"));
                    send.put("user_id", received.get("UserId"));
                    send.put("operation_type", received.get("Operation"));
                    send.put("app_name", received.get("Workload"));
                    keywords.add(send.toString());
                    // apply regex to value and for each match add it to keywords

                } catch (Exception e) {
                    // TODO: handle exception
                    System.err.println("Unable to convert to json");
                    e.printStackTrace();
                }

                return keywords;
            }
        }).to("user_activity_by_date");
KStream source\u user\u activity=builder.stream(“user\u activity”);
source\u user\u activity.flatMapValues(新的ValueMapper(){
@凌驾
公共Iterable应用(字符串值){
System.out.println(“值:”+value);
ArrayList关键字=新建ArrayList();
试一试{
JSONObject send=新建JSONObject();
接收到的JSONObject=新的JSONObject(值);
send.put(“current_date”,getCurrentDate().toString());
send.put(“活动时间”,received.get(“CreationTime”);
send.put(“user_id”,received.get(“UserId”);
send.put(“操作类型”,received.get(“操作”);
send.put(“app_name”,received.get(“Workload”);
关键词.add(send.toString());
//将正则表达式应用于值,并为每个匹配项将其添加到关键字
}捕获(例外e){
//TODO:处理异常
System.err.println(“无法转换为json”);
e、 printStackTrace();
}
返回关键字;
}
})。至(“用户活动截止日期”);
在这段代码中,我想检查操作类型,然后根据操作类型将流推送到相关主题中

我怎样才能做到这一点

编辑:

我已将代码更新为:

final StreamsBuilder builder = new StreamsBuilder();

KStream<String, String> source_o365_user_activity = builder.stream("o365_user_activity");
KStream<String, String>[] branches = source_o365_user_activity.branch( 
      (key, value) -> (value.contains("Operation\":\"SharingSet") && value.contains("ItemType\":\"File")),
      (key, value) -> (value.contains("Operation\":\"AddedToSecureLink") && value.contains("ItemType\":\"File")),
      (key, value) -> true
     );

branches[0].to("o365_sharing_set_by_date");
branches[1].to("o365_added_to_secure_link_by_date");
branches[2].to("o365_user_activity_by_date");
final StreamsBuilder builder=new StreamsBuilder();
KStream source_o365_user_activity=builder.stream(“o365_user_activity”);
KStream[]branchs=源\用户\活动。分支(
(键,值)->(value.contains(“Operation\”:\“SharingSet”)和&value.contains(“ItemType\”:\“File”),
(键,值)->(value.contains(“Operation\”:\“AddedToSecureLink”)和&value.contains(“ItemType\”:\“File”),
(键,值)->true
);
分支机构[0]。至(“o365共享按日期设置”);
分支机构[1]。至(“o365在日期之前添加到安全链接”);
分支机构[2]。至(“o365用户活动截止日期”);

您可以使用
分支
方法来分割流。此方法使用谓词将源流拆分为多个流

以下代码取自:

KStream[]forks=ordersWithTotals.branch(
(id,orderValue)->orderValue.getValue()>=欺诈限额,
(id,orderValue)->orderValue.getValue();
分叉[0]。映射值(
orderValue->new OrderValidation(orderValue.getOrder().getId(),欺诈检查,失败))
.to(ORDER_VALIDATIONS.name(),已生成
.with(ORDER_VALIDATIONS.keySerde()、ORDER_VALIDATIONS.valueSerde());
forks[1]。映射值(
orderValue->new OrderValidation(orderValue.getOrder().getId(),欺诈检查,通过))
.to(ORDER_VALIDATIONS.name(),已生成
.with(ORDER_VALIDATIONS.keySerde()、ORDER_VALIDATIONS.valueSerde());

原始的
KStream.branch
方法很不方便,因为它混合了数组和泛型,并且因为它迫使人们使用“幻数”从结果中提取正确的分支(参见例如问题)。从2.2.4开始,课程可用。使用它,可以实现更方便的分支:

newkafkastreamsbrancher()
.branch((键,值)->value.contains(“A”),ks->ks.to(“A”))
.branch((键,值)->value.contains(“B”),ks->ks.to(“B”))
.defaultBranch(ks->ks.to(“C”))
.onTopOf(builder.stream(“源”))
//onTopOf返回提供的流,以便我们可以继续方法链接
//并对原始流执行更多操作

卡夫卡本身也有可能改进分支

另一种可能性是使用TopicNameExtractor动态路由事件:

不过,您需要提前创建主题

val outputTopic: TopicNameExtractor[String, String] = (_, value: String, _) => defineOutputTopic(value)

builder
  .stream[String, String](inputTopic)
  .to(outputTopic)
defineOutputTopic可以返回给定值的一组已定义主题中的一个(或该主题的键或记录上下文)。
PD:对scala代码感到抱歉,在链接中有一个Java示例

什么是
(id,orderValue
)?我在看Kafka Streams文档,它类似于
(key,value)->predicate()
。但我在值中有一个Json对象,然后在该Json对象中有多个键和值。那么,我如何才能根据这一点进行分支呢?这只是一个示例。看看这个:好的,我明白了。谓词的数量是静态的,因此您可以将源流拆分为预定义数量的子流。如果您需要一些动态拆分,恐怕您必须重新设计逻辑。关于您的问题:您可以定义一个谓词列表,如_hasField_uz(…)或其他什么。每个谓词都将检查json中的字段是否正确。假设我想将所有记录发送到第三个主题。branch允许这样做吗?@EL323是的,您只需为每个记录创建一个求值为true的谓词。就像我在编辑中所做的那样?但它没有得到其他日志。它只获取前两个谓词计算为false的日志。更新的代码有效吗?@panoit是的,谢谢。这节省了我的时间。
val outputTopic: TopicNameExtractor[String, String] = (_, value: String, _) => defineOutputTopic(value)

builder
  .stream[String, String](inputTopic)
  .to(outputTopic)