Skip to content

Commit 44c9d9a

Browse files
authored
Merge pull request splunk#403 from mo-mosh/develop
added a timestamp.timezone configuration in SplunkSinkConnectorConfig
2 parents 2372eb4 + 1c6a738 commit 44c9d9a

File tree

5 files changed

+75
-4
lines changed

5 files changed

+75
-4
lines changed

dependency-reduced-pom.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,3 @@
204204
<junit.platform.version>1.3.2</junit.platform.version>
205205
</properties>
206206
</project>
207-

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,4 +342,4 @@
342342

343343
</plugins>
344344
</build>
345-
</project>
345+
</project>

src/main/java/com/splunk/kafka/connect/SplunkSinkConnectorConfig.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public final class SplunkSinkConnectorConfig extends AbstractConfig {
9898
static final String ENABLE_TIMESTAMP_EXTRACTION_CONF = "enable.timestamp.extraction";
9999
static final String REGEX_CONF = "timestamp.regex";
100100
static final String TIMESTAMP_FORMAT_CONF = "timestamp.format";
101+
static final String TIMESTAMP_TIMEZONE_CONF = "timestamp.timezone";
101102

102103
// Kafka configuration description strings
103104
// Required Parameters
@@ -206,6 +207,7 @@ public final class SplunkSinkConnectorConfig extends AbstractConfig {
206207
static final String ENABLE_TIMESTAMP_EXTRACTION_DOC = "Set to true if you want to extract the timestamp";
207208
static final String REGEX_DOC = "Regex";
208209
static final String TIMESTAMP_FORMAT_DOC = "Timestamp format";
210+
static final String TIMESTAMP_TIMEZONE_DOC = "Timestamp timezone";
209211

210212
final String splunkToken;
211213
final String splunkURI;
@@ -263,6 +265,8 @@ public final class SplunkSinkConnectorConfig extends AbstractConfig {
263265
final String timestampFormat;
264266
final int queueCapacity;
265267

268+
final String timeZone;
269+
266270
SplunkSinkConnectorConfig(Map<String, String> taskConfig) {
267271
super(conf(), taskConfig);
268272
splunkToken = getPassword(TOKEN_CONF).value();
@@ -316,6 +320,7 @@ public final class SplunkSinkConnectorConfig extends AbstractConfig {
316320
enableTimestampExtraction = getBoolean(ENABLE_TIMESTAMP_EXTRACTION_CONF);
317321
regex = getString(REGEX_CONF);
318322
timestampFormat = getString(TIMESTAMP_FORMAT_CONF).trim();
323+
timeZone = getString(TIMESTAMP_TIMEZONE_CONF);
319324
validateRegexForTimestamp(regex);
320325
queueCapacity = getInt(QUEUE_CAPACITY_CONF);
321326
validateQueueCapacity(queueCapacity);
@@ -367,7 +372,8 @@ public static ConfigDef conf() {
367372
.define(ENABLE_TIMESTAMP_EXTRACTION_CONF, ConfigDef.Type.BOOLEAN, false , ConfigDef.Importance.MEDIUM, ENABLE_TIMESTAMP_EXTRACTION_DOC)
368373
.define(REGEX_CONF, ConfigDef.Type.STRING, "" , ConfigDef.Importance.MEDIUM, REGEX_DOC)
369374
.define(TIMESTAMP_FORMAT_CONF, ConfigDef.Type.STRING, "", ConfigDef.Importance.MEDIUM, TIMESTAMP_FORMAT_DOC)
370-
.define(QUEUE_CAPACITY_CONF, ConfigDef.Type.INT, 100, ConfigDef.Importance.LOW, QUEUE_CAPACITY_DOC);
375+
.define(TIMESTAMP_TIMEZONE_CONF, ConfigDef.Type.STRING, "", ConfigDef.Importance.MEDIUM, TIMESTAMP_TIMEZONE_DOC)
376+
.define(QUEUE_CAPACITY_CONF, ConfigDef.Type.INT, 100, ConfigDef.Importance.LOW, QUEUE_CAPACITY_DOC);
371377
}
372378

373379
/**

src/main/java/com/splunk/kafka/connect/SplunkSinkTask.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,12 @@ private void timestampExtraction(Event event) {
579579
}
580580
} else {
581581
SimpleDateFormat df = new SimpleDateFormat(connectorConfig.timestampFormat);
582+
df.setTimeZone(TimeZone.getTimeZone("UTC"));
582583
Date date;
583584
try {
585+
if(!connectorConfig.timeZone.isEmpty())
586+
df.setTimeZone(TimeZone.getTimeZone(connectorConfig.timeZone));
587+
584588
date = df.parse(timestamp);
585589
event.setTime(date.getTime() / 1000.0);
586590
} catch (ParseException e) {

src/test/java/com/splunk/kafka/connect/SplunkSinkTaskTest.java

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,69 @@ public void checkExtractedTimestamp() {
274274
}
275275
task.stop();
276276
}
277-
277+
278+
@Test
279+
public void checkExtractedTimestampWithTimezone() {
280+
SplunkSinkTask task = new SplunkSinkTask();
281+
Collection<SinkRecord> record = createSinkRecords(1,"{\"id\": \"19\",\"host\":\"host-01\",\"source\":\"bu\",\"fields\":{\"hn\":\"hostname1\",\"CLASS\":\"class1\",\"cust_id\":\"000013934\",\"REQ_TIME\": \"20230904133016993\",\"category\":\"IFdata\",\"ifname\":\"LoopBack7\",\"IFdata.Bits received\":\"0\",\"IFdata.Bits sent\":\"0\"}");
282+
283+
UnitUtil uu = new UnitUtil(0);
284+
Map<String, String> config = uu.createTaskConfig();
285+
config.put(SplunkSinkConnectorConfig.RAW_CONF, String.valueOf(false));
286+
config.put(SplunkSinkConnectorConfig.ENABLE_TIMESTAMP_EXTRACTION_CONF, String.valueOf(true));
287+
config.put(SplunkSinkConnectorConfig.REGEX_CONF, "\\\"REQ_TIME\\\":\\s*\\\"(?<time>.*?)\"");
288+
config.put(SplunkSinkConnectorConfig.TIMESTAMP_FORMAT_CONF, "yyyyMMddHHmmssSSS");
289+
config.put(SplunkSinkConnectorConfig.TIMESTAMP_TIMEZONE_CONF, "Asia/Seoul");
290+
HecMock hec = new HecMock(task);
291+
hec.setSendReturnResult(HecMock.success);
292+
task.setHec(hec);
293+
task.start(config);
294+
task.put(record);
295+
296+
List<EventBatch> batches = hec.getBatches();
297+
for (Iterator<EventBatch> iter = batches.listIterator(); iter.hasNext();) {
298+
EventBatch batch = iter.next();
299+
List<Event> event_list = batch.getEvents();
300+
Iterator<Event> iterator = event_list.listIterator() ;
301+
Event event = iterator.next();
302+
303+
Assert.assertEquals(1.693801816993E9, event.getTime(), 0);
304+
break;
305+
}
306+
task.stop();
307+
}
308+
309+
@Test
310+
public void checkExtractedTimestampWithoutTimezoneAsUTC() {
311+
SplunkSinkTask task = new SplunkSinkTask();
312+
Collection<SinkRecord> record = createSinkRecords(1,"{\"id\": \"19\",\"host\":\"host-01\",\"source\":\"bu\",\"fields\":{\"hn\":\"hostname1\",\"CLASS\":\"class1\",\"cust_id\":\"000013934\",\"REQ_TIME\": \"20230904133016993\",\"category\":\"IFdata\",\"ifname\":\"LoopBack7\",\"IFdata.Bits received\":\"0\",\"IFdata.Bits sent\":\"0\"}");
313+
314+
UnitUtil uu = new UnitUtil(0);
315+
Map<String, String> config = uu.createTaskConfig();
316+
config.put(SplunkSinkConnectorConfig.RAW_CONF, String.valueOf(false));
317+
config.put(SplunkSinkConnectorConfig.ENABLE_TIMESTAMP_EXTRACTION_CONF, String.valueOf(true));
318+
config.put(SplunkSinkConnectorConfig.REGEX_CONF, "\\\"REQ_TIME\\\":\\s*\\\"(?<time>.*?)\"");
319+
config.put(SplunkSinkConnectorConfig.TIMESTAMP_FORMAT_CONF, "yyyyMMddHHmmssSSS");
320+
config.put(SplunkSinkConnectorConfig.TIMESTAMP_TIMEZONE_CONF, "");
321+
HecMock hec = new HecMock(task);
322+
hec.setSendReturnResult(HecMock.success);
323+
task.setHec(hec);
324+
task.start(config);
325+
task.put(record);
326+
327+
List<EventBatch> batches = hec.getBatches();
328+
for (Iterator<EventBatch> iter = batches.listIterator(); iter.hasNext();) {
329+
EventBatch batch = iter.next();
330+
List<Event> event_list = batch.getEvents();
331+
Iterator<Event> iterator = event_list.listIterator() ;
332+
Event event = iterator.next();
333+
334+
Assert.assertEquals(1.693834216993E9, event.getTime(), 0);
335+
break;
336+
}
337+
task.stop();
338+
}
339+
278340
@Test(expected = ConfigException.class)
279341
public void emptyRegex() {
280342
SplunkSinkTask task = new SplunkSinkTask();

0 commit comments

Comments
 (0)