@@ -132,7 +132,7 @@ public void add(HecChannel channel, EventBatch batch, String response) {
132132 }
133133
134134 if (channelEvents .get (resp .getAckId ()) != null ) {
135- log .error ("ackId={} already exists for channel={} index={}" , resp .getAckId (), channel , channel .getIndexer ());
135+ log .warn ("ackId={} already exists for channel={} index={} data may be duplicated in Splunk " , resp .getAckId (), channel , channel .getIndexer ());
136136 return ;
137137 }
138138
@@ -184,6 +184,52 @@ public int getAckPollInterval() {
184184 return ackPollInterval ;
185185 }
186186
187+ /**
188+ * StickySessionHandler is used to reassign channel id and fail the batches for that HecChannel.
189+ * Also, the HecChannel will be unavailable during this period.
190+ * StickySessionHandler follows the following flow:
191+ * 1) Set channel unavailable
192+ * 2) Get batches for the channel
193+ * 3) Remove batches for the channel from the poller
194+ * 4) Remove batches from kafka record tracker to fail them and resend
195+ * 5) Remove channel
196+ * 6) Change channel id
197+ * 7) Set channel available
198+ *
199+ * @param channel HecChannel is the channel for which id has tobe changed and batches have to be failed.
200+ * @see HecChannel
201+ * @since 1.1.0
202+ */
203+ public void stickySessionHandler (HecChannel channel ) {
204+ String oldChannelId = channel .getId ();
205+ channel .setAvailable (false );
206+ log .info ("Channel {} set to be not available" , oldChannelId );
207+ ConcurrentHashMap <Long , EventBatch > channelBatches = outstandingEventBatches .get (channel );
208+ if (channelBatches != null && channelBatches .size () > 0 ) {
209+ log .info ("Failing {} batches for the channel {}, these will be resent by the connector." , channelBatches .size (), oldChannelId );
210+ if (pollerCallback != null ) {
211+ List <EventBatch > expired = new ArrayList <>();
212+ Iterator iter = channelBatches .entrySet ().iterator ();
213+ while (iter .hasNext ()) {
214+ Map .Entry <Long , EventBatch > pair = (Map .Entry ) iter .next ();
215+ EventBatch batch = pair .getValue ();
216+ totalOutstandingEventBatches .decrementAndGet ();
217+ batch .fail ();
218+ expired .add (batch );
219+ iter .remove ();
220+ }
221+ pollerCallback .onEventFailure (expired , new HecException ("sticky_session_expired" ));
222+ }
223+ }
224+ outstandingEventBatches .remove (channel );
225+ channel .setId ();
226+ String newChannelId = channel .getId ();
227+ log .info ("Changed channel id from {} to {}" , oldChannelId , newChannelId );
228+
229+ channel .setAvailable (true );
230+ log .info ("Channel {} is available" , newChannelId );
231+ }
232+
187233 private void poll () {
188234 if (totalOutstandingEventBatches .get () <= 0 || outstandingEventBatches .size () <= 0 ) {
189235 return ;
@@ -273,19 +319,22 @@ private void handleAckPollResult(HecChannel channel, HecAckPollResponse result)
273319
274320 List <EventBatch > committedBatches = new ArrayList <>();
275321 ConcurrentHashMap <Long , EventBatch > channelBatches = outstandingEventBatches .get (channel );
276- for (Long id : ids ) {
277- EventBatch batch = channelBatches .remove (id );
278- if (batch == null ) {
279- log .warn ("event batch id={} for channel={} on host={} is not in map anymore" , id , channel , channel .getIndexer ());
280- continue ;
322+ // Added null check as channelBatches might still be null(It may be removed while handling sticky sessions and not added until we send more data)
323+ if (channelBatches != null ) {
324+ for (Long id : ids ) {
325+ EventBatch batch = channelBatches .remove (id );
326+ if (batch == null ) {
327+ log .warn ("event batch id={} for channel={} on host={} is not in map anymore" , id , channel , channel .getIndexer ());
328+ continue ;
329+ }
330+ totalOutstandingEventBatches .decrementAndGet ();
331+ batch .commit ();
332+ committedBatches .add (batch );
281333 }
282- totalOutstandingEventBatches .decrementAndGet ();
283- batch .commit ();
284- committedBatches .add (batch );
285- }
286334
287- if (!committedBatches .isEmpty () && pollerCallback != null ) {
288- pollerCallback .onEventCommitted (committedBatches );
335+ if (!committedBatches .isEmpty () && pollerCallback != null ) {
336+ pollerCallback .onEventCommitted (committedBatches );
337+ }
289338 }
290339 }
291340
0 commit comments