Compare commits
11 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
556d263e37 | |
|
|
66f06b1711 | |
|
|
4534883782 | |
|
|
4c5842aa8f | |
|
|
5099a7b4d6 | |
|
|
5e81f4f979 | |
|
|
cb15d6ac69 | |
|
|
c82a06e58d | |
|
|
42cf4baba4 | |
|
|
adb2972d81 | |
|
|
0a031cd74b |
|
|
@ -24,3 +24,6 @@
|
||||||
hs_err_pid*
|
hs_err_pid*
|
||||||
replay_pid*
|
replay_pid*
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
justfile
|
||||||
|
pom.xml
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
Dokumentation Befehle für Konsole
|
||||||
|
|
||||||
|
mvn exec:java -Dexec.mainClass="vs.SyslogServer"
|
||||||
|
> startet den SyslogServer
|
||||||
|
> Strg + C um Server im Terminal aus Endlosschleife zu beenden
|
||||||
|
|
||||||
|
echo "test" | nc -u -w1 127.0.0.1 5514
|
||||||
|
> Test ob Server auf dem Port 5514 aktiv zuhört und Nachricht korrekt ankommt
|
||||||
|
> w1 damit nach einer Sekunde beendet wird, netcat (nc) wartet bei UDP manchmal auf eine Antwort
|
||||||
|
|
||||||
|
python3 -c "print('A'*600)" | nc -u -w1 127.0.0.1 5514
|
||||||
|
> Test Maximallänge überschritten
|
||||||
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
package vs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper class for RFC 5424 (https://datatracker.ietf.org/doc/html/rfc5424)
|
||||||
|
* compliant log messages as immutable Java objects - representation of a subset
|
||||||
|
* of printable strings of specific length
|
||||||
|
*
|
||||||
|
* @author Sandro Leuchter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AsciiChars {
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AsciiChars(int length, String value) {
|
||||||
|
if (value != null) {
|
||||||
|
if (value.length() > length) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Stringlänge = " + value.length() + " > " + length
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (int c : value.getBytes()) {
|
||||||
|
if (c < 33 || c > 126) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Stringinhalt nicht printable US-ASCII ohne Space"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (value() == null || value().length() == 0) {
|
||||||
|
return "-";
|
||||||
|
} else {
|
||||||
|
return value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class L004 extends AsciiChars {
|
||||||
|
|
||||||
|
public L004(String value) {
|
||||||
|
super(4, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class L012 extends AsciiChars {
|
||||||
|
|
||||||
|
public L012(String value) {
|
||||||
|
super(12, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class L032 extends AsciiChars {
|
||||||
|
|
||||||
|
public L032(String value) {
|
||||||
|
super(32, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class L048 extends AsciiChars {
|
||||||
|
|
||||||
|
public L048(String value) {
|
||||||
|
super(48, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class L128 extends AsciiChars {
|
||||||
|
|
||||||
|
public L128(String value) {
|
||||||
|
super(128, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class L255 extends AsciiChars {
|
||||||
|
|
||||||
|
public L255(String value) {
|
||||||
|
super(255, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
package vs;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper class for RFC 5424 (https://datatracker.ietf.org/doc/html/rfc5424)
|
||||||
|
* compliant log messages as immutable Java objects - structured data (set of
|
||||||
|
* key/value-pairs) with some predefined sets according to the standard
|
||||||
|
*
|
||||||
|
* @author Sandro Leuchter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class StructuredData {
|
||||||
|
|
||||||
|
public static class Element {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private List<Param> parameters;
|
||||||
|
|
||||||
|
public static Element newTimeQuality(
|
||||||
|
boolean tzKnown,
|
||||||
|
boolean isSynced
|
||||||
|
) {
|
||||||
|
return newTimeQuality(tzKnown, isSynced, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element newTimeQuality(
|
||||||
|
boolean tzKnown,
|
||||||
|
boolean isSynced,
|
||||||
|
Integer syncAccuracy
|
||||||
|
) {
|
||||||
|
var e = new Element("timeQuality");
|
||||||
|
e.add(new Param("tzKnown", (tzKnown) ? "1" : "0"));
|
||||||
|
e.add(new Param("isSynced", (isSynced) ? "1" : "0"));
|
||||||
|
if (syncAccuracy != null && !isSynced) {
|
||||||
|
e.add(new Param("syncAccuracy", String.valueOf(syncAccuracy)));
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element newOrigin(
|
||||||
|
String enterpriseId,
|
||||||
|
String software,
|
||||||
|
String swVersion
|
||||||
|
) {
|
||||||
|
return newOrigin(
|
||||||
|
new String[] {},
|
||||||
|
enterpriseId,
|
||||||
|
software,
|
||||||
|
swVersion
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element newOrigin(
|
||||||
|
String ip,
|
||||||
|
String enterpriseId,
|
||||||
|
String software,
|
||||||
|
String swVersion
|
||||||
|
) {
|
||||||
|
return newOrigin(
|
||||||
|
new String[] { ip },
|
||||||
|
enterpriseId,
|
||||||
|
software,
|
||||||
|
swVersion
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element newOrigin(
|
||||||
|
String[] ip,
|
||||||
|
String enterpriseId,
|
||||||
|
String software,
|
||||||
|
String swVersion
|
||||||
|
) {
|
||||||
|
var e = new Element("origin");
|
||||||
|
for (var p : ip) {
|
||||||
|
e = e.add(new Param("ip", p));
|
||||||
|
}
|
||||||
|
if (enterpriseId != null && !enterpriseId.equals("")) {
|
||||||
|
e = e.add(new Param("enterpriseId", enterpriseId));
|
||||||
|
}
|
||||||
|
if (software != null && !software.equals("")) {
|
||||||
|
e = e.add(new Param("software", software));
|
||||||
|
}
|
||||||
|
if (swVersion != null && !swVersion.equals("")) {
|
||||||
|
e = e.add(new Param("swVersion", swVersion));
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element newMeta(
|
||||||
|
Integer sequenceId,
|
||||||
|
Integer sysUpTime,
|
||||||
|
String language
|
||||||
|
) {
|
||||||
|
var e = new Element("meta");
|
||||||
|
if (sequenceId != null && sequenceId > 0) {
|
||||||
|
e = e.add(
|
||||||
|
new Param(
|
||||||
|
"sequenceId",
|
||||||
|
String.valueOf(sequenceId % 2147483647)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (sysUpTime != null && sysUpTime >= 0) {
|
||||||
|
e = e.add(new Param("sysUpTime", String.valueOf(sysUpTime)));
|
||||||
|
}
|
||||||
|
if (language != null && !language.equals("")) {
|
||||||
|
e = e.add(new Param("language", language));
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element(String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.parameters = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element add(Param parameter) {
|
||||||
|
var e = new Element(this.name);
|
||||||
|
e.parameters = this.parameters;
|
||||||
|
e.parameters.add(parameter);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
var str = "[" + this.name;
|
||||||
|
for (var p : this.parameters) {
|
||||||
|
str = str + " " + p.toString();
|
||||||
|
}
|
||||||
|
return str + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Param {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
// name: printable US-ASCII string ^[@=\]\"\s]+
|
||||||
|
// "@" + private enterpise number "@\d+(\.\d+)*"
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
public Param(String name, String value) {
|
||||||
|
this.name = name; // 7-Bit ASCII
|
||||||
|
this.value = value; // UTF-8
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.name + "=\"" + this.value + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Element> params;
|
||||||
|
|
||||||
|
public StructuredData() {
|
||||||
|
this.params = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StructuredData(List<Element> params) {
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (this.params.size() == 0) {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
var str = "";
|
||||||
|
for (var p : this.params) {
|
||||||
|
str = str + p.toString();
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StructuredData add(Element e) {
|
||||||
|
var p = this.params;
|
||||||
|
p.add(e);
|
||||||
|
return new StructuredData(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
package vs;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RFC 5424 (https://datatracker.ietf.org/doc/html/rfc5424) compliant log
|
||||||
|
* messages as immutable Java objects
|
||||||
|
*
|
||||||
|
* @author Sandro Leuchter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SyslogMessage implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5895573029109990861L;
|
||||||
|
private final Facility fac;
|
||||||
|
private final Severity sev;
|
||||||
|
private final AsciiChars.L255 host;
|
||||||
|
private final AsciiChars.L048 appName;
|
||||||
|
private final AsciiChars.L128 procId;
|
||||||
|
private final AsciiChars.L032 msgId;
|
||||||
|
private final StructuredData data;
|
||||||
|
private final Message message;
|
||||||
|
|
||||||
|
public SyslogMessage(
|
||||||
|
Facility fac,
|
||||||
|
Severity sev,
|
||||||
|
AsciiChars.L255 host,
|
||||||
|
AsciiChars.L048 appName,
|
||||||
|
AsciiChars.L128 procId,
|
||||||
|
AsciiChars.L032 msgId,
|
||||||
|
StructuredData data,
|
||||||
|
Message message
|
||||||
|
) {
|
||||||
|
this.fac = fac;
|
||||||
|
this.sev = sev;
|
||||||
|
this.host = host;
|
||||||
|
this.appName = appName;
|
||||||
|
this.procId = procId;
|
||||||
|
this.msgId = msgId;
|
||||||
|
this.data = data;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Facility fac() {
|
||||||
|
return this.fac;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Severity sev() {
|
||||||
|
return sev;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsciiChars.L255 host() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsciiChars.L048 appName() {
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsciiChars.L128 procId() {
|
||||||
|
return procId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsciiChars.L032 msgId() {
|
||||||
|
return msgId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StructuredData data() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Message message() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int version() {
|
||||||
|
return VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum Facility {
|
||||||
|
KERNEL,
|
||||||
|
USER,
|
||||||
|
MAIL_SYSTEM,
|
||||||
|
SYS_DAEMON,
|
||||||
|
SECURITY1,
|
||||||
|
INTERNAL,
|
||||||
|
PRINTER,
|
||||||
|
NEWS,
|
||||||
|
UUCP,
|
||||||
|
CLOCK1,
|
||||||
|
SECURITY2,
|
||||||
|
FTP,
|
||||||
|
NTP,
|
||||||
|
AUDIT,
|
||||||
|
ALERT,
|
||||||
|
CLOCK2,
|
||||||
|
LOCAL0,
|
||||||
|
LOCAL1,
|
||||||
|
LOCAL2,
|
||||||
|
LOCAL3,
|
||||||
|
LOCAL4,
|
||||||
|
LOCAL5,
|
||||||
|
LOCAL6,
|
||||||
|
LOCAL7,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum Severity {
|
||||||
|
EMERGENCY,
|
||||||
|
ALERT,
|
||||||
|
CRITICAL,
|
||||||
|
ERROR,
|
||||||
|
WARNING,
|
||||||
|
NOTICE,
|
||||||
|
INFORMATIONAL,
|
||||||
|
DEBUG,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface Message {
|
||||||
|
public Object message();
|
||||||
|
|
||||||
|
public int length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BinaryMessage implements Message {
|
||||||
|
|
||||||
|
private Byte[] message;
|
||||||
|
|
||||||
|
public BinaryMessage(Byte[] message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return message.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object message() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return this.message.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TextMessage implements Message {
|
||||||
|
|
||||||
|
private String message; // UTF8
|
||||||
|
|
||||||
|
public TextMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "\u00EF\u00BB\u00BF" + message.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object message() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return this.message.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final int VERSION = 1; // RFC 5424, Mar 2009
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
var prival = String.valueOf(fac().ordinal() * 8 + sev().ordinal());
|
||||||
|
var d = "";
|
||||||
|
if (data() != null) {
|
||||||
|
d = " " + data();
|
||||||
|
}
|
||||||
|
var m = "";
|
||||||
|
if (
|
||||||
|
message() != null &&
|
||||||
|
message().message() != null &&
|
||||||
|
message().length() > 0
|
||||||
|
) {
|
||||||
|
m = " " + message();
|
||||||
|
}
|
||||||
|
var timestamp = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(
|
||||||
|
new Date()
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
"<" +
|
||||||
|
prival +
|
||||||
|
">" +
|
||||||
|
VERSION +
|
||||||
|
" " +
|
||||||
|
timestamp +
|
||||||
|
" " +
|
||||||
|
host().toString() +
|
||||||
|
" " +
|
||||||
|
appName().toString() +
|
||||||
|
" " +
|
||||||
|
procId().toString() +
|
||||||
|
" " +
|
||||||
|
msgId().toString() +
|
||||||
|
d +
|
||||||
|
m
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
package vs;
|
||||||
|
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.io.IOException;
|
||||||
|
import vs.SyslogMessage;
|
||||||
|
import vs.AsciiChars;
|
||||||
|
|
||||||
|
|
||||||
|
public class SyslogServer {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int port = 514; // Default syslog port: 514, but using 5514 to avoid permission issues
|
||||||
|
SyslogServer server = new SyslogServer();
|
||||||
|
server.start(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runDiscoveryListener() {
|
||||||
|
try {
|
||||||
|
DatagramSocket discoverySocket = new DatagramSocket(8888); // Port for discovery
|
||||||
|
|
||||||
|
byte[] bufferDiscovery = new byte[256];
|
||||||
|
|
||||||
|
System.out.println("Discovery Listener started on port 8888");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
DatagramPacket discoveryRequest = new DatagramPacket(bufferDiscovery, bufferDiscovery.length);
|
||||||
|
discoverySocket.receive(discoveryRequest);
|
||||||
|
|
||||||
|
InetAddress clientAddress = discoveryRequest.getAddress();
|
||||||
|
int clientPort = discoveryRequest.getPort();
|
||||||
|
|
||||||
|
System.out.println(
|
||||||
|
"Discovery request received from: " + clientAddress.getHostAddress() + ":" + clientPort);
|
||||||
|
|
||||||
|
// Send a response back to the client
|
||||||
|
byte[] responseData = "SYSLOG_SERVER".getBytes(StandardCharsets.UTF_8);
|
||||||
|
DatagramPacket discoveryResponse = new DatagramPacket(
|
||||||
|
responseData,
|
||||||
|
responseData.length,
|
||||||
|
clientAddress,
|
||||||
|
clientPort);
|
||||||
|
|
||||||
|
discoverySocket.send(discoveryResponse);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int MAX_MESSAGE_SIZE = 480;
|
||||||
|
|
||||||
|
public void start(int port) {
|
||||||
|
|
||||||
|
System.out.println("Syslog Server started on port " + port);
|
||||||
|
// Discovery Listener in a separate thread
|
||||||
|
new Thread(() -> runDiscoveryListener()).start();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create a DatagramSocket to listen for incoming messages
|
||||||
|
DatagramSocket socket = new DatagramSocket(port);
|
||||||
|
|
||||||
|
// Buffer to hold incoming messages
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
||||||
|
|
||||||
|
// Wait for a message to be received (blocking call)
|
||||||
|
socket.receive(packet);
|
||||||
|
|
||||||
|
// Extract the message from the packet + data; how many bytes were actually
|
||||||
|
// received
|
||||||
|
int length = packet.getLength();
|
||||||
|
|
||||||
|
if (length > MAX_MESSAGE_SIZE) {
|
||||||
|
System.err.println("Received message exceeds maximum allowed size of " + MAX_MESSAGE_SIZE
|
||||||
|
+ " bytes. Message will be ignored.");
|
||||||
|
continue; // Skip processing this message
|
||||||
|
}
|
||||||
|
|
||||||
|
String message = new String(
|
||||||
|
packet.getData(), // complete byte array be aware: packet.getData() returns the entire buffer,
|
||||||
|
// not just the received data
|
||||||
|
packet.getOffset(), // get the offset where the data starts
|
||||||
|
length,
|
||||||
|
StandardCharsets.UTF_8); // Convert the byte array to a string using UTF-8 encoding
|
||||||
|
|
||||||
|
// Show Client IP and Port
|
||||||
|
InetAddress clientAddress = packet.getAddress();
|
||||||
|
int clientPort = packet.getPort();
|
||||||
|
System.out.println("From: " + clientAddress.getHostAddress() + ":" + clientPort);
|
||||||
|
|
||||||
|
System.out.println("Message received: " + message);
|
||||||
|
|
||||||
|
SyslogMessage syslogMessage = new SyslogMessage(
|
||||||
|
SyslogMessage.Facility.LOCAL0,
|
||||||
|
SyslogMessage.Severity.INFORMATIONAL,
|
||||||
|
new AsciiChars.L255("server"),
|
||||||
|
new AsciiChars.L048("syslogServer"),
|
||||||
|
new AsciiChars.L128("-"),
|
||||||
|
new AsciiChars.L032("MSG"),
|
||||||
|
null,
|
||||||
|
new SyslogMessage.TextMessage(message)
|
||||||
|
);
|
||||||
|
|
||||||
|
System.out.println("Formatted Syslog Message: " + syslogMessage.toString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (IOException e) {
|
||||||
|
System.err.println("Could not start server: " + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package vs;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class AsciiCharsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nullValue() {
|
||||||
|
var ac = new AsciiChars.L004(null);
|
||||||
|
assertEquals(ac.toString(), "-");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void emptyValue() {
|
||||||
|
var ac = new AsciiChars.L004("");
|
||||||
|
assertEquals(ac.toString(), "-");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void longValue() {
|
||||||
|
var ac = new AsciiChars.L004("1234");
|
||||||
|
assertEquals(ac.toString(), "1234");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void longerValue() {
|
||||||
|
var thrown = assertThrows(IllegalArgumentException.class, () -> {
|
||||||
|
new AsciiChars.L004("12345");
|
||||||
|
});
|
||||||
|
assertEquals("Stringlänge = 5 > 4", thrown.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void space() {
|
||||||
|
var thrown = assertThrows(IllegalArgumentException.class, () -> {
|
||||||
|
new AsciiChars.L004("1 1");
|
||||||
|
});
|
||||||
|
assertEquals(
|
||||||
|
"Stringinhalt nicht printable US-ASCII ohne Space",
|
||||||
|
thrown.getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void special() {
|
||||||
|
var thrown = assertThrows(IllegalArgumentException.class, () -> {
|
||||||
|
new AsciiChars.L004("ä");
|
||||||
|
});
|
||||||
|
assertEquals(
|
||||||
|
"Stringinhalt nicht printable US-ASCII ohne Space",
|
||||||
|
thrown.getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
package vs;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import vs.StructuredData.*;
|
||||||
|
import vs.SyslogMessage.*;
|
||||||
|
|
||||||
|
class SyslogMessageTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testToString() {
|
||||||
|
var m1 = new SyslogMessage(
|
||||||
|
//
|
||||||
|
Facility.SECURITY1, //
|
||||||
|
Severity.CRITICAL, //
|
||||||
|
new AsciiChars.L255("mymachine.example.com"), //
|
||||||
|
new AsciiChars.L048("su"), //
|
||||||
|
new AsciiChars.L128(""), //
|
||||||
|
new AsciiChars.L032("ID47"), //
|
||||||
|
new StructuredData() //
|
||||||
|
.add(Element.newTimeQuality(true, true))
|
||||||
|
.add(
|
||||||
|
new Element("exampleSDID@32473")
|
||||||
|
.add(new Param("iut", "3"))
|
||||||
|
.add(new Param("eventSource", "Application"))
|
||||||
|
.add(new Param("eventID", "1011"))
|
||||||
|
)
|
||||||
|
.add(
|
||||||
|
new Element("examplePriority@32473").add(
|
||||||
|
new Param("class", "high")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
new TextMessage("'su root' failed for lonvick on /dev/pts/8")
|
||||||
|
);
|
||||||
|
var s = m1.toString();
|
||||||
|
assertEquals(s.substring(0, 6), "<34>1 ");
|
||||||
|
assertEquals(
|
||||||
|
s.substring(s.length() - 221, s.length()),
|
||||||
|
" mymachine.example.com su - ID47 [timeQuality tzKnown=\"1\" isSynced=\"1\"][exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"][examplePriority@32473 class=\"high\"] 'su root' failed for lonvick on /dev/pts/8"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test2() {
|
||||||
|
var m1 = new SyslogMessage(
|
||||||
|
//
|
||||||
|
Facility.SECURITY1, //
|
||||||
|
Severity.CRITICAL, //
|
||||||
|
new AsciiChars.L255("mymachine.example.com"), //
|
||||||
|
new AsciiChars.L048("su"), //
|
||||||
|
new AsciiChars.L128(""), //
|
||||||
|
new AsciiChars.L032("ID47"), //
|
||||||
|
null, //
|
||||||
|
new TextMessage("'su root' failed for lonvick on /dev/pts/8")
|
||||||
|
);
|
||||||
|
var s = m1.toString();
|
||||||
|
assertEquals(s.substring(0, 6), "<34>1 ");
|
||||||
|
assertEquals(
|
||||||
|
s.substring(s.length() - 78, s.length()),
|
||||||
|
" mymachine.example.com su - ID47 'su root' failed for lonvick on /dev/pts/8"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test3() {
|
||||||
|
var m1 = new SyslogMessage(
|
||||||
|
//
|
||||||
|
Facility.SECURITY1, //
|
||||||
|
Severity.CRITICAL, //
|
||||||
|
new AsciiChars.L255("mymachine.example.com"), //
|
||||||
|
new AsciiChars.L048("su"), //
|
||||||
|
new AsciiChars.L128(""), //
|
||||||
|
new AsciiChars.L032("ID47"), //
|
||||||
|
new StructuredData() //
|
||||||
|
.add(Element.newTimeQuality(true, true))
|
||||||
|
.add(
|
||||||
|
Element.newOrigin(
|
||||||
|
new String[] { "0.0.8.8", "8.8.8.8" },
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.add(Element.newMeta(null, 32, "de")),
|
||||||
|
new BinaryMessage(null)
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
m1.data().toString(),
|
||||||
|
"[timeQuality tzKnown=\"1\" isSynced=\"1\"][origin ip=\"0.0.8.8\" ip=\"8.8.8.8\"][meta sysUpTime=\"32\" language=\"de\"]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue