99
1010import static org .phoebus .applications .alarm .AlarmSystem .logger ;
1111
12+ import java .io .FileInputStream ;
13+ import java .io .IOException ;
1214import java .util .Collection ;
1315import java .util .List ;
1416import java .util .Properties ;
1517import java .util .UUID ;
18+ import java .util .logging .Level ;
1619
1720import org .apache .kafka .clients .consumer .Consumer ;
1821import org .apache .kafka .clients .consumer .ConsumerRebalanceListener ;
@@ -51,24 +54,28 @@ public class KafkaHelper
5154 * @param kafka_servers Servers to read
5255 * @param topics Topics to which to subscribe
5356 * @param from_beginning Topics to read from the beginning
57+ * @param properties_file File name to load additional settings for the kafka consumer
5458 * @return {@link Consumer}
5559 */
56- public static Consumer <String , String > connectConsumer (final String kafka_servers , final List <String > topics , final List <String > from_beginning )
60+ public static Consumer <String , String > connectConsumer (final String kafka_servers , final List <String > topics , final List <String > from_beginning , final String properties_file )
5761 {
58- final Properties props = new Properties ();
59- props .put ("bootstrap.servers" , kafka_servers );
60- // API requires for Consumer to be in a group.
61- // Each alarm client must receive all updates,
62- // cannot balance updates across a group
63- // --> Use unique group for each client
64- final String group_id = "Alarm-" + UUID .randomUUID ();
65- props .put ("group.id" , group_id );
62+ Properties kafka_props = loadPropsFromFile (properties_file );
63+ kafka_props .put ("bootstrap.servers" , kafka_servers );
6664
67- logger .fine (group_id + " subscribes to " + kafka_servers + " for " + topics );
65+ if (!kafka_props .containsKey ("group.id" )){
66+ // API requires for Consumer to be in a group.
67+ // Each alarm client must receive all updates,
68+ // cannot balance updates across a group
69+ // --> Use unique group for each client
70+ final String group_id = "Alarm-" + UUID .randomUUID ();
71+ kafka_props .put ("group.id" , group_id );
72+ }
73+
74+ logger .fine (kafka_props .getProperty ("group.id" ) + " subscribes to " + kafka_servers + " for " + topics );
6875
6976 // Read key, value as string
7077 final Deserializer <String > deserializer = new StringDeserializer ();
71- final Consumer <String , String > consumer = new KafkaConsumer <>(props , deserializer , deserializer );
78+ final Consumer <String , String > consumer = new KafkaConsumer <>(kafka_props , deserializer , deserializer );
7279
7380 // Rewind whenever assigned to partition
7481 final ConsumerRebalanceListener crl = new ConsumerRebalanceListener ()
@@ -101,19 +108,20 @@ public void onPartitionsRevoked(final Collection<TopicPartition> parts)
101108
102109 /** Create producer for alarm information
103110 * @param kafka_servers Kafka servers
111+ * @param properties_file File name to load additional settings for the kafka producer
104112 * @return {@link Producer}
105113 */
106- public static Producer <String , String > connectProducer (final String kafka_servers )
114+ public static Producer <String , String > connectProducer (final String kafka_servers , final String properties_file )
107115 {
108- final Properties props = new Properties ( );
109- props .put ("bootstrap.servers" , kafka_servers );
116+ Properties kafka_props = loadPropsFromFile ( properties_file );
117+ kafka_props .put ("bootstrap.servers" , kafka_servers );
110118 // Collect messages for 20ms until sending them out as a batch
111- props .put ("linger.ms" , 20 );
119+ kafka_props .put ("linger.ms" , 20 );
112120
113121 // Write String key, value
114122 final Serializer <String > serializer = new StringSerializer ();
115123
116- final Producer <String , String > producer = new KafkaProducer <>(props , serializer , serializer );
124+ final Producer <String , String > producer = new KafkaProducer <>(kafka_props , serializer , serializer );
117125
118126 return producer ;
119127 }
@@ -123,22 +131,43 @@ public static Producer<String, String> connectProducer(final String kafka_server
123131 * @param kafka_servers - Sever to connect to.
124132 * @param topics List of topics to aggregate.
125133 * @param aggregate_topic - Name of topic to aggregate to.
134+ * @param kafka_props File name to load additional settings for the kafka stream
126135 * @return aggregate_stream - KafkaStreams
127136 * @author Evan Smith
128137 */
129- public static KafkaStreams aggregateTopics (String kafka_servers , List <String > topics , String aggregate_topic )
138+ public static KafkaStreams aggregateTopics (String kafka_servers , List <String > topics , String aggregate_topic , final String properties_file )
130139 {
131- final Properties props = new Properties ( );
132- props .put (StreamsConfig .APPLICATION_ID_CONFIG , "Stream-To-Long-Term" );
133- props .put (StreamsConfig .BOOTSTRAP_SERVERS_CONFIG , kafka_servers );
134- props .put (StreamsConfig .DEFAULT_KEY_SERDE_CLASS_CONFIG , Serdes .String ().getClass ());
135- props .put (StreamsConfig .DEFAULT_VALUE_SERDE_CLASS_CONFIG , Serdes .String ().getClass ());
140+ Properties kafka_props = loadPropsFromFile ( properties_file );
141+ kafka_props .put (StreamsConfig .APPLICATION_ID_CONFIG , "Stream-To-Long-Term" );
142+ kafka_props .put (StreamsConfig .BOOTSTRAP_SERVERS_CONFIG , kafka_servers );
143+ kafka_props .put (StreamsConfig .DEFAULT_KEY_SERDE_CLASS_CONFIG , Serdes .String ().getClass ());
144+ kafka_props .put (StreamsConfig .DEFAULT_VALUE_SERDE_CLASS_CONFIG , Serdes .String ().getClass ());
136145
137146 final StreamsBuilder builder = new StreamsBuilder ();
138147
139148 // Aggregate the topics by mapping the topic key value pairs one to one into the aggregate topic.
140149 builder .<String , String >stream (topics ).mapValues (pair -> pair ).to (aggregate_topic );
141150
142- return new KafkaStreams (builder .build (), props );
151+ return new KafkaStreams (builder .build (), kafka_props );
152+ }
153+
154+
155+ /**
156+ * Load properties from the given file path. Path may be blank or null
157+ * resulting in a properties object without entries.
158+ * @param filePath Full path to properties file
159+ * @return properties - the properties loaded from file
160+ */
161+ static public Properties loadPropsFromFile (String filePath ) {
162+ logger .fine ("loading file from path: " + filePath );
163+ Properties properties = new Properties ();
164+ if (filePath != null && !filePath .isBlank ()){
165+ try (FileInputStream file = new FileInputStream (filePath );){
166+ properties .load (file );
167+ } catch (IOException e ) {
168+ logger .log (Level .SEVERE , "failed to load kafka properties" , e );
169+ }
170+ }
171+ return properties ;
143172 }
144173}
0 commit comments