From ed07de54653c164ee059a7ffd03f12385e40c07e Mon Sep 17 00:00:00 2001 From: 0xNB Date: Mon, 16 Aug 2021 14:22:18 +0200 Subject: [PATCH 1/2] add stub test and exception for HttpEventCollectorSender --- .../HttpEventCollectorErrorHandler.java | 44 +++++++++++++++---- .../logging/HttpEventCollectorSender.java | 37 +++++++++++++--- .../logging/HttpEventCollectorSenderTest.java | 4 ++ 3 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 src/test/java/com/splunk/logging/HttpEventCollectorSenderTest.java diff --git a/src/main/java/com/splunk/logging/HttpEventCollectorErrorHandler.java b/src/main/java/com/splunk/logging/HttpEventCollectorErrorHandler.java index b8e1074c..adebaa72 100644 --- a/src/main/java/com/splunk/logging/HttpEventCollectorErrorHandler.java +++ b/src/main/java/com/splunk/logging/HttpEventCollectorErrorHandler.java @@ -1,16 +1,14 @@ package com.splunk.logging; /** - * @copyright - * - * Copyright 2013-2015 Splunk, Inc. - * + * @copyright Copyright 2013-2015 Splunk, Inc. + *

* 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 - * + *

+ * 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 @@ -36,6 +34,35 @@ */ public class HttpEventCollectorErrorHandler { + + /** + * This exception is passed to error callback when Splunk fails to flush events + */ + public static class FlushException extends Exception { + private int numMsg; + private String errorText; + + /** + * Create an exception with number of messages that couldn't be flushed properly + * + * @param numMsg number of messages + */ + public FlushException(final int numMsg) { + this.errorText = "There was an exception flushing [" + numMsg + "] events!"; + } + + @Override + public String getMessage() { + return String.valueOf(numMsg); + } + + + @Override + public String toString() { + return getMessage(); + } + } + /** * This exception is passed to error callback when Splunk server replies an error */ @@ -88,7 +115,8 @@ public String getMessage() { } - @Override public String toString() { + @Override + public String toString() { return getReply(); } } diff --git a/src/main/java/com/splunk/logging/HttpEventCollectorSender.java b/src/main/java/com/splunk/logging/HttpEventCollectorSender.java index 960640f5..6498adbd 100644 --- a/src/main/java/com/splunk/logging/HttpEventCollectorSender.java +++ b/src/main/java/com/splunk/logging/HttpEventCollectorSender.java @@ -29,6 +29,7 @@ import java.io.Serializable; import java.security.cert.CertificateException; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @@ -46,6 +47,8 @@ public class HttpEventCollectorSender extends TimerTask implements HttpEventColl private static final String SendModeSequential = "sequential"; private static final String SendModeSParallel = "parallel"; private TimeoutSettings timeoutSettings = new TimeoutSettings(); + private static final int MaxFlushRetries = 5; + private static final AtomicInteger FlushRetries = new AtomicInteger(0); // allow flushing up to 5 times until messages in buffer are cleared. private static final Gson gson = new GsonBuilder() .registerTypeAdapter(HttpEventCollectorEventInfo.class, new EventInfoTypeAdapter()) .create(); @@ -62,7 +65,7 @@ public enum SendMode { Sequential, Parallel - }; + } /** * Recommended default values for events batching. @@ -176,11 +179,15 @@ public synchronized void send( final String exception_message, Serializable marker ) { - // create event info container and add it to the batch - HttpEventCollectorEventInfo eventInfo = - new HttpEventCollectorEventInfo(timeMsSinceEpoch, severity, message, logger_name, thread_name, properties, exception_message, marker); - eventsBatch.add(eventInfo); - eventsBatchSize += severity.length() + message.length(); + // check whether message or severity are null + if (message != null && severity != null) { + // create event info container and add it to the batch + HttpEventCollectorEventInfo eventInfo = + new HttpEventCollectorEventInfo(timeMsSinceEpoch, severity, message, logger_name, thread_name, properties, exception_message, marker); + eventsBatch.add(eventInfo); + eventsBatchSize += severity.length() + message.length(); + } + // flush anyway on message since last flush could have caused exception if (eventsBatch.size() >= maxEventsBatchCount || eventsBatchSize > maxEventsBatchSize) { flush(); } @@ -199,7 +206,23 @@ public synchronized void send(final String message) { */ public synchronized void flush() { if (eventsBatch.size() > 0) { - postEventsAsync(eventsBatch); + try { + postEventsAsync(eventsBatch); + } + catch (Exception e) { + // log error, update max retries + HttpEventCollectorErrorHandler.error( + eventsBatch, + new HttpEventCollectorErrorHandler.FlushException(eventsBatch.size())); + if(FlushRetries.getAndIncrement() < MaxFlushRetries) { + // do _not_ clear events list in this case since error could be network connection or some other fault + return; + } + else { + // max retries reached reset counter + FlushRetries.set(0); + } + } } // Clear the batch. A new list should be created because events are // sending asynchronously and "previous" instance of eventsBatch object diff --git a/src/test/java/com/splunk/logging/HttpEventCollectorSenderTest.java b/src/test/java/com/splunk/logging/HttpEventCollectorSenderTest.java new file mode 100644 index 00000000..0fbe6f3d --- /dev/null +++ b/src/test/java/com/splunk/logging/HttpEventCollectorSenderTest.java @@ -0,0 +1,4 @@ +package com.splunk.logging; + +public class HttpEventCollectorSenderTest { +} From 8e0aaa6ce8c553ee87b96cf37fbf57ea6599faf3 Mon Sep 17 00:00:00 2001 From: 0xNB Date: Mon, 16 Aug 2021 15:31:38 +0200 Subject: [PATCH 2/2] flush exception handling and tests --- pom.xml | 16 +- .../logging/HttpEventCollectorSender.java | 20 +- .../logging/HttpEventCollectorSenderTest.java | 58 + .../logging}/HttpEventCollectorUnitTest.java | 29 +- .../HttpEventCollectorUnitTestMiddleware.java | 2 + .../HttpEventCollector_JavaLoggingTest.java | 10 +- .../HttpEventCollector_Log4j2Test.java | 4 +- .../HttpEventCollector_LogbackTest.java | 4 +- .../logging}/HttpEventCollector_Test.java | 49 +- .../splunk/logging}/HttpLoggerStressTest.java | 2 + .../splunk/logging}/JULFunctionalTest.java | 8 +- .../splunk/logging}/Log4jFunctionalTest.java | 2 +- .../logging}/LogbackFunctionalTest.java | 2 +- .../logging}/SplunkCimLogEventUnitTest.java | 10 +- .../logging}/TestEventBodySerializer.java | 2 +- .../logging}/TestEventHeaderSerializer.java | 2 +- .../splunk/logging}/TestFormatter.java | 2 +- .../{ => com/splunk/logging}/TestUtil.java | 1062 ++++++++--------- .../java/{ => com/splunk/logging}/Util.java | 2 +- src/test/resources/jdklogging.properties | 2 +- src/test/resources/log4j2.xml | 2 +- src/test/resources/logback.xml | 2 +- .../resources/logging_template.properties | 2 +- 23 files changed, 677 insertions(+), 617 deletions(-) rename src/test/java/{ => com/splunk/logging}/HttpEventCollectorUnitTest.java (95%) rename src/test/java/{ => com/splunk/logging}/HttpEventCollectorUnitTestMiddleware.java (98%) rename src/test/java/{ => com/splunk/logging}/HttpEventCollector_JavaLoggingTest.java (98%) rename src/test/java/{ => com/splunk/logging}/HttpEventCollector_Log4j2Test.java (99%) rename src/test/java/{ => com/splunk/logging}/HttpEventCollector_LogbackTest.java (99%) rename src/test/java/{ => com/splunk/logging}/HttpEventCollector_Test.java (90%) rename src/test/java/{ => com/splunk/logging}/HttpLoggerStressTest.java (99%) rename src/test/java/{ => com/splunk/logging}/JULFunctionalTest.java (88%) rename src/test/java/{ => com/splunk/logging}/Log4jFunctionalTest.java (97%) rename src/test/java/{ => com/splunk/logging}/LogbackFunctionalTest.java (97%) rename src/test/java/{ => com/splunk/logging}/SplunkCimLogEventUnitTest.java (94%) rename src/test/java/{ => com/splunk/logging}/TestEventBodySerializer.java (97%) rename src/test/java/{ => com/splunk/logging}/TestEventHeaderSerializer.java (97%) rename src/test/java/{ => com/splunk/logging}/TestFormatter.java (97%) rename src/test/java/{ => com/splunk/logging}/TestUtil.java (97%) rename src/test/java/{ => com/splunk/logging}/Util.java (99%) diff --git a/pom.xml b/pom.xml index 185d0cc0..bd67372f 100644 --- a/pom.xml +++ b/pom.xml @@ -131,7 +131,7 @@ 2.22.2 - **/HttpEventCollectorUnitTest.class + **/com.splunk.logging.HttpEventCollectorUnitTest.class @@ -148,7 +148,7 @@ 2.22.2 - **/HttpLoggerStressTest.class + **/com.splunk.logging.HttpLoggerStressTest.class @@ -180,6 +180,18 @@ 4.13.2 test + + org.mockito + mockito-core + 3.11.2 + test + + + org.hamcrest + hamcrest-all + 1.3 + test + org.slf4j slf4j-api diff --git a/src/main/java/com/splunk/logging/HttpEventCollectorSender.java b/src/main/java/com/splunk/logging/HttpEventCollectorSender.java index 6498adbd..c67c3962 100644 --- a/src/main/java/com/splunk/logging/HttpEventCollectorSender.java +++ b/src/main/java/com/splunk/logging/HttpEventCollectorSender.java @@ -44,8 +44,6 @@ public class HttpEventCollectorSender extends TimerTask implements HttpEventColl private static final String HttpRawCollectorUriPath = "/services/collector/raw"; private static final String JsonHttpContentType = "application/json; profile=urn:splunk:event:1.0; charset=utf-8"; private static final String PlainTextHttpContentType = "plain/text; charset=utf-8"; - private static final String SendModeSequential = "sequential"; - private static final String SendModeSParallel = "parallel"; private TimeoutSettings timeoutSettings = new TimeoutSettings(); private static final int MaxFlushRetries = 5; private static final AtomicInteger FlushRetries = new AtomicInteger(0); // allow flushing up to 5 times until messages in buffer are cleared. @@ -74,6 +72,12 @@ public enum SendMode public static final int DefaultBatchSize = 10 * 1024; // 10KB public static final int DefaultBatchCount = 10; // 10 events + /** + * Send modes to choose from + */ + public static final String SendModeSequential = "sequential"; + public static final String SendModeSParallel = "parallel"; + private HttpUrl url; private String token; private String channel; @@ -214,7 +218,7 @@ public synchronized void flush() { HttpEventCollectorErrorHandler.error( eventsBatch, new HttpEventCollectorErrorHandler.FlushException(eventsBatch.size())); - if(FlushRetries.getAndIncrement() < MaxFlushRetries) { + if(FlushRetries.incrementAndGet() < MaxFlushRetries) { // do _not_ clear events list in this case since error could be network connection or some other fault return; } @@ -344,7 +348,7 @@ public boolean verify(String hostname, SSLSession session) { httpClient = builder.build(); } - private void postEventsAsync(final List events) { + protected void postEventsAsync(final List events) { this.middleware.postEvents(events, this, new HttpEventCollectorMiddleware.IHttpSenderCallback() { @Override @@ -411,6 +415,14 @@ public void onFailure(Call call, IOException ex) { }); } + public static int getMaxFlushRetries() { + return MaxFlushRetries; + } + + protected int getCurrentEventsBatchSize() { + return eventsBatch.size(); + } + public static class TimeoutSettings { public static final long DEFAULT_CONNECT_TIMEOUT = 30000; public static final long DEFAULT_WRITE_TIMEOUT = 0; // 0 means no timeout diff --git a/src/test/java/com/splunk/logging/HttpEventCollectorSenderTest.java b/src/test/java/com/splunk/logging/HttpEventCollectorSenderTest.java index 0fbe6f3d..dcc8edfa 100644 --- a/src/test/java/com/splunk/logging/HttpEventCollectorSenderTest.java +++ b/src/test/java/com/splunk/logging/HttpEventCollectorSenderTest.java @@ -1,4 +1,62 @@ package com.splunk.logging; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import static org.hamcrest.MatcherAssert.assertThat; + public class HttpEventCollectorSenderTest { + + + final int maxFlushRetries = HttpEventCollectorSender.getMaxFlushRetries(); + HttpEventCollectorSender httpEventCollectorSender; + final List exceptionsThatOccured = new LinkedList<>(); + + @Before + public void setupHttpSender() { + httpEventCollectorSender = new HttpEventCollectorSender("", "", "", "", 0L, 3, 20000, HttpEventCollectorSender.SendModeSequential, new HashMap<>(), null); + + httpEventCollectorSender = Mockito.spy(httpEventCollectorSender); + Mockito.doAnswer(invocationOnMock -> { + throw new NullPointerException("something bad happened"); + }).when(httpEventCollectorSender).postEventsAsync(Mockito.anyList()); + + HttpEventCollectorErrorHandler.onError((data, ex) -> exceptionsThatOccured.add(ex)); + } + + + @Test + public void testFlushRetries() { + httpEventCollectorSender.send("some random message"); + httpEventCollectorSender.send("some random message"); + Mockito.verify(httpEventCollectorSender, Mockito.times(0)).flush(); + httpEventCollectorSender.send("some random message"); + Mockito.verify(httpEventCollectorSender, Mockito.times(1)).flush(); + + assertThat(httpEventCollectorSender.getCurrentEventsBatchSize(), Matchers.is(3)); + assertThat(exceptionsThatOccured, Matchers.hasSize(1)); + + // generate more until retry limit is hit + for (int i = 0; i < maxFlushRetries - 1; i++) { + httpEventCollectorSender.send("some random message"); + } + + assertThat(exceptionsThatOccured, Matchers.hasSize(5)); + assertThat(httpEventCollectorSender.getCurrentEventsBatchSize(), Matchers.is(0)); + + Mockito.doNothing().when(httpEventCollectorSender).postEventsAsync(Mockito.anyList()); + + for (int i = 0; i < 500; i++) { + httpEventCollectorSender.send("some random message"); + } + + assertThat(exceptionsThatOccured, Matchers.hasSize(5)); + + } } diff --git a/src/test/java/HttpEventCollectorUnitTest.java b/src/test/java/com/splunk/logging/HttpEventCollectorUnitTest.java similarity index 95% rename from src/test/java/HttpEventCollectorUnitTest.java rename to src/test/java/com/splunk/logging/HttpEventCollectorUnitTest.java index 2961934b..1aa88f50 100644 --- a/src/test/java/HttpEventCollectorUnitTest.java +++ b/src/test/java/com/splunk/logging/HttpEventCollectorUnitTest.java @@ -1,4 +1,4 @@ -/** +package com.splunk.logging; /** * @copyright * * Copyright 2013-2015 Splunk, Inc. @@ -17,21 +17,14 @@ */ import java.io.IOException; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import com.splunk.logging.HttpEventCollectorErrorHandler; -import com.splunk.logging.HttpEventCollectorEventInfo; import org.junit.Assert; import org.junit.Test; -import sun.rmi.runtime.Log; import java.io.ByteArrayInputStream; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.logging.LogManager; -import java.util.logging.Logger; public class HttpEventCollectorUnitTest { @Test @@ -40,7 +33,7 @@ public void log4j_simple() throws Exception { String loggerName = "splunk.log4jSimple"; userInputs.put("user_logger_name", loggerName); userInputs.put("user_httpEventCollector_token", "11111111-2222-3333-4444-555555555555"); - userInputs.put("user_middleware", "HttpEventCollectorUnitTestMiddleware"); + userInputs.put("user_middleware", "com.splunk.logging.HttpEventCollectorUnitTestMiddleware"); userInputs.put("user_batch_size_count", "1"); userInputs.put("user_batch_size_bytes", "0"); userInputs.put("user_eventBodySerializer", "DoesNotExistButShouldNotCrashTest"); @@ -72,7 +65,7 @@ public void logback_simple() throws Exception { final String loggerName = "splunk.logback"; userInputs.put("user_logger_name", loggerName); userInputs.put("user_httpEventCollector_token", "11111111-2222-3333-4444-555555555555"); - userInputs.put("user_middleware", "HttpEventCollectorUnitTestMiddleware"); + userInputs.put("user_middleware", "com.splunk.logging.HttpEventCollectorUnitTestMiddleware"); userInputs.put("user_eventBodySerializer", "DoesNotExistButShouldNotCrashTest"); userInputs.put("user_eventHeaderSerializer", "DoesNotExistButShouldNotCrashTest"); TestUtil.resetLogbackConfiguration("logback_template.xml", "logback.xml", userInputs); @@ -105,7 +98,7 @@ public void java_util_logger_simple() { "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_count=0\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_bytes=0\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_interval=0\n" + - "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=HttpEventCollectorUnitTestMiddleware\n" + + "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=com.splunk.logging.HttpEventCollectorUnitTestMiddleware\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.eventBodySerializer=DoesNotExistButShouldNotCrashTest\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.eventHeaderSerializer=DoesNotExistButShouldNotCrashTest\n" ); @@ -136,7 +129,7 @@ public void java_util_logger_error_handler() { "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_count=0\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_bytes=0\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_interval=0\n" + - "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=HttpEventCollectorUnitTestMiddleware\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=com.splunk.logging.HttpEventCollectorUnitTestMiddleware\n" ); // mimic server 404 @@ -168,7 +161,7 @@ public void java_util_logger_resend() { "handlers=com.splunk.logging.HttpEventCollectorLoggingHandler\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.url=http://localhost:8088\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.token=TOKEN\n" + - "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=HttpEventCollectorUnitTestMiddleware\n" + + "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=com.splunk.logging.HttpEventCollectorUnitTestMiddleware\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_count=0\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_bytes=0\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_interval=0\n" + @@ -211,7 +204,7 @@ public void java_util_logger_resend_max_retries() { "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_count=0\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_bytes=0\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_interval=0\n" + - "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=HttpEventCollectorUnitTestMiddleware\n" + + "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=com.splunk.logging.HttpEventCollectorUnitTestMiddleware\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.retries_on_error=2\n" ); @@ -246,7 +239,7 @@ public void java_util_logger_batching() { "handlers=com.splunk.logging.HttpEventCollectorLoggingHandler\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.url=http://localhost:8088\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.token=TOKEN\n" + - "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=HttpEventCollectorUnitTestMiddleware\n" + + "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=com.splunk.logging.HttpEventCollectorUnitTestMiddleware\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.batch_size_count=3\n" ); @@ -273,7 +266,7 @@ public void java_util_logger_batching_default_count() { "handlers=com.splunk.logging.HttpEventCollectorLoggingHandler\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.url=http://localhost:8088\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.token=TOKEN\n" + - "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=HttpEventCollectorUnitTestMiddleware\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=com.splunk.logging.HttpEventCollectorUnitTestMiddleware\n" ); final int DefaultBatchCount = 10; HttpEventCollectorUnitTestMiddleware.eventsReceived = 0; @@ -296,7 +289,7 @@ public void java_util_logger_batching_default_size() { "handlers=com.splunk.logging.HttpEventCollectorLoggingHandler\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.url=http://localhost:8088\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.token=TOKEN\n" + - "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=HttpEventCollectorUnitTestMiddleware\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=com.splunk.logging.HttpEventCollectorUnitTestMiddleware\n" ); final int DefaultBatchSize = 10 * 1024; HttpEventCollectorUnitTestMiddleware.eventsReceived = 0; @@ -319,7 +312,7 @@ public void java_util_logger_batching_default_interval() { "handlers=com.splunk.logging.HttpEventCollectorLoggingHandler\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.url=http://localhost:8088\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.token=TOKEN\n" + - "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=HttpEventCollectorUnitTestMiddleware\n" + "com.splunk.logging.HttpEventCollectorLoggingHandler.middleware=com.splunk.logging.HttpEventCollectorUnitTestMiddleware\n" ); final int DefaultInterval = 10000; HttpEventCollectorUnitTestMiddleware.eventsReceived = 0; diff --git a/src/test/java/HttpEventCollectorUnitTestMiddleware.java b/src/test/java/com/splunk/logging/HttpEventCollectorUnitTestMiddleware.java similarity index 98% rename from src/test/java/HttpEventCollectorUnitTestMiddleware.java rename to src/test/java/com/splunk/logging/HttpEventCollectorUnitTestMiddleware.java index 0d272cd0..e3a9e43f 100644 --- a/src/test/java/HttpEventCollectorUnitTestMiddleware.java +++ b/src/test/java/com/splunk/logging/HttpEventCollectorUnitTestMiddleware.java @@ -1,3 +1,5 @@ +package com.splunk.logging; + import com.splunk.logging.HttpEventCollectorEventInfo; import com.splunk.logging.HttpEventCollectorMiddleware; diff --git a/src/test/java/HttpEventCollector_JavaLoggingTest.java b/src/test/java/com/splunk/logging/HttpEventCollector_JavaLoggingTest.java similarity index 98% rename from src/test/java/HttpEventCollector_JavaLoggingTest.java rename to src/test/java/com/splunk/logging/HttpEventCollector_JavaLoggingTest.java index 32127d78..180bb998 100644 --- a/src/test/java/HttpEventCollector_JavaLoggingTest.java +++ b/src/test/java/com/splunk/logging/HttpEventCollector_JavaLoggingTest.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may @@ -18,8 +18,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import com.splunk.logging.HttpEventCollectorErrorHandler; -import com.splunk.logging.HttpEventCollectorEventInfo; import org.apache.commons.lang3.StringUtils; import org.junit.Assert; @@ -355,7 +353,7 @@ public void error(final List data, final Exception public void EventsFlushedAfterCloseLogger() throws Exception { String msgs = queueEvents(); // Thread.sleep(9000); -// TestUtil.verifyOneAndOnlyOneEventSentToSplunk(msgs); +// com.splunk.logging.TestUtil.verifyOneAndOnlyOneEventSentToSplunk(msgs); } @@ -462,7 +460,7 @@ public void canSendEventUsingJavaLoggingWithUserEventBodySerializer() throws Exc HashMap userInputs = new HashMap(); userInputs.put("user_httpEventCollector_token", token); userInputs.put("user_logger_name", loggerName); - userInputs.put("user_eventBodySerializer", "TestEventBodySerializer"); + userInputs.put("user_eventBodySerializer", "com.splunk.logging.TestEventBodySerializer"); TestUtil.resetJavaLoggingConfiguration("logging_template.properties", "logging.properties", userInputs); @@ -490,7 +488,7 @@ public void canSendEventUsingJavaLoggingWithUserEventHeaderSerializer() throws E HashMap userInputs = new HashMap(); userInputs.put("user_httpEventCollector_token", token); userInputs.put("user_logger_name", loggerName); - userInputs.put("user_eventHeaderSerializer", "TestEventHeaderSerializer"); + userInputs.put("user_eventHeaderSerializer", "com.splunk.logging.TestEventHeaderSerializer"); TestUtil.resetJavaLoggingConfiguration("logging_template.properties", "logging.properties", userInputs); diff --git a/src/test/java/HttpEventCollector_Log4j2Test.java b/src/test/java/com/splunk/logging/HttpEventCollector_Log4j2Test.java similarity index 99% rename from src/test/java/HttpEventCollector_Log4j2Test.java rename to src/test/java/com/splunk/logging/HttpEventCollector_Log4j2Test.java index b049f812..b0ea6ad3 100644 --- a/src/test/java/HttpEventCollector_Log4j2Test.java +++ b/src/test/java/com/splunk/logging/HttpEventCollector_Log4j2Test.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may @@ -19,8 +19,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import com.splunk.logging.HttpEventCollectorErrorHandler; -import com.splunk.logging.HttpEventCollectorEventInfo; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.core.LoggerContext; diff --git a/src/test/java/HttpEventCollector_LogbackTest.java b/src/test/java/com/splunk/logging/HttpEventCollector_LogbackTest.java similarity index 99% rename from src/test/java/HttpEventCollector_LogbackTest.java rename to src/test/java/com/splunk/logging/HttpEventCollector_LogbackTest.java index 3fa2c20e..01f53d77 100644 --- a/src/test/java/HttpEventCollector_LogbackTest.java +++ b/src/test/java/com/splunk/logging/HttpEventCollector_LogbackTest.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may @@ -18,8 +18,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import com.splunk.logging.HttpEventCollectorErrorHandler; -import com.splunk.logging.HttpEventCollectorEventInfo; import org.apache.commons.lang3.StringUtils; import org.junit.Assert; diff --git a/src/test/java/HttpEventCollector_Test.java b/src/test/java/com/splunk/logging/HttpEventCollector_Test.java similarity index 90% rename from src/test/java/HttpEventCollector_Test.java rename to src/test/java/com/splunk/logging/HttpEventCollector_Test.java index 35a32920..11926669 100644 --- a/src/test/java/HttpEventCollector_Test.java +++ b/src/test/java/com/splunk/logging/HttpEventCollector_Test.java @@ -1,4 +1,4 @@ -/** +package com.splunk.logging; /** * @copyright * * Copyright 2013-2015 Splunk, Inc. @@ -17,8 +17,6 @@ */ import ch.qos.logback.core.joran.spi.JoranException; -import com.splunk.logging.HttpEventCollectorErrorHandler; -import com.splunk.logging.HttpEventCollectorEventInfo; import org.junit.Assert; import org.junit.Test; @@ -30,7 +28,6 @@ import java.lang.reflect.*; import com.splunk.*; -import org.slf4j.*; public class HttpEventCollector_Test { public static void addPath(String s) throws Exception { @@ -160,7 +157,7 @@ private boolean insertDataWithLoggerAndVerify(String token, String loggerType, i userInputs.put("user_batch_size_bytes", "12"); } - if (loggerType == "log4j") { + if (Objects.equals(loggerType, "log4j")) { String loggerName = "splunk.log4jInsertVerify"; userInputs.put("user_logger_name", loggerName); org.apache.logging.log4j.core.LoggerContext context = TestUtil.resetLog4j2Configuration("log4j2_template.xml", "log4j2.xml", userInputs); @@ -169,7 +166,7 @@ private boolean insertDataWithLoggerAndVerify(String token, String loggerType, i LOG4J.info(String.format("log4j message%d", i)); } } - if (loggerType == "logback") { + if (Objects.equals(loggerType, "logback")) { String loggerName = "logBackLogger"; userInputs.put("user_logger_name", loggerName); userInputs.put("user_defined_httpEventCollector_token", token); @@ -179,7 +176,7 @@ private boolean insertDataWithLoggerAndVerify(String token, String loggerType, i LOGBACK.info(String.format("logback message%d", i)); } } - if (loggerType == "javautil") { + if (Objects.equals(loggerType, "javautil")) { String loggerName = batching?"splunkLogger_batching":"splunkLogger_nobatching"; userInputs.put("user_logger_name", loggerName); TestUtil.resetJavaLoggingConfiguration("logging_template.properties", "logging.properties", userInputs); @@ -188,36 +185,33 @@ private boolean insertDataWithLoggerAndVerify(String token, String loggerType, i LOGGER.info(String.format("javautil message%d", i)); } } - System.out.printf("Done\n"); + System.out.print("Done\n"); // Wait for indexing to complete Thread.sleep(10000); String searchQuery = String.format("search %s earliest=%d| stats count", loggerType, startTime); waitForIndexingToComplete(searchQuery, expectedCounter); - Boolean testPassed = true; int eventCount = getEventsCount(searchQuery); System.out.printf("\tLogger: '%s', expected %d events, actually %d, %s\r\n", loggerType, expectedCounter, eventCount, (eventCount == expectedCounter) ? "Passed." : "Failed."); return (eventCount == expectedCounter); } private void LogToSplunk(boolean batching) throws Exception { - HttpEventCollectorErrorHandler.onError(new HttpEventCollectorErrorHandler.ErrorCallback() { - public void error(final List data, final Exception ex) { - HttpEventCollectorErrorHandler.ServerErrorException serverErrorException = - (HttpEventCollectorErrorHandler.ServerErrorException) ex; - System.out.printf("ERROR: %s", ex.toString()); - Assert.assertTrue(false); - } + HttpEventCollectorErrorHandler.onError((data, ex) -> { + HttpEventCollectorErrorHandler.ServerErrorException serverErrorException = + (HttpEventCollectorErrorHandler.ServerErrorException) ex; + System.out.printf("ERROR: %s", ex.toString()); + Assert.fail(); }); int expectedCounter = 2; System.out.printf("\tSetting up http event collector with %s ... ", batching ? "batching" : "no batching"); String token = setupHttpEventCollector(batching); - System.out.printf("Set\n"); - Boolean testPassed = true; - testPassed &= insertDataWithLoggerAndVerify(token, "log4j", expectedCounter, batching); + System.out.print("Set\n"); + boolean testPassed; + testPassed = insertDataWithLoggerAndVerify(token, "log4j", expectedCounter, batching); testPassed &= insertDataWithLoggerAndVerify(token, "logback", expectedCounter, batching); testPassed &= insertDataWithLoggerAndVerify(token, "javautil", expectedCounter, batching); Assert.assertTrue(testPassed); - System.out.printf("PASSED.\n\n"); + System.out.print("PASSED.\n\n"); } private void waitForIndexingToComplete(String query, int expectedCounter) throws IOException, InterruptedException { @@ -236,7 +230,7 @@ private void waitForIndexingToComplete(String query, int expectedCounter) throws } private static class DataSender implements Runnable { - private String threadName; + private final String threadName; public int eventsGenerated = 0, testDurationInSecs = 300; java.util.logging.Logger logger; @@ -249,7 +243,7 @@ public DataSender(String threadName, int testDurationInSecs, java.util.logging.L public void run() { Date dCurrent = new Date(); Date dEnd = new Date(); - dEnd.setTime(dCurrent.getTime() + testDurationInSecs * 1000); + dEnd.setTime(dCurrent.getTime() + testDurationInSecs * 1000L); while (dCurrent.before(dEnd)) { this.logger.info(String.format("javautil thread: %s, event: %d", this.threadName, eventsGenerated++)); try { @@ -270,13 +264,12 @@ public void error(final List data, final Exception HttpEventCollectorErrorHandler.ServerErrorException serverErrorException = (HttpEventCollectorErrorHandler.ServerErrorException) ex; System.out.printf("ERROR: %s", ex.toString()); - Assert.assertTrue(false); + Assert.fail(); } }); - boolean batching = false; - System.out.printf("\tSetting up http event collector with %s ... ", batching ? "batching" : "no batching"); - String token = setupHttpEventCollector(batching); - System.out.printf("HTTP event collector fully set\n"); + System.out.print("\tSetting up http event collector without batching"); + String token = setupHttpEventCollector(false); + System.out.print("HTTP event collector fully set\n"); Service service = TestUtil.connectToSplunk(); HashMap userInputs = new HashMap(); userInputs.put("user_httpEventCollector_token", token); @@ -304,6 +297,6 @@ public void error(final List data, final Exception int eventCount = getEventsCount(searchQuery); System.out.printf("\tLogger: '%s', expected %d events, actually %d, %s\r\n", "javautil", expectedCounter, eventCount, (eventCount == expectedCounter) ? "Passed." : "Failed."); Assert.assertEquals(eventCount, expectedCounter); - System.out.printf("PASSED.\n\n"); + System.out.print("PASSED.\n\n"); } } diff --git a/src/test/java/HttpLoggerStressTest.java b/src/test/java/com/splunk/logging/HttpLoggerStressTest.java similarity index 99% rename from src/test/java/HttpLoggerStressTest.java rename to src/test/java/com/splunk/logging/HttpLoggerStressTest.java index 3f21ea03..98759434 100644 --- a/src/test/java/HttpLoggerStressTest.java +++ b/src/test/java/com/splunk/logging/HttpLoggerStressTest.java @@ -1,3 +1,5 @@ +package com.splunk.logging; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/src/test/java/JULFunctionalTest.java b/src/test/java/com/splunk/logging/JULFunctionalTest.java similarity index 88% rename from src/test/java/JULFunctionalTest.java rename to src/test/java/com/splunk/logging/JULFunctionalTest.java index 54de6b02..8594cf53 100644 --- a/src/test/java/JULFunctionalTest.java +++ b/src/test/java/com/splunk/logging/JULFunctionalTest.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may @@ -16,12 +16,6 @@ import org.junit.Assert; import org.junit.Test; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.ServerSocket; -import java.net.Socket; import java.util.logging.Logger; public class JULFunctionalTest { diff --git a/src/test/java/Log4jFunctionalTest.java b/src/test/java/com/splunk/logging/Log4jFunctionalTest.java similarity index 97% rename from src/test/java/Log4jFunctionalTest.java rename to src/test/java/com/splunk/logging/Log4jFunctionalTest.java index 5f4c899b..236ec704 100644 --- a/src/test/java/Log4jFunctionalTest.java +++ b/src/test/java/com/splunk/logging/Log4jFunctionalTest.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may diff --git a/src/test/java/LogbackFunctionalTest.java b/src/test/java/com/splunk/logging/LogbackFunctionalTest.java similarity index 97% rename from src/test/java/LogbackFunctionalTest.java rename to src/test/java/com/splunk/logging/LogbackFunctionalTest.java index 193364ed..6890d84a 100644 --- a/src/test/java/LogbackFunctionalTest.java +++ b/src/test/java/com/splunk/logging/LogbackFunctionalTest.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may diff --git a/src/test/java/SplunkCimLogEventUnitTest.java b/src/test/java/com/splunk/logging/SplunkCimLogEventUnitTest.java similarity index 94% rename from src/test/java/SplunkCimLogEventUnitTest.java rename to src/test/java/com/splunk/logging/SplunkCimLogEventUnitTest.java index 35407ec8..ed4617dd 100644 --- a/src/test/java/SplunkCimLogEventUnitTest.java +++ b/src/test/java/com/splunk/logging/SplunkCimLogEventUnitTest.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may @@ -130,8 +130,8 @@ public void addThrowableWorks() { String expectedString = "\"name=name\" \"event_id=event-id\" " + "\"throwable_class=java.lang.Exception\" \"throwable_message=This is a test of the Java " + - "emergency broadcast system.\" \"stacktrace_elements=SplunkCimLogEventUnitTest." + - "addThrowableWorks(SplunkCimLogEventUnitTest.java:???),"; + "emergency broadcast system.\" \"stacktrace_elements=com.splunk.logging.SplunkCimLogEventUnitTest." + + "addThrowableWorks(com.splunk.logging.SplunkCimLogEventUnitTest.java:???),"; String foundString = event.toString(); foundString = foundString.replaceAll(":\\d+\\)", ":???)"); // Get rid of line numbers. @@ -151,8 +151,8 @@ public void addThrowableWorksWithDepth() { String expected = "\"name=name\" \"event_id=event-id\" " + "\"throwable_class=java.lang.Exception\" \"throwable_message=This is a test of the Java " + - "emergency broadcast system.\" \"stacktrace_elements=SplunkCimLogEventUnitTest." + - "addThrowableWorksWithDepth(SplunkCimLogEventUnitTest.java:???)\""; + "emergency broadcast system.\" \"stacktrace_elements=com.splunk.logging.SplunkCimLogEventUnitTest." + + "addThrowableWorksWithDepth(com.splunk.logging.SplunkCimLogEventUnitTest.java:???)\""; Assert.assertEquals(expected, event.toString().replaceAll(":\\d+\\)", ":???)")); } diff --git a/src/test/java/TestEventBodySerializer.java b/src/test/java/com/splunk/logging/TestEventBodySerializer.java similarity index 97% rename from src/test/java/TestEventBodySerializer.java rename to src/test/java/com/splunk/logging/TestEventBodySerializer.java index fdf3022a..837ebddb 100644 --- a/src/test/java/TestEventBodySerializer.java +++ b/src/test/java/com/splunk/logging/TestEventBodySerializer.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may diff --git a/src/test/java/TestEventHeaderSerializer.java b/src/test/java/com/splunk/logging/TestEventHeaderSerializer.java similarity index 97% rename from src/test/java/TestEventHeaderSerializer.java rename to src/test/java/com/splunk/logging/TestEventHeaderSerializer.java index 4896d5c3..2597aeb6 100644 --- a/src/test/java/TestEventHeaderSerializer.java +++ b/src/test/java/com/splunk/logging/TestEventHeaderSerializer.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may diff --git a/src/test/java/TestFormatter.java b/src/test/java/com/splunk/logging/TestFormatter.java similarity index 97% rename from src/test/java/TestFormatter.java rename to src/test/java/com/splunk/logging/TestFormatter.java index 945346ac..961c9fd9 100644 --- a/src/test/java/TestFormatter.java +++ b/src/test/java/com/splunk/logging/TestFormatter.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may diff --git a/src/test/java/TestUtil.java b/src/test/java/com/splunk/logging/TestUtil.java similarity index 97% rename from src/test/java/TestUtil.java rename to src/test/java/com/splunk/logging/TestUtil.java index d6c291a1..77a34d8a 100644 --- a/src/test/java/TestUtil.java +++ b/src/test/java/com/splunk/logging/TestUtil.java @@ -1,531 +1,531 @@ -/* - * Copyright 2013-2014 Splunk, Inc. - * - * 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. - */ - -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.joran.JoranConfigurator; -import ch.qos.logback.core.joran.spi.JoranException; -import com.google.gson.*; -import com.splunk.*; - -import org.junit.Assert; -import org.slf4j.*; - -import java.io.*; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.Map.Entry; -import java.util.logging.LogManager; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class TestUtil { - - private static final ServiceArgs serviceArgs = new ServiceArgs(); - private static Service service; - private static final String httpEventCollectorTokenEndpointPath = "/services/data/inputs/http"; - - /** - * read splunk host info from .splunkrc file - */ - private static void getSplunkHostInfo() throws IOException { - // .splunkrc overrides environment - - if (serviceArgs.isEmpty()) { - //set default value - Map environment = System.getenv(); - serviceArgs.setUsername(environment.getOrDefault("SPLUNK_USER", "admin")); - serviceArgs.setPassword(environment.getOrDefault("SPLUNK_PASSWORD", "changed!")); - serviceArgs.setHost(environment.getOrDefault("SPLUNK_HOST", "localhost")); - - serviceArgs.setPort(8089); - String environmentPort = environment.get("SPLUNK_ADMIN_PORT"); - if (environmentPort != null) { - try { - int parsedPort = Integer.parseInt(environmentPort); - } catch(NumberFormatException e) { - // Use default set above - } - } - - String environmentScheme = environment.get("SPLUNK_ADMIN_PROTOCOL"); - if (environmentScheme != null) { - if ("https".equalsIgnoreCase(environmentScheme) || "http".equalsIgnoreCase(environmentScheme)) { - serviceArgs.setScheme(environmentScheme.toLowerCase()); - } else { - throw new IOException("Unknown admin transport protocol '" + environmentScheme + "', expect http or https"); - } - } else { - serviceArgs.setScheme("https"); - } - - String splunkUserEnv = System.getenv("SPLUNK_USER"); - if (splunkUserEnv != null) { - serviceArgs.setUsername("SPLUNK_USER"); - } - - //update serviceArgs with customer splunk host info - String splunkhostfile = System.getProperty("user.home") + File.separator + ".splunkrc"; - - Path configPath = new File(splunkhostfile).toPath(); - if (Files.exists(configPath)) { - List lines = Files.readAllLines(configPath, Charset.defaultCharset()); - for (String line : lines) { - if (line.toLowerCase().contains("host=")) { - serviceArgs.setHost(line.split("=")[1]); - } - if (line.toLowerCase().contains("admin=")) { - serviceArgs.setUsername(line.split("=")[1]); - } - if (line.toLowerCase().contains("password=")) { - serviceArgs.setPassword(line.split("=")[1]); - } - if (line.toLowerCase().contains("scheme=")) { - serviceArgs.setScheme(line.split("=")[1]); - } - if (line.toLowerCase().contains("port=")) { - serviceArgs.setPort(Integer.parseInt(line.split("=")[1])); - } - } - } - } - // Use TLSv1 instead of SSLv3 - serviceArgs.setSSLSecurityProtocol(SSLSecurityProtocol.TLSv1_2); - } - - public static void resetConnection() { - service = null; - } - - public static Service connectToSplunk() throws IOException { - - int retry = 0; - while (true) { - try { - - if (service == null) { - getSplunkHostInfo(); - - service = Service.connect(serviceArgs); - service.login(); - } - - return service; - } catch (IOException ex) { - retry++; - if (retry > 5) - throw ex; - } - } - } - - public static void createIndex(String indexName) throws Exception { - connectToSplunk(); - IndexCollection indexes = service.getIndexes(); - if (indexes.containsKey(indexName)) { - Index index = indexes.get(indexName); - indexes.remove(indexName); - } - - int retry = 3; - - while (retry > 0) { - try { - indexes.create(indexName); - return; - } catch (HttpException e) { - retry--; - Thread.sleep(1000); - } - } - } - - - /** - * create http event collector token - */ - public static String createHttpEventCollectorToken(String httpEventCollectorName) throws Exception { - connectToSplunk(); - - //enable logging endpoint - enableHttpEventCollector(); - - //create an httpEventCollector - Map args = new HashMap<>(); - args.put("name", httpEventCollectorName); - args.put("description", "test http event collector"); - - deleteHttpEventCollectorToken(httpEventCollectorName); - Thread.sleep(500); - - ResponseMessage msg = service.post(httpEventCollectorTokenEndpointPath, args); - assert msg.getStatus() == 201; - - //get httpEventCollector token - args = new HashMap<>(); - ResponseMessage response = service.get(httpEventCollectorTokenEndpointPath + "/" + httpEventCollectorName, args); - BufferedReader reader = new BufferedReader(new InputStreamReader(response.getContent(), StandardCharsets.UTF_8)); - String token = ""; - while (true) { - String line = reader.readLine(); - if (line == null) break; - - if (line.contains("name=\"token\"")) { - token = line.split(">")[1]; - token = token.split("<")[0]; - break; - } - } - reader.close(); - - if (token.isEmpty()) { - Assert.fail("no httpEventCollector token is created"); - } - - return token; - } - - /** - * delete http event collector token - */ - public static void deleteHttpEventCollectorToken(String httpEventCollectorName) throws Exception { - connectToSplunk(); - try { - ResponseMessage response = service.get(httpEventCollectorTokenEndpointPath + "/" + httpEventCollectorName); - if (response.getStatus() == 200) { - response = service.delete(httpEventCollectorTokenEndpointPath + "/" + httpEventCollectorName); - assert response.getStatus() == 200; - } - } catch (com.splunk.HttpException e) { - if (e.getStatus() != 404) - throw e; - } - } - - /** - * disable http event collector feature - */ - public static void disableHttpEventCollector() throws IOException { - connectToSplunk(); - - //disable logging endpoint - Map args = new HashMap(); - args.put("disabled", 1); - ResponseMessage response = service.post("/servicesNS/admin/search/data/inputs/http/http", args); - assert response.getStatus() == 200; - } - - /** - * enable http event collector feature - */ - public static void enableHttpEventCollector() throws IOException { - connectToSplunk(); - - //enable logging endpoint - Map args = new HashMap(); - args.put("disabled", 0); - ResponseMessage response = service.post("/servicesNS/admin/search/data/inputs/http/http", args); - assert response.getStatus() == 200; - - } - - /** - * disable http event collector token - */ - public static void disableHttpEventCollector(String httpEventCollectorName) throws IOException { - connectToSplunk(); - - Map args = new HashMap(); - args.put("disabled", 1); - - ResponseMessage response = service.post(httpEventCollectorTokenEndpointPath + "/" + httpEventCollectorName, args); - assert response.getStatus() == 200; - } - - /** - * modify the config file with the generated token, and configured splunk host, - * read the template from configFileTemplate, and create the updated configfile to configFile - */ - public static String updateConfigFile(String configFileTemplate, String configFile, HashMap userInputs) throws IOException { - getSplunkHostInfo(); - - String configFileDir = TestUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath(); - List lines = Files.readAllLines(new File(configFileDir, configFileTemplate).toPath(), Charset.defaultCharset()); - for (int i = 0; i < lines.size(); i++) { - if (lines.get(i).contains("%host%")) { - lines.set(i, lines.get(i).replace("%host%", serviceArgs.host)); - } - if (lines.get(i).contains("%port%")) { - lines.set(i, lines.get(i).replace("%port%", serviceArgs.port.toString())); - } - - if (lines.get(i).contains("%scheme%")) { - lines.set(i, lines.get(i).replace("%scheme%", serviceArgs.scheme)); - } - - String match = FindUserInputConfiguration(lines.get(i)); - if (!match.isEmpty()) { - if (userInputs.keySet().contains(match)) - lines.set(i, lines.get(i).replace("%" + match + "%", userInputs.get(match))); - else - lines.set(i, ""); - } - } - - String configFilePath = new File(configFileDir, configFile).getPath(); - FileWriter fw = new FileWriter(configFilePath); - for (String line : lines) { - if (!line.isEmpty()) { - fw.write(line); - fw.write(System.getProperty("line.separator")); - } - } - - fw.flush(); - fw.close(); - - return configFilePath; - } - - private static String FindUserInputConfiguration(String line) { - String pattern = "%.*%"; - Pattern r = Pattern.compile(pattern); - Matcher m = r.matcher(line); - if (m.find()) { - return m.group(0).substring(1, m.group(0).length() - 1); - } else - return ""; - } - - /* - create log4j2.xml and force log4j2 context manager to reload the configurations, return context and using this context to retrieve logger instead of using LogManager - */ - public static org.apache.logging.log4j.core.LoggerContext resetLog4j2Configuration(String configFileTemplate, String configFile, HashMap userInputs) throws IOException, JoranException { - String configFilePath = updateConfigFile(configFileTemplate, configFile, userInputs); - org.apache.logging.log4j.core.LoggerContext context = new org.apache.logging.log4j.core.LoggerContext(userInputs.get("user_logger_name")); - context.reconfigure(); - context.updateLoggers(); - return context; - } - - /* - create logback.xml and force logback manager to reload the configurations - */ - public static void resetLogbackConfiguration(String configFileTemplate, String configFile, HashMap userInputs) throws IOException, JoranException { - String configFilePath = updateConfigFile(configFileTemplate, configFile, userInputs); - - //force the Logback factory to reload the configuration file - JoranConfigurator jc = new JoranConfigurator(); - LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); - jc.setContext(context); - context.reset(); - jc.doConfigure(configFilePath); - } - - /* - create logging.property and force java logging manager to reload the configurations - */ - public static void resetJavaLoggingConfiguration(String configFileTemplate, String configFile, HashMap userInputs) throws IOException, JoranException { - String configFilePath = updateConfigFile(configFileTemplate, configFile, userInputs); - FileInputStream configFileStream = new FileInputStream(configFilePath); - LogManager.getLogManager().readConfiguration(configFileStream); - configFileStream.close(); - } - - public static void verifyOneAndOnlyOneEventSentToSplunk(String msg) throws IOException { - connectToSplunk(); - - long startTime = System.currentTimeMillis(); - int eventCount = 0; - InputStream resultsStream = null; - ResultsReaderXml resultsReader = null; - while (System.currentTimeMillis() - startTime < 30 * 1000)/*wait for up to 30s*/ { - resultsStream = service.oneshotSearch("search " + msg); - resultsReader = new ResultsReaderXml(resultsStream); - - //verify has one and only one record return - for (Event event : resultsReader) { - eventCount++; - System.out.println("---------------"); - System.out.println(event.getSegmentedRaw()); - } - - if (eventCount > 0) - break; - } - - resultsReader.close(); - resultsStream.close(); - - Assert.assertTrue(eventCount == 1); - } - - public static void verifyNoEventSentToSplunk(List msgs) throws IOException { - connectToSplunk(); - String searchstr = org.apache.commons.lang3.StringUtils.join(msgs, "\" OR \""); - searchstr = "\"" + searchstr + "\""; - - long startTime = System.currentTimeMillis(); - int eventCount = 0; - InputStream resultsStream = null; - ResultsReaderXml resultsReader = null; - while (System.currentTimeMillis() - startTime < 10 * 1000)/*wait for up to 30s*/ { - resultsStream = service.oneshotSearch("search " + searchstr); - resultsReader = new ResultsReaderXml(resultsStream); - - //verify has one and only one record return - for (Event event : resultsReader) { - eventCount++; - System.out.println("------verify no events---------"); - System.out.println(event.getSegmentedRaw()); - } - - if (eventCount > 0) - break; - } - - resultsReader.close(); - resultsStream.close(); - - Assert.assertTrue(eventCount == 0); - } - - /* - verify each of the message in msgs appeared and appeared only once in splunk - */ - public static void verifyEventsSentToSplunk(List msgs) throws IOException, InterruptedException { - connectToSplunk(); - - for (String msg : msgs) { - long startTime = System.currentTimeMillis(); - int eventCount = 0; - InputStream resultsStream = null; - ResultsReaderXml resultsReader = null; - Object parsedObject; - try { - parsedObject = JsonParser.parseString(msg); - } catch (JsonSyntaxException e) { - parsedObject = msg; - } - while (System.currentTimeMillis() - startTime < 30 * 1000)/*wait for up to 30s*/ { - if (parsedObject instanceof JsonObject) { - resultsStream = searchJsonMessageEvent((JsonObject) parsedObject); - } else { - resultsStream = service.oneshotSearch("search " + msg); - } - - resultsReader = new ResultsReaderXml(resultsStream); - - //verify has one and only one record return - for (Event event : resultsReader) { - eventCount++; - System.out.println("------verify has events---------"); - System.out.println(event.getSegmentedRaw()); - } - - if (eventCount > 0) - break; - - Thread.sleep(5000); - } - - resultsReader.close(); - resultsStream.close(); - - Assert.assertEquals("Event search results did not match.", 1, eventCount); - } - } - - /** - * Search JSON message event. - * - * @param jsonObject the JSON event object - * @return the input stream linked with the search result - */ - @SuppressWarnings("rawtypes") - private static InputStream searchJsonMessageEvent(final JsonObject jsonObject) { - StringBuilder searchQuery = new StringBuilder(); - boolean firstSearchTerm = true; - for (final Object entryObject : jsonObject.entrySet()) { - final Entry jsonEntry = (Entry) entryObject; - if (firstSearchTerm) { - searchQuery.append(String.format("search \"message.%s\"=%s", jsonEntry.getKey(), jsonEntry.getValue())); - firstSearchTerm = false; - } else { - searchQuery.append(String.format(" | search \"message.%s\"=%s", jsonEntry.getKey(), jsonEntry.getValue())); - } - } - System.err.println(searchQuery.toString()); - - return service.oneshotSearch(searchQuery.toString()); - } - - public static void verifyEventsSentInOrder(String prefix, int totalEventsCount, String index) throws IOException { - connectToSplunk(); - - long startTime = System.currentTimeMillis(); - InputStream resultsStream = null; - ResultsReaderXml resultsReader = null; - List results = new ArrayList(); - while (System.currentTimeMillis() - startTime < 100 * 1000)/*wait for up to 30s*/ { - results.clear(); - String searchstr = "search index=" + index; - resultsStream = service.oneshotSearch(searchstr, new Args("count", 0)); - resultsReader = new ResultsReaderXml(resultsStream); - - for (Event event : resultsReader) { - results.add(event.getSegmentedRaw()); - } - - if (results.size() == totalEventsCount) - break; - } - - resultsReader.close(); - resultsStream.close(); - - assert (results.size() == totalEventsCount) : String.format("expect: %d, actual: %d", totalEventsCount, results.size()); - - //verify events record is in correct order - for (int i = 0; i < totalEventsCount; i++) { - String expect = String.format("%s %s", prefix, totalEventsCount - 1 - i); - assert results.get(i).contains(expect) : - String.format("expect: %s, actual: %s", expect, results.get(i)); - } - } - - - /** - * Builds user input map using specified parameters. - * - * @param loggerName the logger name - * @param token the event collector token - * @param sourceType the source type - * @return the hash map - */ - public static HashMap buildUserInputMap(final String loggerName, final String token, final String sourceType, final String messageFormat) { - final HashMap userInputs = new HashMap(); - userInputs.put("user_logger_name", loggerName); - userInputs.put("user_httpEventCollector_token", token); - userInputs.put("user_host", "host.example.com"); - userInputs.put("user_source", "splunktest"); - userInputs.put("user_sourcetype", sourceType); - userInputs.put("user_messageFormat", messageFormat); - return userInputs; - } -} +package com.splunk.logging;/* + * Copyright 2013-2014 Splunk, Inc. + * + * 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. + */ + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.joran.JoranConfigurator; +import ch.qos.logback.core.joran.spi.JoranException; +import com.google.gson.*; +import com.splunk.*; + +import org.junit.Assert; +import org.slf4j.*; + +import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.Map.Entry; +import java.util.logging.LogManager; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TestUtil { + + private static final ServiceArgs serviceArgs = new ServiceArgs(); + private static Service service; + private static final String httpEventCollectorTokenEndpointPath = "/services/data/inputs/http"; + + /** + * read splunk host info from .splunkrc file + */ + private static void getSplunkHostInfo() throws IOException { + // .splunkrc overrides environment + + if (serviceArgs.isEmpty()) { + //set default value + Map environment = System.getenv(); + serviceArgs.setUsername(environment.getOrDefault("SPLUNK_USER", "admin")); + serviceArgs.setPassword(environment.getOrDefault("SPLUNK_PASSWORD", "changed!")); + serviceArgs.setHost(environment.getOrDefault("SPLUNK_HOST", "localhost")); + + serviceArgs.setPort(8089); + String environmentPort = environment.get("SPLUNK_ADMIN_PORT"); + if (environmentPort != null) { + try { + int parsedPort = Integer.parseInt(environmentPort); + } catch(NumberFormatException e) { + // Use default set above + } + } + + String environmentScheme = environment.get("SPLUNK_ADMIN_PROTOCOL"); + if (environmentScheme != null) { + if ("https".equalsIgnoreCase(environmentScheme) || "http".equalsIgnoreCase(environmentScheme)) { + serviceArgs.setScheme(environmentScheme.toLowerCase()); + } else { + throw new IOException("Unknown admin transport protocol '" + environmentScheme + "', expect http or https"); + } + } else { + serviceArgs.setScheme("https"); + } + + String splunkUserEnv = System.getenv("SPLUNK_USER"); + if (splunkUserEnv != null) { + serviceArgs.setUsername("SPLUNK_USER"); + } + + //update serviceArgs with customer splunk host info + String splunkhostfile = System.getProperty("user.home") + File.separator + ".splunkrc"; + + Path configPath = new File(splunkhostfile).toPath(); + if (Files.exists(configPath)) { + List lines = Files.readAllLines(configPath, Charset.defaultCharset()); + for (String line : lines) { + if (line.toLowerCase().contains("host=")) { + serviceArgs.setHost(line.split("=")[1]); + } + if (line.toLowerCase().contains("admin=")) { + serviceArgs.setUsername(line.split("=")[1]); + } + if (line.toLowerCase().contains("password=")) { + serviceArgs.setPassword(line.split("=")[1]); + } + if (line.toLowerCase().contains("scheme=")) { + serviceArgs.setScheme(line.split("=")[1]); + } + if (line.toLowerCase().contains("port=")) { + serviceArgs.setPort(Integer.parseInt(line.split("=")[1])); + } + } + } + } + // Use TLSv1 instead of SSLv3 + serviceArgs.setSSLSecurityProtocol(SSLSecurityProtocol.TLSv1_2); + } + + public static void resetConnection() { + service = null; + } + + public static Service connectToSplunk() throws IOException { + + int retry = 0; + while (true) { + try { + + if (service == null) { + getSplunkHostInfo(); + + service = Service.connect(serviceArgs); + service.login(); + } + + return service; + } catch (IOException ex) { + retry++; + if (retry > 5) + throw ex; + } + } + } + + public static void createIndex(String indexName) throws Exception { + connectToSplunk(); + IndexCollection indexes = service.getIndexes(); + if (indexes.containsKey(indexName)) { + Index index = indexes.get(indexName); + indexes.remove(indexName); + } + + int retry = 3; + + while (retry > 0) { + try { + indexes.create(indexName); + return; + } catch (HttpException e) { + retry--; + Thread.sleep(1000); + } + } + } + + + /** + * create http event collector token + */ + public static String createHttpEventCollectorToken(String httpEventCollectorName) throws Exception { + connectToSplunk(); + + //enable logging endpoint + enableHttpEventCollector(); + + //create an httpEventCollector + Map args = new HashMap<>(); + args.put("name", httpEventCollectorName); + args.put("description", "test http event collector"); + + deleteHttpEventCollectorToken(httpEventCollectorName); + Thread.sleep(500); + + ResponseMessage msg = service.post(httpEventCollectorTokenEndpointPath, args); + assert msg.getStatus() == 201; + + //get httpEventCollector token + args = new HashMap<>(); + ResponseMessage response = service.get(httpEventCollectorTokenEndpointPath + "/" + httpEventCollectorName, args); + BufferedReader reader = new BufferedReader(new InputStreamReader(response.getContent(), StandardCharsets.UTF_8)); + String token = ""; + while (true) { + String line = reader.readLine(); + if (line == null) break; + + if (line.contains("name=\"token\"")) { + token = line.split(">")[1]; + token = token.split("<")[0]; + break; + } + } + reader.close(); + + if (token.isEmpty()) { + Assert.fail("no httpEventCollector token is created"); + } + + return token; + } + + /** + * delete http event collector token + */ + public static void deleteHttpEventCollectorToken(String httpEventCollectorName) throws Exception { + connectToSplunk(); + try { + ResponseMessage response = service.get(httpEventCollectorTokenEndpointPath + "/" + httpEventCollectorName); + if (response.getStatus() == 200) { + response = service.delete(httpEventCollectorTokenEndpointPath + "/" + httpEventCollectorName); + assert response.getStatus() == 200; + } + } catch (com.splunk.HttpException e) { + if (e.getStatus() != 404) + throw e; + } + } + + /** + * disable http event collector feature + */ + public static void disableHttpEventCollector() throws IOException { + connectToSplunk(); + + //disable logging endpoint + Map args = new HashMap(); + args.put("disabled", 1); + ResponseMessage response = service.post("/servicesNS/admin/search/data/inputs/http/http", args); + assert response.getStatus() == 200; + } + + /** + * enable http event collector feature + */ + public static void enableHttpEventCollector() throws IOException { + connectToSplunk(); + + //enable logging endpoint + Map args = new HashMap(); + args.put("disabled", 0); + ResponseMessage response = service.post("/servicesNS/admin/search/data/inputs/http/http", args); + assert response.getStatus() == 200; + + } + + /** + * disable http event collector token + */ + public static void disableHttpEventCollector(String httpEventCollectorName) throws IOException { + connectToSplunk(); + + Map args = new HashMap(); + args.put("disabled", 1); + + ResponseMessage response = service.post(httpEventCollectorTokenEndpointPath + "/" + httpEventCollectorName, args); + assert response.getStatus() == 200; + } + + /** + * modify the config file with the generated token, and configured splunk host, + * read the template from configFileTemplate, and create the updated configfile to configFile + */ + public static String updateConfigFile(String configFileTemplate, String configFile, HashMap userInputs) throws IOException { + getSplunkHostInfo(); + + String configFileDir = TestUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + List lines = Files.readAllLines(new File(configFileDir, configFileTemplate).toPath(), Charset.defaultCharset()); + for (int i = 0; i < lines.size(); i++) { + if (lines.get(i).contains("%host%")) { + lines.set(i, lines.get(i).replace("%host%", serviceArgs.host)); + } + if (lines.get(i).contains("%port%")) { + lines.set(i, lines.get(i).replace("%port%", serviceArgs.port.toString())); + } + + if (lines.get(i).contains("%scheme%")) { + lines.set(i, lines.get(i).replace("%scheme%", serviceArgs.scheme)); + } + + String match = FindUserInputConfiguration(lines.get(i)); + if (!match.isEmpty()) { + if (userInputs.keySet().contains(match)) + lines.set(i, lines.get(i).replace("%" + match + "%", userInputs.get(match))); + else + lines.set(i, ""); + } + } + + String configFilePath = new File(configFileDir, configFile).getPath(); + FileWriter fw = new FileWriter(configFilePath); + for (String line : lines) { + if (!line.isEmpty()) { + fw.write(line); + fw.write(System.getProperty("line.separator")); + } + } + + fw.flush(); + fw.close(); + + return configFilePath; + } + + private static String FindUserInputConfiguration(String line) { + String pattern = "%.*%"; + Pattern r = Pattern.compile(pattern); + Matcher m = r.matcher(line); + if (m.find()) { + return m.group(0).substring(1, m.group(0).length() - 1); + } else + return ""; + } + + /* + create log4j2.xml and force log4j2 context manager to reload the configurations, return context and using this context to retrieve logger instead of using LogManager + */ + public static org.apache.logging.log4j.core.LoggerContext resetLog4j2Configuration(String configFileTemplate, String configFile, HashMap userInputs) throws IOException, JoranException { + String configFilePath = updateConfigFile(configFileTemplate, configFile, userInputs); + org.apache.logging.log4j.core.LoggerContext context = new org.apache.logging.log4j.core.LoggerContext(userInputs.get("user_logger_name")); + context.reconfigure(); + context.updateLoggers(); + return context; + } + + /* + create logback.xml and force logback manager to reload the configurations + */ + public static void resetLogbackConfiguration(String configFileTemplate, String configFile, HashMap userInputs) throws IOException, JoranException { + String configFilePath = updateConfigFile(configFileTemplate, configFile, userInputs); + + //force the Logback factory to reload the configuration file + JoranConfigurator jc = new JoranConfigurator(); + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + jc.setContext(context); + context.reset(); + jc.doConfigure(configFilePath); + } + + /* + create logging.property and force java logging manager to reload the configurations + */ + public static void resetJavaLoggingConfiguration(String configFileTemplate, String configFile, HashMap userInputs) throws IOException, JoranException { + String configFilePath = updateConfigFile(configFileTemplate, configFile, userInputs); + FileInputStream configFileStream = new FileInputStream(configFilePath); + LogManager.getLogManager().readConfiguration(configFileStream); + configFileStream.close(); + } + + public static void verifyOneAndOnlyOneEventSentToSplunk(String msg) throws IOException { + connectToSplunk(); + + long startTime = System.currentTimeMillis(); + int eventCount = 0; + InputStream resultsStream = null; + ResultsReaderXml resultsReader = null; + while (System.currentTimeMillis() - startTime < 30 * 1000)/*wait for up to 30s*/ { + resultsStream = service.oneshotSearch("search " + msg); + resultsReader = new ResultsReaderXml(resultsStream); + + //verify has one and only one record return + for (Event event : resultsReader) { + eventCount++; + System.out.println("---------------"); + System.out.println(event.getSegmentedRaw()); + } + + if (eventCount > 0) + break; + } + + resultsReader.close(); + resultsStream.close(); + + Assert.assertTrue(eventCount == 1); + } + + public static void verifyNoEventSentToSplunk(List msgs) throws IOException { + connectToSplunk(); + String searchstr = org.apache.commons.lang3.StringUtils.join(msgs, "\" OR \""); + searchstr = "\"" + searchstr + "\""; + + long startTime = System.currentTimeMillis(); + int eventCount = 0; + InputStream resultsStream = null; + ResultsReaderXml resultsReader = null; + while (System.currentTimeMillis() - startTime < 10 * 1000)/*wait for up to 30s*/ { + resultsStream = service.oneshotSearch("search " + searchstr); + resultsReader = new ResultsReaderXml(resultsStream); + + //verify has one and only one record return + for (Event event : resultsReader) { + eventCount++; + System.out.println("------verify no events---------"); + System.out.println(event.getSegmentedRaw()); + } + + if (eventCount > 0) + break; + } + + resultsReader.close(); + resultsStream.close(); + + Assert.assertTrue(eventCount == 0); + } + + /* + verify each of the message in msgs appeared and appeared only once in splunk + */ + public static void verifyEventsSentToSplunk(List msgs) throws IOException, InterruptedException { + connectToSplunk(); + + for (String msg : msgs) { + long startTime = System.currentTimeMillis(); + int eventCount = 0; + InputStream resultsStream = null; + ResultsReaderXml resultsReader = null; + Object parsedObject; + try { + parsedObject = JsonParser.parseString(msg); + } catch (JsonSyntaxException e) { + parsedObject = msg; + } + while (System.currentTimeMillis() - startTime < 30 * 1000)/*wait for up to 30s*/ { + if (parsedObject instanceof JsonObject) { + resultsStream = searchJsonMessageEvent((JsonObject) parsedObject); + } else { + resultsStream = service.oneshotSearch("search " + msg); + } + + resultsReader = new ResultsReaderXml(resultsStream); + + //verify has one and only one record return + for (Event event : resultsReader) { + eventCount++; + System.out.println("------verify has events---------"); + System.out.println(event.getSegmentedRaw()); + } + + if (eventCount > 0) + break; + + Thread.sleep(5000); + } + + resultsReader.close(); + resultsStream.close(); + + Assert.assertEquals("Event search results did not match.", 1, eventCount); + } + } + + /** + * Search JSON message event. + * + * @param jsonObject the JSON event object + * @return the input stream linked with the search result + */ + @SuppressWarnings("rawtypes") + private static InputStream searchJsonMessageEvent(final JsonObject jsonObject) { + StringBuilder searchQuery = new StringBuilder(); + boolean firstSearchTerm = true; + for (final Object entryObject : jsonObject.entrySet()) { + final Entry jsonEntry = (Entry) entryObject; + if (firstSearchTerm) { + searchQuery.append(String.format("search \"message.%s\"=%s", jsonEntry.getKey(), jsonEntry.getValue())); + firstSearchTerm = false; + } else { + searchQuery.append(String.format(" | search \"message.%s\"=%s", jsonEntry.getKey(), jsonEntry.getValue())); + } + } + System.err.println(searchQuery.toString()); + + return service.oneshotSearch(searchQuery.toString()); + } + + public static void verifyEventsSentInOrder(String prefix, int totalEventsCount, String index) throws IOException { + connectToSplunk(); + + long startTime = System.currentTimeMillis(); + InputStream resultsStream = null; + ResultsReaderXml resultsReader = null; + List results = new ArrayList(); + while (System.currentTimeMillis() - startTime < 100 * 1000)/*wait for up to 30s*/ { + results.clear(); + String searchstr = "search index=" + index; + resultsStream = service.oneshotSearch(searchstr, new Args("count", 0)); + resultsReader = new ResultsReaderXml(resultsStream); + + for (Event event : resultsReader) { + results.add(event.getSegmentedRaw()); + } + + if (results.size() == totalEventsCount) + break; + } + + resultsReader.close(); + resultsStream.close(); + + assert (results.size() == totalEventsCount) : String.format("expect: %d, actual: %d", totalEventsCount, results.size()); + + //verify events record is in correct order + for (int i = 0; i < totalEventsCount; i++) { + String expect = String.format("%s %s", prefix, totalEventsCount - 1 - i); + assert results.get(i).contains(expect) : + String.format("expect: %s, actual: %s", expect, results.get(i)); + } + } + + + /** + * Builds user input map using specified parameters. + * + * @param loggerName the logger name + * @param token the event collector token + * @param sourceType the source type + * @return the hash map + */ + public static HashMap buildUserInputMap(final String loggerName, final String token, final String sourceType, final String messageFormat) { + final HashMap userInputs = new HashMap(); + userInputs.put("user_logger_name", loggerName); + userInputs.put("user_httpEventCollector_token", token); + userInputs.put("user_host", "host.example.com"); + userInputs.put("user_source", "splunktest"); + userInputs.put("user_sourcetype", sourceType); + userInputs.put("user_messageFormat", messageFormat); + return userInputs; + } +} diff --git a/src/test/java/Util.java b/src/test/java/com/splunk/logging/Util.java similarity index 99% rename from src/test/java/Util.java rename to src/test/java/com/splunk/logging/Util.java index 603897d3..d824ebc9 100644 --- a/src/test/java/Util.java +++ b/src/test/java/com/splunk/logging/Util.java @@ -1,4 +1,4 @@ -/* +package com.splunk.logging;/* * Copyright 2013-2014 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may diff --git a/src/test/resources/jdklogging.properties b/src/test/resources/jdklogging.properties index a77caf24..571774d8 100644 --- a/src/test/resources/jdklogging.properties +++ b/src/test/resources/jdklogging.properties @@ -42,4 +42,4 @@ java.util.logging.SocketHandler.port = 15000 # SimpleFormatter doesn't accept a format string under Java 6, and so we cannot # control its output. Thus we use a trivial formatter as part of the test suite # to make it easy to deal with. -java.util.logging.SocketHandler.formatter = TestFormatter +java.util.logging.SocketHandler.formatter = com.splunk.logging.TestFormatter diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml index 18fb5b87..9a06c200 100644 --- a/src/test/resources/log4j2.xml +++ b/src/test/resources/log4j2.xml @@ -40,7 +40,7 @@ under the License. source="splunktest" sourcetype="battlecat" messageFormat="text" - middleware="HttpEventCollectorUnitTestMiddleware" + middleware="com.splunk.logging.HttpEventCollectorUnitTestMiddleware" batch_size_bytes="0" batch_size_count="0" batch_interval="0" diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 960372a5..523b7843 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -58,7 +58,7 @@ under the License. splunktest battlecat text - HttpEventCollectorUnitTestMiddleware + com.splunk.logging.HttpEventCollectorUnitTestMiddleware 5000 %msg diff --git a/src/test/resources/logging_template.properties b/src/test/resources/logging_template.properties index 30e37ba1..6b172c5c 100644 --- a/src/test/resources/logging_template.properties +++ b/src/test/resources/logging_template.properties @@ -27,4 +27,4 @@ com.splunk.logging.HttpEventCollectorLoggingHandler.eventHeaderSerializer = %use # SimpleFormatter doesn't accept a format string under Java 6, and so we cannot # control its output. Thus we use a trivial formatter as part of the test suite # to make it easy to deal with. -#com.splunk.logging.HttpEventCollectorHandler.Formatter = TestFormatter +#com.splunk.logging.HttpEventCollectorHandler.Formatter = com.splunk.logging.TestFormatter