Hi,
i wrote a Java Modular Input with the Splunk SDK 1.6.2. The Input read a Http Request and have only read at the request at the query part. Is the reading successful the input must send a ok-response. The test in eclipse is fine and work 100%.
I get in the _internal index the output:
...
Creating ServerStarter Object done
Creating Thread Object done
Starting Thread done (LogMessage from my Java-class)
**javax.xml.stream.XMLStreamException: No element was found to write: java.lang.ArrayIndexOutOfBoundsException: -1
(LogMessage from XMLStream, my PROBLEM :-( )**
Start HTTP Server (IO) 192.168.1.10 (LogMessage from my Java-class)
...
In the input is it not possible to write the Event to the Eventqueue. I use the method ew.writeEvent() and try the method ew.synchronizedWriteEvent() from the Splunk SDK.
The Stacktrace is:
java.lang.ArrayIndexOutOfBoundsException: -2 com.sun.xml.internal.stream.writers.XMLStreamWriterImpl$ElementStack.peek(XMLStreamWriterImpl.java:2010)
com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.closeStartTag(XMLStreamWriterImpl.java:1512)
com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeStartElement(XMLStreamWriterImpl.java:1229)
com.splunk.modularinput.EventWriter.writeEvent(EventWriter.java:131)
com.splunk.modularinput.EventWriter.synchronizedWriteEvent(EventWriter.java:115)
com.default.DataHandler.handle(DataHandler.java:76)
com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82)
My inputs.conf.spec
[MyScheme://]
ipadresse =
port =
My inputs.conf
[MyScheme://http_input_1]
ipadresse = 192.168.1.10
port = 54321
index = test
sourcetype = test_push
My Java Classes are:
package com.default;
import java.io.IOException;
import javax.xml.stream.XMLStreamException;
import com.splunk.modularinput.Argument;
import com.splunk.modularinput.EventWriter;
import com.splunk.modularinput.InputDefinition;
import com.splunk.modularinput.MalformedDataException;
import com.splunk.modularinput.Scheme;
import com.splunk.modularinput.Script;
import com.splunk.modularinput.SingleValueParameter;
import com.splunk.modularinput.ValidationDefinition;
public class ModularInput extends Script {
public static void main(String[] args) {
new ModularInput().run(args);
}
@Override
public Scheme getScheme() {
Scheme scheme = new Scheme("MyScheme");
scheme.setDescription("Read push messages from my Sourece");
scheme.setUseExternalValidation(true);
scheme.setUseSingleInstance(true);
Argument ipadresse = new Argument("ipadresse");
ipadresse.setDataType(Argument.DataType.STRING);
ipadresse.setRequiredOnCreate(true);
scheme.addArgument(ipadresse);
Argument port = new Argument("port");
port.setDataType(Argument.DataType.NUMBER);
port.setRequiredOnCreate(true);
scheme.addArgument(port);
return scheme;
}
@Override
public void validateInput(ValidationDefinition definition) throws Exception {
String ipadresse = ((SingleValueParameter) definition.getParameters().get("ipadresse")).getValue();
int port = ((SingleValueParameter) definition.getParameters().get("port")).getInt();
if (ipadresse == null || ipadresse.isEmpty()) {
throw new Exception("The Paramter ipadresse must be set.");
}
if (port == Integer.MIN_VALUE) {
throw new Exception("The Paramter port must be set.");
}
}
@Override
public void streamEvents(InputDefinition inputs, EventWriter ew)
throws MalformedDataException, XMLStreamException, IOException {
for (String inputName : inputs.getInputs().keySet()) {
ew.log("INFO", "streamEvents for MyScheme Input " + inputName);
String ipadresse = ((SingleValueParameter) inputs.getInputs().get(inputName).get("ipadresse")).getValue();
int port = ((SingleValueParameter) inputs.getInputs().get(inputName).get("port")).getInt();
String splunkHost = inputs.getServerHost();
String splunkUri = inputs.getServerUri();
String[] splunkUriArray = splunkUri.split(":");
int splunkPort = 8089;
try {
ew.log("INFO", "Parse URI: " + splunkUri);
splunkPort = Integer.parseInt(splunkUriArray[2]);
} catch (NumberFormatException nfe) {
ew.log("WARN", "Can't parse port value from URI String!! Use default Port 8089!");
}
ew.log("INFO", "read ip-Adress: " + ipadresse + " port: " + port + " Splunk Port: " + splunkPort);
HTTPServer gZR = new HTTPServer(ew, inputName, ipadresse, port, splunkHost, splunkPort);
ew.log("INFO", "Creating ServerStarter Object done");
Thread t = new Thread(gZR);
ew.log("INFO", "Creating Thread Object done");
t.start();
ew.log("INFO", "Starting Thread done");
}
}
}
The HTTPServer Code:
package com.default;
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import org.apache.logging.log4j.Level;
import com.splunk.modularinput.EventWriter;
import com.sun.net.httpserver.HttpServer;
public class HTTPServer implements Runnable {
private static final int backlog = 3;
private EventWriter ew;
private String inputName;
private String ipadresse;
private int port;
private String splunkHost;
private int splunkPort;
public HTTPServer(EventWriter ew, String inputName, String ipadresse, int port, String splunkHost, int splunkPort) {
super();
this.ew = ew;
this.inputName = inputName;
this.ipadresse = ipadresse;
this.port = port;
this.splunkHost = splunkHost;
this.splunkPort = splunkPort;
}
@Override
public void run() {
ew.log(Level.INFO.name(), "Start HTTP Server (IO) " + this.ipadresse);
HttpServer server = null;
InetSocketAddress inetSocketAddress;
inetSocketAddress = new InetSocketAddress(ipadresse, port);
try {
ew.log(Level.INFO.name(), "try create HttpServer");
server = HttpServer.create(inetSocketAddress, backlog);
server.createContext("/", new DataHandler(this.ew, this.inputName, this.ipadresse, this.port,
this.splunkHost, this.splunkPort));
ew.log(Level.INFO.name(), "Start HttpServer");
server.start();
ew.log(Level.INFO.name(), "Started HttpServer");
} catch (BindException e) {
ew.log(Level.ERROR.name(), "Port bound " + e.getMessage());
} catch (IOException e) {
ew.log(Level.ERROR.name(), e.getMessage());
} catch (Exception e) {
ew.log(Level.ERROR.name(), e.getMessage());
}}}
This is the DataHandler:
package com.default;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.logging.log4j.Level;
import com.splunk.modularinput.Event;
import com.splunk.modularinput.EventWriter;
import com.splunk.modularinput.MalformedDataException;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
public class DataHandler implements HttpHandler {
private EventWriter ew;
String inputName;
public DataHandler(EventWriter ew, String inputName) {
super();
this.ew = ew;
this.inputName = inputName;
}
@Override
public void handle(HttpExchange httpExchange) throws IOException {
ew.log(Level.INFO.name(), "DataHandler handle");
URI requestURI = httpExchange.getRequestURI();
if (requestURI != null) {
ew.log(Level.INFO.name(), "requestURI: "+requestURI.toString());
String query = requestURI.getQuery();
String queryDecode = "";
try {
queryDecode = URLDecoder.decode(query, StandardCharsets.UTF_8.name());
ew.log(Level.INFO.name(), "QueryDecode: "+queryDecode);
} catch (UnsupportedEncodingException e) {
ew.log(Level.ERROR.name(), e.getMessage());
}
if (query != null && !query.isEmpty()) {
StringBuilder sb = new StringBuilder();
sb.append(requestURI.getPath());
sb.append(query);
ew.log(Level.INFO.name(), "Event creating");
Event event = new Event();
Date time = new Date(System.currentTimeMillis());
event.setTime(time);
event.setData(sb.toString());
try {
ew.log(Level.INFO.name(), "Start write Event "+ event.getData());
ew.synchronizedWriteEvent(event);
ew.log(Level.INFO.name(), "Event writed");
} catch (MalformedDataException e) {
ew.log(Level.ERROR.name(), " Write Event: " + e.getMessage());
} catch (Exception e){
ew.log(Level.ERROR.name(), " Other Exception: " + e +" "+ Arrays.asList(e.getStackTrace()).stream().map(Objects::toString).collect(Collectors.joining("\n") ));
}
ew.log(Level.INFO.name(), "Http Status 200");
String text = "OK";
byte[] response = text.getBytes();
httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
httpExchange.getResponseBody().write(response);
ew.log(Level.INFO.name(), "Send HTTP OK done");
} else {
String text = "Bad Request";
byte[] response = text.getBytes();
httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_BAD_REQUEST, response.length);
httpExchange.getResponseBody().write(response);
ew.log(Level.INFO.name(), "Send HTTP BAD REQUEST done");
}
} else {
ew.log(Level.ERROR.name(), "HTTP URI NULL");
}
}
}
↧