-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTrendDetectingForTransactions.java
More file actions
127 lines (99 loc) · 6.52 KB
/
Copy pathTrendDetectingForTransactions.java
File metadata and controls
127 lines (99 loc) · 6.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
*
* Process detecting trend pattern
*
*/
package stepProcessing_DetectingTrends;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import org.apache.kafka.common.serialization.Serde;
import org.apache.kafka.common.serialization.Serdes;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.kstream.KStream;
import org.apache.kafka.streams.kstream.KTable;
import org.apache.kafka.streams.kstream.Produced;
import org.apache.kafka.streams.kstream.TimeWindows;
import org.apache.kafka.streams.kstream.Windowed;
import org.apache.kafka.streams.kstream.internals.WindowedDeserializer;
import org.apache.kafka.streams.kstream.internals.WindowedSerializer;
import avroDetectingTrends.DetectingTrendsForTransaction;
import avroTransactionRaw.Transaction;
import io.confluent.kafka.serializers.AbstractKafkaAvroSerDeConfig;
import io.confluent.kafka.streams.serdes.avro.SpecificAvroSerde;
public class TrendDetectingForTransactions {
// The calculation example for ADX below is based on a 14-period indicator setting, as recommended by Welles Wilder.
public static int numberOfWindowsForADX = 14;
public static void main(String[] args) {
// receive stream data from
String topicNameTransactionsAvro = "RawTransactionsAvro";
// Write processed stream to
String topicNameTrendDetectingForTransactions = "TrendDetectingForTransactions";
String topicNameTrendDetectingTrendAD = "chartTrendDetectingTrendAD";
String topicNameTrendDetectingTrendRSI = "chartTrendDetectingTrendRSI";
String topicNameTrendDetectingTrendADX = "chartTrendDetectingTrendADX";
Properties properties = new Properties();
properties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
properties.put(StreamsConfig.APPLICATION_ID_CONFIG, "TrendDetecting");
properties.put(StreamsConfig.CLIENT_ID_CONFIG, "TrendDetectingClient");
// Where to find the Confluent schema registry instance(s)
properties.put(AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG, "http://localhost:8081");
// Specify default (de)serializers for record keys and for record values.
properties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
properties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, SpecificAvroSerde.class);
// When you want to override serdes explicitly/selectively. Necessary to set the schema registry url.
final Map<String, String> serdeConfig = Collections.singletonMap("schema.registry.url", "http://localhost:8081");
final Serde<DetectingTrendsForTransaction> valueSpecificAvroSerde = new SpecificAvroSerde<>();
valueSpecificAvroSerde.configure(serdeConfig, false);
// Records should be flushed every 1000ms. This is less than the default of 30seconds.
properties.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 1000);
// // Necessary SerDe to produce windowed data
StringSerializer stringSerializer = new StringSerializer();
StringDeserializer stringDeserializer = new StringDeserializer();
WindowedSerializer<String> windowedStringSerializer = new WindowedSerializer<>(stringSerializer);
WindowedDeserializer<String> windowedStringDeserializer = new WindowedDeserializer<>(stringDeserializer);
Serde<Windowed<String>> windowedStringSerde = Serdes.serdeFrom(windowedStringSerializer, windowedStringDeserializer);
final StreamsBuilder builder = new StreamsBuilder();
// Set time window in ms
long timewindowInMs = 10000;
// build stream for topicname
KStream<String, Transaction> rawTransactions = builder.stream(topicNameTransactionsAvro);
// Takes one record and produces one record or more records, while retaining the key of the original record.
// Storage necessary value of transactions for detecting trends
KStream<String, DetectingTrendsForTransaction> streamInDetectingTrendsTransactions = rawTransactions
.mapValues(value -> new DetectingTrendsForTransaction(0.0, value.getX().getTotalInput(), 0.0, 0.0, 0.0, Double.MAX_VALUE,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0L));
// Windowed aggregation. Combines the values of records, per window, by the grouped key.
// The current record value is combined with the last reduced value, and a new reduced value is returned.
// Records with null key or value are ignored. The result value type cannot be changed, unlike aggregate.
KTable<Windowed<String>, DetectingTrendsForTransaction> detectingTrendsTransactionsKTable = streamInDetectingTrendsTransactions
.selectKey((key, value) -> "keyForDetectingTrends").groupByKey()
.windowedBy(TimeWindows.of(timewindowInMs))
.aggregate(() -> new DetectingTrendsForTransaction(0.0, 0.0, 0.0, 0.0, 0.0, Double.MAX_VALUE, // Initializer
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0L), // Initializer
(aggKey, newValue, aggregate) -> new DetectingTrendsForTransaction(aggregate, newValue)); // Aggregate
// WindowedKTable to stream
KStream<Windowed<String>, DetectingTrendsForTransaction> streamOutDetectingTrendsTransactions = detectingTrendsTransactionsKTable
.toStream();
// map for charts
KStream<Windowed<String>, String> streamADforChart = streamOutDetectingTrendsTransactions.mapValues(
value -> String.valueOf(value.getTrendAdvcancedDeclineLine()));
KStream<Windowed<String>, String> streamRSIforChart = streamOutDetectingTrendsTransactions.mapValues(
value -> String.valueOf(value.getTrendRelativeStrengthIndex()));
KStream<Windowed<String>, String> streamADXforChart = streamOutDetectingTrendsTransactions.mapValues(
value -> String.valueOf(value.getTrendAverageDirectionalMovementIndex()));
// Produce stream to topic with windowedStringSerde for key
streamOutDetectingTrendsTransactions.to(topicNameTrendDetectingForTransactions, Produced.with(windowedStringSerde, valueSpecificAvroSerde));
streamADforChart.to(topicNameTrendDetectingTrendAD, Produced.with(windowedStringSerde, Serdes.String()));
streamRSIforChart.to(topicNameTrendDetectingTrendRSI, Produced.with(windowedStringSerde, Serdes.String()));
streamADXforChart.to(topicNameTrendDetectingTrendADX, Produced.with(windowedStringSerde, Serdes.String()));
KafkaStreams streams = new KafkaStreams(builder.build(), properties);
streams.cleanUp();
streams.start();
Runtime.getRuntime().addShutdownHook(new Thread(streams::close));
}
}