diff --git a/spring-integration-splunk/build.gradle b/spring-integration-splunk/build.gradle index 7313d5f..f0ae0ef 100644 --- a/spring-integration-splunk/build.gradle +++ b/spring-integration-splunk/build.gradle @@ -36,7 +36,7 @@ dependencies { compile "org.springframework:spring-context:$springVersion" compile "org.springframework:spring-expression:$springVersion" compile "org.springframework.integration:spring-integration-core:$springIntegrationVersion" - compile "commons-lang:commons-lang:$commonsLangVersion" + compile "joda-time:joda-time:$jodaTimeVersion" compile "commons-pool:commons-pool:$commonsPoolVersion" testCompile "org.mockito:mockito-all:$mockitoVersion" diff --git a/spring-integration-splunk/gradle.properties b/spring-integration-splunk/gradle.properties index 89135de..5212a02 100644 --- a/spring-integration-splunk/gradle.properties +++ b/spring-integration-splunk/gradle.properties @@ -1,10 +1,10 @@ -version=0.5.0.BUILD-SNAPSHOT +version=1.0.0.BUILD-SNAPSHOT cglibVersion=2.2 junitVersion=4.8.2 log4jVersion=1.2.12 mockitoVersion=1.9.0 -springVersion=3.1.2.RELEASE -springIntegrationVersion=2.1.2.RELEASE -commonsLangVersion=2.6 +springVersion=3.1.3.RELEASE +springIntegrationVersion=2.2.1.RELEASE +jodaTimeVersion=2.1 commonsPoolVersion=1.6 splunkVersion =1.0.0 diff --git a/spring-integration-splunk/src/main/java/org/springframework/integration/splunk/event/SplunkEvent.java b/spring-integration-splunk/src/main/java/org/springframework/integration/splunk/event/SplunkEvent.java index 4e772d3..e3725f6 100644 --- a/spring-integration-splunk/src/main/java/org/springframework/integration/splunk/event/SplunkEvent.java +++ b/spring-integration-splunk/src/main/java/org/springframework/integration/splunk/event/SplunkEvent.java @@ -17,15 +17,19 @@ package org.springframework.integration.splunk.event; import java.io.Serializable; import java.util.Date; +import java.util.HashMap; import java.util.Map; -import org.apache.commons.lang.time.FastDateFormat; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import org.springframework.util.Assert; /** * Splunk data entity * * @author Jarred Li * @author Damien Dallimore damien@dtdsoftware.com + * @author David Turanski * @since 1.0 * */ @@ -33,8 +37,6 @@ import org.apache.commons.lang.time.FastDateFormat; @SuppressWarnings("serial") public class SplunkEvent implements Serializable { - private Map eventData; - /** * Contents of the event message */ @@ -65,11 +67,11 @@ public class SplunkEvent implements Serializable { /** * default date format is using internal generated date */ - protected static final String DATEFORMATPATTERN = "yyyy-MM-dd HH:mm:ss:SSSZ"; + protected static final String DATEFORMATPATTERN = "yyyy-MM-dd\tHH:mm:ss:SSSZ"; /** - * Date Formatter instance + * Date Formatter */ - protected static FastDateFormat DATEFORMATTER = FastDateFormat.getInstance(DATEFORMATPATTERN); + protected static final DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern(DATEFORMATPATTERN); /** * Event prefix fields @@ -85,7 +87,7 @@ public class SplunkEvent implements Serializable { protected static final String THROWABLE_STACKTRACE_ELEMENTS = "stacktrace_elements"; protected static final String LINEBREAK = "\n"; - + // ---------------------------------- // Common event fields // ---------------------------------- @@ -227,26 +229,33 @@ public class SplunkEvent implements Serializable { */ public static String UPDATE_PACKAGE = "package"; - + /** + * A Constructor to load data from a Map + * @param data the map + */ public SplunkEvent(Map data) { this.eventMessage = new StringBuffer(); - this.eventData = data; for (String key : data.keySet()) { this.addPair(key, data.get(key)); } } /** - * Constructor. - * - * @param eventName - * the event name - * @param eventID - * the event id - * @param useInternalDate - * Whether or not to add a date to the event string - * @param quoteValues - * Whether or not to put quotes around values + * A Copy constructor + * @param splunkEvent + */ + public SplunkEvent(SplunkEvent splunkEvent) { + this.eventMessage = splunkEvent.eventMessage; + this.quoteValues = splunkEvent.quoteValues; + this.useInternalDate = splunkEvent.useInternalDate; + } + + /** + * Constructor to create a generic event + * @param eventName the event name + * @param eventID the event id + * @param useInternalDate whether or not to add a date to the event string + * @param quoteValues whether or not to put quotes around values */ public SplunkEvent(String eventName, String eventID, boolean useInternalDate, boolean quoteValues) { @@ -259,13 +268,10 @@ public class SplunkEvent implements Serializable { } /** - * Constructor.Will add internally generated date and put quotes around - * values. + * Constructor to create a generic event with the default format * - * @param eventName - * the event name - * @param eventID - * the event ID + * @param eventName the event name + * @param eventID the event ID */ public SplunkEvent(String eventName, String eventID) { @@ -279,20 +285,27 @@ public class SplunkEvent implements Serializable { this.eventMessage = new StringBuffer(); } - /** - * Simple shallow cloning method - */ - public SplunkEvent clone() { - SplunkEvent clone = new SplunkEvent(); - clone.quoteValues = this.quoteValues; - clone.useInternalDate = this.useInternalDate; - clone.eventMessage.append(this.eventMessage); - - return clone; - } - - public Map getEventData() { + Map eventData = new HashMap(); + String eventEntries = eventMessage.toString(); + + String[] entries = eventEntries.split(PAIRDELIM); + + String quote = new String(new char[] { QUOTE }); + + for (String entry : entries) { + String[] pair = entry.split(KVDELIM); + + Assert.isTrue(pair.length == 2, String.format("invalid event data [%s]", entry)); + + String key = pair[0].replaceAll(quote, ""); + String value = pair[1].replaceAll(quote, ""); + if ("null".equals(value)) { + value = null; + } + + eventData.put(key, value); + } return eventData; } @@ -417,7 +430,7 @@ public class SplunkEvent implements Serializable { * @param value */ public void addPair(String key, String value) { - + Assert.notNull(key, "key cannot be null"); if (quoteValues) this.eventMessage.append(key).append(KVDELIM).append(QUOTE).append(value).append(QUOTE).append(PAIRDELIM); else @@ -435,13 +448,13 @@ public class SplunkEvent implements Serializable { if (useInternalDate) { StringBuffer clonedMessage = new StringBuffer(); - clonedMessage.append(DATEFORMATTER.format(new Date())).append(PAIRDELIM).append(this.eventMessage); + clonedMessage.append(DATE_FORMATTER.print(new Date().getTime())).append(PAIRDELIM) + .append(this.eventMessage); event = clonedMessage.toString(); - } - else + } else event = eventMessage.toString(); // trim off trailing pair delim char(s) - String result = event.substring(0, event.length() - PAIRDELIM.length()) + LINEBREAK; + String result = event.substring(0, event.length() - PAIRDELIM.length()) + LINEBREAK; return result; } diff --git a/spring-integration-splunk/src/test/java/org/springframework/integration/splunk/event/SplunkEventTests.java b/spring-integration-splunk/src/test/java/org/springframework/integration/splunk/event/SplunkEventTests.java new file mode 100644 index 0000000..60da94e --- /dev/null +++ b/spring-integration-splunk/src/test/java/org/springframework/integration/splunk/event/SplunkEventTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.springframework.integration.splunk.event; +import static org.junit.Assert.*; + +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; + +/** + * @author David Turanski + * + */ +public class SplunkEventTests { + @Test + public void testGetEventData() { + Map data = new HashMap(); + data.put("foo", "foo"); + data.put("bar", null); + SplunkEvent event = new SplunkEvent(data); + Map eventData = event.getEventData(); + assertEquals(data.size(),eventData.size()); + for (String key: eventData.keySet()) { + assertEquals(data.get(key),eventData.get(key)); + } + } + public void testGetEventDataEmpty() { + SplunkEvent event = new SplunkEvent( ); + Map eventData = event.getEventData(); + assertEquals(0,eventData.size()); + } + + @Test(expected=RuntimeException.class) + public void testKeyCannotBeNull() { + SplunkEvent event = new SplunkEvent(); + event.addPair(null, "foo"); + } + + @Test + public void testCopyConstructor() { + Map data = new HashMap(); + data.put("foo", "foo"); + data.put("bar", "bar"); + SplunkEvent event = new SplunkEvent(data); + SplunkEvent event2 = new SplunkEvent(event); + assertEquals(event.quoteValues, event2.quoteValues); + assertEquals(event.useInternalDate,event2.useInternalDate); + Map eventData = event.getEventData(); + Map event2Data = event2.getEventData(); + assertEquals(eventData.size(),event2Data.size()); + for (String key: eventData.keySet()) { + assertEquals(eventData.get(key),event2Data.get(key)); + } + } +}