├── .gitignore
├── LICENSE
├── README.md
├── pom.xml
└── src
└── main
├── java
└── io
│ └── redpanda
│ └── examples
│ └── WordCount.java
└── resources
└── log4j2.properties
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | target/
26 | dependency-reduced-pom.xml
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Nyalia Lui
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flink-kafka-examples
2 | A repo of Java examples using Apache Flink with flink-connector-kafka
3 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
19 |
21 | 4.0.0
22 |
23 | io.redpanda.examples
24 | flink-kafka-examples
25 | 1.0
26 | jar
27 |
28 | Flink Quickstart Job
29 |
30 |
31 | UTF-8
32 | 1.14.0
33 | 1.8
34 | 2.11
35 | ${target.java.version}
36 | ${target.java.version}
37 | 2.14.1
38 |
39 |
40 |
41 |
42 | apache.snapshots
43 | Apache Development Snapshot Repository
44 | https://repository.apache.org/content/repositories/snapshots/
45 |
46 | false
47 |
48 |
49 | true
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | org.apache.flink
59 | flink-java
60 | ${flink.version}
61 | provided
62 |
63 |
64 | org.apache.flink
65 | flink-streaming-java_${scala.binary.version}
66 | ${flink.version}
67 | provided
68 |
69 |
70 | org.apache.flink
71 | flink-clients_${scala.binary.version}
72 | ${flink.version}
73 | provided
74 |
75 |
76 |
77 |
78 |
86 |
87 | org.apache.flink
88 | flink-connector-kafka_${scala.binary.version}
89 | ${flink.version}
90 |
91 |
92 |
93 |
94 |
95 | org.apache.logging.log4j
96 | log4j-slf4j-impl
97 | ${log4j.version}
98 | runtime
99 |
100 |
101 | org.apache.logging.log4j
102 | log4j-api
103 | ${log4j.version}
104 | runtime
105 |
106 |
107 | org.apache.logging.log4j
108 | log4j-core
109 | ${log4j.version}
110 | runtime
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | org.apache.maven.plugins
120 | maven-compiler-plugin
121 | 3.1
122 |
123 | ${target.java.version}
124 | ${target.java.version}
125 |
126 |
127 |
128 |
129 |
130 |
131 | org.apache.maven.plugins
132 | maven-shade-plugin
133 | 3.1.1
134 |
135 |
136 |
137 | package
138 |
139 | shade
140 |
141 |
142 |
143 |
144 | org.apache.flink:flink-shaded-force-shading
145 | com.google.code.findbugs:jsr305
146 | org.slf4j:*
147 | org.apache.logging.log4j:*
148 |
149 |
150 |
151 |
152 |
154 | *:*
155 |
156 | META-INF/*.SF
157 | META-INF/*.DSA
158 | META-INF/*.RSA
159 |
160 |
161 |
162 |
163 |
164 | io.redpanda.examples.WordCount
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 | org.eclipse.m2e
179 | lifecycle-mapping
180 | 1.0.0
181 |
182 |
183 |
184 |
185 |
186 | org.apache.maven.plugins
187 | maven-shade-plugin
188 | [3.1.1,)
189 |
190 | shade
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 | org.apache.maven.plugins
200 | maven-compiler-plugin
201 | [3.1,)
202 |
203 | testCompile
204 | compile
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
--------------------------------------------------------------------------------
/src/main/java/io/redpanda/examples/WordCount.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | package io.redpanda.examples;
20 |
21 |
22 | import org.apache.flink.api.common.functions.FlatMapFunction;
23 | import org.apache.flink.streaming.api.datastream.DataStream;
24 | import org.apache.flink.api.java.tuple.Tuple2;
25 | import org.apache.flink.util.Collector;
26 | import org.apache.flink.connector.kafka.source.KafkaSource;
27 | import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer;
28 | import org.apache.flink.connector.kafka.sink.KafkaSink;
29 | import org.apache.flink.connector.kafka.sink.KafkaRecordSerializationSchema;
30 | import org.apache.flink.api.common.serialization.SimpleStringSchema;
31 | import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
32 | import org.apache.flink.api.common.eventtime.WatermarkStrategy;
33 |
34 | /**
35 | * This is a re-write of the Apache Flink WordCount example using Kafka connectors.
36 | * Find the original example at
37 | * https://github.com/apache/flink/blob/master/flink-examples/flink-examples-streaming/src/main/java/org/apache/flink/streaming/examples/wordcount/WordCount.java
38 | */
39 | public class WordCount {
40 |
41 | final static String inputTopic = "input-topic";
42 | final static String outputTopic = "output-topic";
43 | final static String jobTitle = "WordCount";
44 |
45 | public static void main(String[] args) throws Exception {
46 | final String bootstrapServers = args.length > 0 ? args[0] : "localhost:9092";
47 |
48 | // Set up the streaming execution environment
49 | final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
50 |
51 | KafkaSource source = KafkaSource.builder()
52 | .setBootstrapServers(bootstrapServers)
53 | .setTopics(inputTopic)
54 | .setGroupId("my-group")
55 | .setStartingOffsets(OffsetsInitializer.earliest())
56 | .setValueOnlyDeserializer(new SimpleStringSchema())
57 | .build();
58 |
59 | KafkaRecordSerializationSchema serializer = KafkaRecordSerializationSchema.builder()
60 | .setValueSerializationSchema(new SimpleStringSchema())
61 | .setTopic(outputTopic)
62 | .build();
63 |
64 | KafkaSink sink = KafkaSink.builder()
65 | .setBootstrapServers(bootstrapServers)
66 | .setRecordSerializer(serializer)
67 | .build();
68 |
69 | DataStream text = env.fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");
70 |
71 |
72 | // Split up the lines in pairs (2-tuples) containing: (word,1)
73 | DataStream counts = text.flatMap(new Tokenizer())
74 | // Group by the tuple field "0" and sum up tuple field "1"
75 | .keyBy(value -> value.f0)
76 | .sum(1)
77 | .flatMap(new Reducer());
78 |
79 | // Add the sink to so results
80 | // are written to the outputTopic
81 | counts.sinkTo(sink);
82 |
83 | // Execute program
84 | env.execute(jobTitle);
85 | }
86 |
87 | /**
88 | * Implements the string tokenizer that splits sentences into words as a user-defined
89 | * FlatMapFunction. The function takes a line (String) and splits it into multiple pairs in the
90 | * form of "(word,1)" ({@code Tuple2}).
91 | */
92 | public static final class Tokenizer
93 | implements FlatMapFunction> {
94 |
95 | @Override
96 | public void flatMap(String value, Collector> out) {
97 | // Normalize and split the line
98 | String[] tokens = value.toLowerCase().split("\\W+");
99 |
100 | // Emit the pairs
101 | for (String token : tokens) {
102 | if (token.length() > 0) {
103 | out.collect(new Tuple2<>(token, 1));
104 | }
105 | }
106 | }
107 | }
108 |
109 | // Implements a simple reducer using FlatMap to
110 | // reduce the Tuple2 into a single string for
111 | // writing to kafka topics
112 | public static final class Reducer
113 | implements FlatMapFunction, String> {
114 |
115 | @Override
116 | public void flatMap(Tuple2 value, Collector out) {
117 | // Convert the pairs to a string
118 | // for easy writing to Kafka Topic
119 | String count = value.f0 + " " + value.f1;
120 | out.collect(count);
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | ################################################################################
18 |
19 | rootLogger.level = INFO
20 | rootLogger.appenderRef.console.ref = ConsoleAppender
21 |
22 | appender.console.name = ConsoleAppender
23 | appender.console.type = CONSOLE
24 | appender.console.layout.type = PatternLayout
25 | appender.console.layout.pattern = %d{HH:mm:ss,SSS} %-5p %-60c %x - %m%n
26 |
--------------------------------------------------------------------------------