From 6e844c926130b64e716b6d13031db4ab913bb815 Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Wed, 6 Nov 2024 14:40:34 +0200
Subject: [PATCH 01/14] Sync in the middle, WIP
---
.gitignore | 2 +
README.adoc | 35 +-
eclipse-java-formatter.xml | 450 +++++++++++++
license-header | 45 ++
pom.xml | 593 ++++++++++++++++++
src/main/assembly/jar-with-dependencies.xml | 21 +
src/main/java/com/teragrep/rlp_11/Main.java | 97 +++
.../java/com/teragrep/rlp_11/RelpProbe.java | 175 ++++++
.../rlp_11/RelpProbeConfiguration.java | 187 ++++++
.../rlp_11/RelpProbeConfigurationError.java | 53 ++
.../com/teragrep/rlp_11/ConnectionTest.java | 135 ++++
.../rlp_11/InvalidConfigValidationTest.java | 219 +++++++
src/test/resources/connectiontest.properties | 17 +
13 files changed, 2011 insertions(+), 18 deletions(-)
create mode 100644 .gitignore
create mode 100644 eclipse-java-formatter.xml
create mode 100644 license-header
create mode 100644 pom.xml
create mode 100644 src/main/assembly/jar-with-dependencies.xml
create mode 100644 src/main/java/com/teragrep/rlp_11/Main.java
create mode 100644 src/main/java/com/teragrep/rlp_11/RelpProbe.java
create mode 100644 src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
create mode 100644 src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java
create mode 100644 src/test/java/com/teragrep/rlp_11/ConnectionTest.java
create mode 100644 src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
create mode 100644 src/test/resources/connectiontest.properties
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..92322c4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.idea/
+target/
diff --git a/README.adoc b/README.adoc
index 0f563cc..e102f52 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,35 +1,34 @@
-// Before publishing your new repository:
-// 1. Write the readme file
-// 2. Update the issues link in Contributing section in the readme file
-// 3. Update the discussion link in config.yml file in .github/ISSUE_TEMPLATE directory
+= RELP Commit Latency Probe rlp_11
-= repo-template
-
-// Add a short description of your project. Tell what your project does and what it's used for.
-
-This is a template repository for Teragrep organization.
+Measures latency for RELP events.
== Features
-// List your project's features
+Provides Dropwizard metrics
-== Documentation
+Provides Prometheus endpoint
-See the official documentation on https://docs.teragrep.com[docs.teragrep.com].
+== Documentation
== Limitations
-// If your project has limitations, please list them. Otherwise remove this section.
+== How to compile
-== How to [compile/use/implement]
+[source]
+----
+mvn clean package
+----
-// add instructions how people can start to use your project
+== How to use
-== Contributing
+[source]
+----
+java -jar rlp_11.jar
+----
-// Change the repository name in the issues link to match with your project's name
+== Contributing
-You can involve yourself with our project by https://github.com/teragrep/repo-template/issues/new/choose[opening an issue] or submitting a pull request.
+You can involve yourself with our project by https://github.com/teragrep/rlp_11/issues/new/choose[opening an issue] or submitting a pull request.
Contribution requirements:
diff --git a/eclipse-java-formatter.xml b/eclipse-java-formatter.xml
new file mode 100644
index 0000000..53b9f2a
--- /dev/null
+++ b/eclipse-java-formatter.xml
@@ -0,0 +1,450 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/license-header b/license-header
new file mode 100644
index 0000000..1ace12e
--- /dev/null
+++ b/license-header
@@ -0,0 +1,45 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..5019ef4
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,593 @@
+
+
+ 4.0.0
+ com.teragrep
+ rlp_11
+ ${revision}${sha1}${changelist}
+ jar
+ rlp_11
+ RELP Commit Latency Probe
+ https://teragrep.com
+
+ -SNAPSHOT
+ 0.0.1-SNAPSHOT
+ 4.2.28
+ 17
+ 1.11.3
+ 5.11.3
+ 17
+ 17
+ UTF-8
+ UTF-8
+ 0.16.0
+ 0.0.1
+ 1.0.1
+ 4.0.3
+ 8.0.1
+
+ 2.0.16
+
+
+
+
+ com.teragrep
+ cnf_01
+ ${cnf_01.version}
+
+
+
+ com.teragrep
+ rlp_01
+ ${rlp_01.version}
+
+
+
+ com.teragrep
+ rlo_14
+ ${rlo_14.version}
+
+
+
+ io.dropwizard.metrics
+ metrics-core
+ ${dropwizard.metrics.version}
+
+
+ io.dropwizard.metrics
+ metrics-jmx
+ ${dropwizard.metrics.version}
+
+
+
+ io.prometheus
+ simpleclient
+ ${prometheus.version}
+
+
+ io.prometheus
+ simpleclient_dropwizard
+ ${prometheus.version}
+
+
+ io.prometheus
+ simpleclient_servlet
+ ${prometheus.version}
+
+
+ io.prometheus
+ simpleclient_hotspot
+ ${prometheus.version}
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j.version}
+
+
+
+ com.teragrep
+ rlp_03
+ ${rlp_03.version}
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.version}
+ test
+
+
+ org.junit.platform
+ junit-platform-launcher
+ ${junit.platform.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ ${junit.version}
+ test
+
+
+
+ ${project.basedir}/target
+ rlp_11
+
+
+ true
+ src/main/resources
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.5.0
+
+
+
+ scan-errors
+
+ check
+
+ process-classes
+
+ error
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ scan-warnings
+
+ check
+
+ process-classes
+
+ warning
+ true
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 3.4.1
+
+
+ enforce-settings
+
+ enforce
+
+
+
+
+
+
+ junit:junit
+
+
+
+ 3.6.53
+
+
+ [17,18)
+
+
+
+
+ com.teragrep:*:0.0.1-SNAPSHOT
+
+
+
+ All plugins are required to contain specific version.
+ org.apache.maven.plugins:maven-site-plugin,org.apache.maven.plugins:maven-resources-plugin,org.apache.maven.plugins:maven-clean-plugin,org.apache.maven.plugins:maven-install-plugin,org.apache.maven.plugins:maven-deploy-plugin,org.apache.maven.plugins:maven-compiler-plugin,org.apache.maven.plugins:maven-jar-plugin
+
+
+ Do not use any external repositories.
+
+
+
+
+
+
+
+
+ com.diffplug.spotless
+ spotless-maven-plugin
+ 2.43.0
+
+
+
+ ${project.basedir}/eclipse-java-formatter.xml
+ 4.10.0
+
+
+
+ ${project.basedir}/license-header
+
+
+
+
+
+ UTF-8
+ \n
+ true
+ false
+ 2
+ recommended_2008_06
+ true
+ true
+ true
+
+
+
+
+
+ .gitattributes
+ .gitignore
+
+
+
+
+ true
+ 4
+
+
+
+
+
+
+
+ check
+
+ compile
+
+
+
+
+
+ org.apache.rat
+ apache-rat-plugin
+ 0.16.1
+ false
+
+ false
+ false
+
+
+ Teragrep
+ Affero General Public License v3
+
+
+
+
+
+
+ Suomen Kanuuna Oy
+ 2024
+
+ RELP Commit Latency Probe RLP-11
+
+ Teragrep
+
+
+ true
+ false
+
+
+ .git/**
+ .gitattributes
+ .gitignore
+ .gitmodules
+
+ .github/workflows/*
+ .github/ISSUE_TEMPLATE/*
+ .github/PULL_REQUEST_TEMPLATE/*
+ toolchains.xml
+ settings.xml
+
+ pom.xml
+ eclipse-java-formatter.xml
+ src/main/assembly/jar-with-dependencies.xml
+
+ src/test/resources/*.properties
+
+ README.adoc
+
+
+
+
+
+ check
+
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.7.1
+
+
+ src/main/assembly/jar-with-dependencies.xml
+
+
+
+ com.teragrep.rlp_11.Main
+ true
+
+
+
+
+
+ make-assembly
+
+ single
+
+ package
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.5.2
+
+ all
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 3.5.2
+
+
+
+ integration-test
+ verify
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 3.1.3
+
+ false
+
+
+
+
+
+
+ publish-github-packages
+
+
+ github
+ GitHub Packages
+ https://maven.pkg.github.com/teragrep/rlp_11
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+
+ sign
+
+ verify
+
+
+ --pinentry-mode
+ loopback
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/assembly/jar-with-dependencies.xml b/src/main/assembly/jar-with-dependencies.xml
new file mode 100644
index 0000000..16d41cd
--- /dev/null
+++ b/src/main/assembly/jar-with-dependencies.xml
@@ -0,0 +1,21 @@
+
+ jar-with-dependencies
+
+ jar
+
+ false
+
+
+ metaInf-services
+
+
+
+
+ true
+ true
+ runtime
+
+
+
diff --git a/src/main/java/com/teragrep/rlp_11/Main.java b/src/main/java/com/teragrep/rlp_11/Main.java
new file mode 100644
index 0000000..f98885f
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Main.java
@@ -0,0 +1,97 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11;
+
+import com.teragrep.cnf_01.ConfigurationException;
+import com.teragrep.cnf_01.PathConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+public class Main {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
+
+ public static void main(final String[] args) {
+ PathConfiguration pathConfiguration = new PathConfiguration(
+ System.getProperty("configurationPath", "etc/rlp_11.properties")
+ );
+ Map map;
+ try {
+ map = pathConfiguration.asMap();
+ }
+ catch (ConfigurationException e) {
+ LOGGER.error("Failed to create PathConfiguration: <{}>", e.getMessage(), e);
+ return;
+ }
+ RelpProbeConfiguration relpProbeConfiguration = new RelpProbeConfiguration(map);
+ try {
+ relpProbeConfiguration.validate();
+ }
+ catch (RelpProbeConfigurationError e) {
+ LOGGER.error("Failed to validate config: <{}>", e.getMessage(), e);
+ }
+
+ RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
+ Thread shutdownHook = new Thread(() -> {
+ LOGGER.info("Shutting down...");
+ relpProbe.stop();
+ });
+ Runtime.getRuntime().addShutdownHook(shutdownHook);
+ LOGGER
+ .info(
+ "Sending events to <[{}:{}]>", relpProbeConfiguration.getTargetHostname(),
+ relpProbeConfiguration.getTargetPort()
+ );
+ LOGGER
+ .info(
+ "Using hostname <[{}]> and appname <[{}]> for the events.",
+ relpProbeConfiguration.getEventHostname(), relpProbeConfiguration.getEventAppname()
+ );
+ relpProbe.start();
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
new file mode 100644
index 0000000..8f9dc29
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -0,0 +1,175 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11;
+
+import com.teragrep.rlo_14.Facility;
+import com.teragrep.rlo_14.Severity;
+import com.teragrep.rlo_14.SyslogMessage;
+import com.teragrep.rlp_01.RelpBatch;
+import com.teragrep.rlp_01.RelpConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class RelpProbe {
+
+ private final RelpProbeConfiguration config;
+ private boolean stayRunning = true;
+ private RelpConnection relpConnection;
+ private final CountDownLatch latch = new CountDownLatch(1);
+ private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbe.class);
+ private boolean connected = false;
+
+ public RelpProbe(RelpProbeConfiguration config) {
+ this.config = config;
+ }
+
+ public void start() {
+ relpConnection = new RelpConnection();
+ connect();
+ int eventDelay = config.getEventDelay();
+ while (stayRunning) {
+ RelpBatch relpBatch = new RelpBatch();
+ Instant timestamp = Instant.now();
+ byte[] record = new SyslogMessage()
+ .withTimestamp(timestamp.toEpochMilli())
+ .withAppName(config.getEventAppname())
+ .withHostname(config.getEventHostname())
+ .withFacility(Facility.USER)
+ .withSeverity(Severity.INFORMATIONAL)
+ .withMsg(timestamp.getEpochSecond() + "." + timestamp.getNano())
+ .toRfc5424SyslogMessage()
+ .getBytes(StandardCharsets.UTF_8);
+ relpBatch.insert(record);
+
+ boolean allSent = false;
+ while (!allSent) {
+ try {
+ relpConnection.commit(relpBatch);
+ }
+ catch (IllegalStateException | IOException | java.util.concurrent.TimeoutException e) {
+ LOGGER.warn("Failed to commit: <{}>", e.getMessage());
+ relpConnection.tearDown();
+ connected = false;
+ }
+ allSent = relpBatch.verifyTransactionAll();
+ if (!allSent) {
+ relpBatch.retryAllFailed();
+ reconnect();
+ }
+ }
+ try {
+ Thread.sleep(eventDelay);
+ }
+ catch (InterruptedException e) {
+ LOGGER.warn("Sleep interrupted: <{}>", e.getMessage());
+ }
+ }
+
+ }
+
+ private void connect() {
+ while (!connected && stayRunning) {
+ try {
+ connected = relpConnection.connect(config.getTargetHostname(), config.getTargetPort());
+ }
+ catch (TimeoutException | IOException e) {
+ LOGGER
+ .warn(
+ "Failed to connect to <[{}:{}]>: <{}>", config.getTargetHostname(),
+ config.getTargetPort(), e.getMessage()
+ );
+ }
+ if (!connected) {
+ try {
+ Thread.sleep(config.getReconnectInterval());
+ }
+ catch (InterruptedException e) {
+ LOGGER.warn("Sleep was interrupted: <{}>", e.getMessage());
+ }
+ }
+ }
+ }
+
+ private void reconnect() {
+ disconnect();
+ connect();
+ }
+
+ private void disconnect() {
+ if (!connected) {
+ return;
+ }
+ try {
+ relpConnection.disconnect();
+ }
+ catch (IOException | TimeoutException e) {
+ LOGGER.warn("Failed to disconnect: <{}>", e.getMessage());
+ }
+ relpConnection.tearDown();
+ connected = false;
+ }
+
+ public void stop() {
+ disconnect();
+ stayRunning = false;
+ try {
+ if (!latch.await(5L, TimeUnit.SECONDS)) {
+ throw new RuntimeException("Timed out while waiting for probe to shutdown.");
+ }
+ }
+ catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
new file mode 100644
index 0000000..6adda51
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
@@ -0,0 +1,187 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+public class RelpProbeConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbeConfiguration.class);
+ private final Map config;
+
+ public RelpProbeConfiguration(Map config) {
+ this.config = config;
+ }
+
+ public void validate() throws RelpProbeConfigurationError {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Validating the following configuration: {}", config);
+ }
+
+ if (config.get("event.hostname") == null) {
+ LOGGER.error("Missing property");
+ throw new RelpProbeConfigurationError("Missing property");
+ }
+
+ if (config.get("event.appname") == null) {
+ LOGGER.error("Missing property");
+ throw new RelpProbeConfigurationError("Missing property");
+ }
+
+ String eventDelay = config.get("event.delay");
+ if (eventDelay == null) {
+ LOGGER.error("Missing property");
+ throw new RelpProbeConfigurationError("Missing property");
+ }
+ try {
+ int eventDelayInt = Integer.parseInt(eventDelay);
+ if (eventDelayInt <= 0) {
+ LOGGER.error("Invalid property, expected > 0, received <[{}]>", eventDelay);
+ throw new RelpProbeConfigurationError(
+ "Invalid property, expected > 0, received <[" + eventDelay + "]>"
+ );
+ }
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Invalid property received, not a number: <{}>", e.getMessage());
+ throw new RelpProbeConfigurationError(
+ "Invalid property received, not a number: <" + e.getMessage() + ">"
+ );
+ }
+
+ if (config.get("target.hostname") == null) {
+ LOGGER.error("Missing property");
+ throw new RelpProbeConfigurationError("Missing property");
+ }
+
+ String targetPort = config.get("target.port");
+ if (targetPort == null) {
+ LOGGER.error("Missing property");
+ throw new RelpProbeConfigurationError("Missing property");
+ }
+ try {
+ int targetPortInt = Integer.parseInt(targetPort);
+ if (targetPortInt <= 0 || targetPortInt > 65535) {
+ LOGGER
+ .error(
+ "Invalid property, expected between 1 and 65535, received <[{}]>",
+ targetPort
+ );
+ throw new RelpProbeConfigurationError(
+ "Invalid property, expected between 1 and 65535, received <[" + targetPort + "]>"
+ );
+ }
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Invalid property received, not a number: <{}>", e.getMessage());
+ throw new RelpProbeConfigurationError(
+ "Invalid property received, not a number: <" + e.getMessage() + ">"
+ );
+ }
+
+ if (config.get("prometheus.endpoint") == null) {
+ LOGGER.error("Missing property");
+ throw new RelpProbeConfigurationError("Missing property");
+ }
+
+ String reconnectInterval = config.get("relp.reconnectinterval");
+ if (reconnectInterval == null) {
+ LOGGER.error("Missing property");
+ throw new RelpProbeConfigurationError("Missing property");
+ }
+ try {
+ int reconnectIntervalInt = Integer.parseInt(reconnectInterval);
+ if (reconnectIntervalInt <= 0) {
+ LOGGER
+ .error(
+ "Invalid property, property, expected > 0, received <[{}]>",
+ reconnectIntervalInt
+ );
+ throw new RelpProbeConfigurationError(
+ "Invalid property, expected > 0, received <[" + reconnectInterval
+ + "]>"
+ );
+ }
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Invalid property received, not a number: <{}>", e.getMessage());
+ throw new RelpProbeConfigurationError(
+ "Invalid property received, not a number: <" + e.getMessage() + ">"
+ );
+ }
+ }
+
+ public String getEventHostname() {
+ return config.get("event.hostname");
+ }
+
+ public String getEventAppname() {
+ return config.get("event.appname");
+ }
+
+ public int getEventDelay() {
+ return Integer.parseInt(config.get("event.delay"));
+ }
+
+ public String getTargetHostname() {
+ return config.get("target.hostname");
+ }
+
+ public int getTargetPort() {
+ return Integer.parseInt(config.get("target.port"));
+ }
+
+ public String getPrometheusEndpoint() {
+ return config.get("prometheus.endpoint");
+ }
+
+ public int getReconnectInterval() {
+ return Integer.parseInt(config.get("relp.reconnectinterval"));
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java b/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java
new file mode 100644
index 0000000..f0c966d
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java
@@ -0,0 +1,53 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11;
+
+public class RelpProbeConfigurationError extends RuntimeException {
+
+ public RelpProbeConfigurationError(String s) {
+ super(s);
+ }
+}
diff --git a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
new file mode 100644
index 0000000..42f0ee0
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
@@ -0,0 +1,135 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11;
+
+import com.teragrep.cnf_01.PathConfiguration;
+import com.teragrep.net_01.channel.socket.PlainFactory;
+import com.teragrep.net_01.eventloop.EventLoop;
+import com.teragrep.net_01.eventloop.EventLoopFactory;
+import com.teragrep.net_01.server.ServerFactory;
+import com.teragrep.rlp_03.frame.FrameDelegationClockFactory;
+import com.teragrep.rlp_03.frame.RelpFrame;
+import com.teragrep.rlp_03.frame.delegate.DefaultFrameDelegate;
+import com.teragrep.rlp_03.frame.delegate.FrameContext;
+import com.teragrep.rlp_03.frame.delegate.FrameDelegate;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+public class ConnectionTest {
+
+ private static final int serverPort = 12345;
+ private Thread eventLoopThread;
+ private EventLoop eventLoop;
+ private ExecutorService executorService;
+ private final List records = new ArrayList<>();
+
+ @BeforeEach
+ public void StartServer() {
+ executorService = Executors.newFixedThreadPool(1);
+ Consumer syslogConsumer = new Consumer<>() {
+
+ @Override
+ public synchronized void accept(FrameContext frameContext) {
+ try (RelpFrame relpFrame = frameContext.relpFrame()) {
+ records.add(relpFrame.payload().toString());
+ }
+ }
+ };
+ Supplier frameDelegateSupplier = () -> new DefaultFrameDelegate(syslogConsumer);
+ EventLoopFactory eventLoopFactory = new EventLoopFactory();
+ eventLoop = Assertions.assertDoesNotThrow(eventLoopFactory::create);
+ eventLoopThread = new Thread(eventLoop);
+ eventLoopThread.start();
+ ServerFactory serverFactory = new ServerFactory(
+ eventLoop,
+ executorService,
+ new PlainFactory(),
+ new FrameDelegationClockFactory(frameDelegateSupplier)
+ );
+ Assertions.assertDoesNotThrow(() -> serverFactory.create(serverPort));
+ }
+
+ @AfterEach
+ public void StopServer() {
+ eventLoop.stop();
+ Assertions.assertDoesNotThrow(() -> eventLoopThread.join());
+ executorService.shutdown();
+ records.clear();
+ }
+
+ @Test
+ public void ConnectToServerTest() {
+ RelpProbeConfiguration relpProbeConfiguration = Assertions
+ .assertDoesNotThrow(
+ () -> new RelpProbeConfiguration(
+ new PathConfiguration("src/test/resources/connectiontest.properties").asMap()
+ )
+ );
+ RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
+
+ TimerTask task = new TimerTask() {
+
+ public void run() {
+ relpProbe.stop();
+ }
+ };
+ Timer timer = new Timer("Timer");
+ timer.schedule(task, 5000L);
+
+ relpProbe.start();
+ }
+}
diff --git a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
new file mode 100644
index 0000000..5bafae4
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
@@ -0,0 +1,219 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class InvalidConfigValidationTest {
+
+ // event.hostname tests
+ @Test
+ public void TestMissingEventHostname() {
+ Map map = getDefaultMap();
+ map.remove("event.hostname");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions.assertEquals("Missing property", e.getMessage());
+ }
+
+ // event.appname tests
+ @Test
+ public void testMissingAppname() {
+ Map map = getDefaultMap();
+ map.remove("event.appname");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions.assertEquals("Missing property", e.getMessage());
+ }
+
+ // event.delay tests
+ @Test
+ public void testMissingEventDelay() {
+ Map map = getDefaultMap();
+ map.remove("event.delay");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions.assertEquals("Missing property", e.getMessage());
+ }
+
+ @Test
+ public void testZeroEventDelay() {
+ Map map = getDefaultMap();
+ map.put("event.delay", "0");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions.assertEquals("Invalid property, expected > 0, received <[0]>", e.getMessage());
+ }
+
+ @Test
+ public void testNonNumericEventDelay() {
+ Map map = getDefaultMap();
+ map.put("event.delay", "not a number");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals(
+ "Invalid property received, not a number: ",
+ e.getMessage()
+ );
+ }
+
+ // target.hostname tests
+ @Test
+ public void testMissingTargetHostname() {
+ Map map = getDefaultMap();
+ map.remove("target.hostname");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions.assertEquals("Missing property", e.getMessage());
+ }
+
+ // target.port tests
+ @Test
+ public void testMissingPort() {
+ Map map = getDefaultMap();
+ map.remove("target.port");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions.assertEquals("Missing property", e.getMessage());
+ }
+
+ @Test
+ public void testTooSmallTargetPort() {
+ Map map = getDefaultMap();
+ map.put("target.port", "0");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals(
+ "Invalid property, expected between 1 and 65535, received <[0]>", e.getMessage()
+ );
+ }
+
+ @Test
+ public void testTooHighTargetPort() {
+ Map map = getDefaultMap();
+ map.put("target.port", "65536");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals(
+ "Invalid property, expected between 1 and 65535, received <[65536]>",
+ e.getMessage()
+ );
+ }
+
+ @Test
+ public void testNonNumericTargetPort() {
+ Map map = getDefaultMap();
+ map.put("target.port", "not a number");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals(
+ "Invalid property received, not a number: ",
+ e.getMessage()
+ );
+ }
+
+ // relp.reconnectinterval tests
+ @Test
+ public void testMissingReconnectInterval() {
+ Map map = getDefaultMap();
+ map.remove("relp.reconnectinterval");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions.assertEquals("Missing property", e.getMessage());
+ }
+
+ @Test
+ public void testZeroReconnectInterval() {
+ Map map = getDefaultMap();
+ map.put("relp.reconnectinterval", "0");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals("Invalid property, expected > 0, received <[0]>", e.getMessage());
+ }
+
+ @Test
+ public void testNonNumericReconnectInterval() {
+ Map map = getDefaultMap();
+ map.put("relp.reconnectinterval", "not a number");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals(
+ "Invalid property received, not a number: ",
+ e.getMessage()
+ );
+ }
+
+ // prometheus.endport tests
+ @Test
+ public void testMissingPrometheusEndpoint() {
+ Map map = getDefaultMap();
+ map.remove("prometheus.endpoint");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions.assertEquals("Missing property", e.getMessage());
+ }
+
+ private Map getDefaultMap() {
+ Map map = new HashMap<>();
+ map.put("event.hostname", "rlp_11");
+ map.put("event.appname", "rlp_11");
+ map.put("event.delay", "1000");
+ map.put("target.hostname", "127.0.0.1");
+ map.put("target.port", "12345");
+ map.put("prometheus.endpoint", "127.0.0.1:8080");
+ return map;
+ }
+}
diff --git a/src/test/resources/connectiontest.properties b/src/test/resources/connectiontest.properties
new file mode 100644
index 0000000..a92dad6
--- /dev/null
+++ b/src/test/resources/connectiontest.properties
@@ -0,0 +1,17 @@
+# Hostname used in RELP event
+event.hostname=rlp_11
+# Appname used in RELP event
+event.appname=rlp_11
+# Delay between sending events, in milliseconds
+event.delay=1000
+
+# RELP Server target address
+target.hostname=127.0.0.1
+# Relp Server target port
+target.port=12345
+
+# RELP reconnect interval
+relp.reconnectinterval=1000
+
+# Prometheus endpoint port
+prometheus.endpoint=127.0.0.1:8080
From 3d4dc6e3b5f7e0f8037385aab74fd543d14784ed Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Wed, 6 Nov 2024 14:53:04 +0200
Subject: [PATCH 02/14] Some minor fixes
---
src/main/java/com/teragrep/rlp_11/Main.java | 3 ++-
src/main/java/com/teragrep/rlp_11/RelpProbe.java | 9 ++++++---
.../teragrep/rlp_11/RelpProbeConfiguration.java | 16 ++++++++--------
.../java/com/teragrep/rlp_11/ConnectionTest.java | 5 +++++
.../rlp_11/InvalidConfigValidationTest.java | 15 +++++++++------
src/test/resources/connectiontest.properties | 5 ++---
6 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/src/main/java/com/teragrep/rlp_11/Main.java b/src/main/java/com/teragrep/rlp_11/Main.java
index f98885f..f9bf13a 100644
--- a/src/main/java/com/teragrep/rlp_11/Main.java
+++ b/src/main/java/com/teragrep/rlp_11/Main.java
@@ -78,8 +78,9 @@ public static void main(final String[] args) {
RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
Thread shutdownHook = new Thread(() -> {
- LOGGER.info("Shutting down...");
+ LOGGER.info("Stopping RelpProbe..");
relpProbe.stop();
+ LOGGER.info("Shutting down.");
});
Runtime.getRuntime().addShutdownHook(shutdownHook);
LOGGER
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index 8f9dc29..377333c 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -93,7 +93,7 @@ public void start() {
relpBatch.insert(record);
boolean allSent = false;
- while (!allSent) {
+ while (!allSent && stayRunning) {
try {
relpConnection.commit(relpBatch);
}
@@ -115,7 +115,10 @@ public void start() {
LOGGER.warn("Sleep interrupted: <{}>", e.getMessage());
}
}
-
+ LOGGER.info("Disconnecting..");
+ disconnect();
+ LOGGER.info("Disconnected.");
+ latch.countDown();
}
private void connect() {
@@ -161,7 +164,6 @@ private void disconnect() {
}
public void stop() {
- disconnect();
stayRunning = false;
try {
if (!latch.await(5L, TimeUnit.SECONDS)) {
@@ -171,5 +173,6 @@ public void stop() {
catch (InterruptedException e) {
throw new RuntimeException(e);
}
+ LOGGER.info("RelpProbe stopped.");
}
}
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
index 6adda51..bbcf1fa 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
@@ -130,29 +130,29 @@ public void validate() throws RelpProbeConfigurationError {
throw new RelpProbeConfigurationError("Missing property");
}
- String reconnectInterval = config.get("relp.reconnectinterval");
+ String reconnectInterval = config.get("target.reconnectinterval");
if (reconnectInterval == null) {
- LOGGER.error("Missing property");
- throw new RelpProbeConfigurationError("Missing property");
+ LOGGER.error("Missing property");
+ throw new RelpProbeConfigurationError("Missing property");
}
try {
int reconnectIntervalInt = Integer.parseInt(reconnectInterval);
if (reconnectIntervalInt <= 0) {
LOGGER
.error(
- "Invalid property, property, expected > 0, received <[{}]>",
+ "Invalid property, property, expected > 0, received <[{}]>",
reconnectIntervalInt
);
throw new RelpProbeConfigurationError(
- "Invalid property, expected > 0, received <[" + reconnectInterval
+ "Invalid property, expected > 0, received <[" + reconnectInterval
+ "]>"
);
}
}
catch (NumberFormatException e) {
- LOGGER.error("Invalid property received, not a number: <{}>", e.getMessage());
+ LOGGER.error("Invalid property received, not a number: <{}>", e.getMessage());
throw new RelpProbeConfigurationError(
- "Invalid property received, not a number: <" + e.getMessage() + ">"
+ "Invalid property received, not a number: <" + e.getMessage() + ">"
);
}
}
@@ -182,6 +182,6 @@ public String getPrometheusEndpoint() {
}
public int getReconnectInterval() {
- return Integer.parseInt(config.get("relp.reconnectinterval"));
+ return Integer.parseInt(config.get("target.reconnectinterval"));
}
}
diff --git a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
index 42f0ee0..7242110 100644
--- a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
+++ b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
@@ -59,6 +59,8 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
@@ -76,6 +78,7 @@ public class ConnectionTest {
private EventLoop eventLoop;
private ExecutorService executorService;
private final List records = new ArrayList<>();
+ private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionTest.class);
@BeforeEach
public void StartServer() {
@@ -131,5 +134,7 @@ public void run() {
timer.schedule(task, 5000L);
relpProbe.start();
+
+ LOGGER.info("Got records: {}", records);
}
}
diff --git a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
index 5bafae4..6b015ae 100644
--- a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
+++ b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
@@ -167,31 +167,33 @@ public void testNonNumericTargetPort() {
@Test
public void testMissingReconnectInterval() {
Map map = getDefaultMap();
- map.remove("relp.reconnectinterval");
+ map.remove("target.reconnectinterval");
RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
+ Assertions.assertEquals("Missing property", e.getMessage());
}
@Test
public void testZeroReconnectInterval() {
Map map = getDefaultMap();
- map.put("relp.reconnectinterval", "0");
+ map.put("target.reconnectinterval", "0");
RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
Assertions
- .assertEquals("Invalid property, expected > 0, received <[0]>", e.getMessage());
+ .assertEquals(
+ "Invalid property, expected > 0, received <[0]>", e.getMessage()
+ );
}
@Test
public void testNonNumericReconnectInterval() {
Map map = getDefaultMap();
- map.put("relp.reconnectinterval", "not a number");
+ map.put("target.reconnectinterval", "not a number");
RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
Assertions
.assertEquals(
- "Invalid property received, not a number: ",
+ "Invalid property received, not a number: ",
e.getMessage()
);
}
@@ -213,6 +215,7 @@ private Map getDefaultMap() {
map.put("event.delay", "1000");
map.put("target.hostname", "127.0.0.1");
map.put("target.port", "12345");
+ map.put("target.reconnectinterval", "1000");
map.put("prometheus.endpoint", "127.0.0.1:8080");
return map;
}
diff --git a/src/test/resources/connectiontest.properties b/src/test/resources/connectiontest.properties
index a92dad6..ed8f4b2 100644
--- a/src/test/resources/connectiontest.properties
+++ b/src/test/resources/connectiontest.properties
@@ -9,9 +9,8 @@ event.delay=1000
target.hostname=127.0.0.1
# Relp Server target port
target.port=12345
-
-# RELP reconnect interval
-relp.reconnectinterval=1000
+# RELP Server reconnect interval
+target.reconnectinterval=1000
# Prometheus endpoint port
prometheus.endpoint=127.0.0.1:8080
From b8e027a2c54598f5a5b1bdeec18163379a462dcc Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Wed, 6 Nov 2024 15:15:08 +0200
Subject: [PATCH 03/14] Change slf4j simple to log4j2, some logging tweaks
---
pom.xml | 14 ++++++++---
.../java/com/teragrep/rlp_11/RelpProbe.java | 11 ++++++--
src/main/resources/log4j2.xml | 16 ++++++++++++
.../com/teragrep/rlp_11/ConnectionTest.java | 25 ++++++++++++++++---
.../rlp_11/InvalidConfigValidationTest.java | 2 +-
5 files changed, 58 insertions(+), 10 deletions(-)
create mode 100644 src/main/resources/log4j2.xml
diff --git a/pom.xml b/pom.xml
index 5019ef4..1109388 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,6 +15,7 @@
17
1.11.3
5.11.3
+ 2.24.1
17
17
UTF-8
@@ -85,9 +86,14 @@
${slf4j.version}
- org.slf4j
- slf4j-simple
- ${slf4j.version}
+ org.apache.logging.log4j
+ log4j-core
+ ${log4j2.version}
+
+
+ org.apache.logging.log4j
+ log4j-slf4j2-impl
+ ${log4j2.version}
@@ -483,6 +489,8 @@
src/main/assembly/jar-with-dependencies.xml
src/test/resources/*.properties
+
+ src/main/resources/log4j2.xml
README.adoc
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index 377333c..bebbe11 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -95,6 +95,7 @@ public void start() {
boolean allSent = false;
while (!allSent && stayRunning) {
try {
+ LOGGER.debug("Committing Relpbatch");
relpConnection.commit(relpBatch);
}
catch (IllegalStateException | IOException | java.util.concurrent.TimeoutException e) {
@@ -102,28 +103,30 @@ public void start() {
relpConnection.tearDown();
connected = false;
}
+ LOGGER.debug("Verifying Transaction");
allSent = relpBatch.verifyTransactionAll();
if (!allSent) {
+ LOGGER.warn("Transactions failed, retrying");
relpBatch.retryAllFailed();
reconnect();
}
}
try {
+ LOGGER.debug("Sleeping before sending next event");
Thread.sleep(eventDelay);
}
catch (InterruptedException e) {
LOGGER.warn("Sleep interrupted: <{}>", e.getMessage());
}
}
- LOGGER.info("Disconnecting..");
disconnect();
- LOGGER.info("Disconnected.");
latch.countDown();
}
private void connect() {
while (!connected && stayRunning) {
try {
+ LOGGER.info("Connecting to <[{}:{}]>", config.getTargetHostname(), config.getTargetPort());
connected = relpConnection.connect(config.getTargetHostname(), config.getTargetPort());
}
catch (TimeoutException | IOException e) {
@@ -135,6 +138,7 @@ private void connect() {
}
if (!connected) {
try {
+ LOGGER.info("Sleeping for <[{}]>ms before reconnecting", config.getReconnectInterval());
Thread.sleep(config.getReconnectInterval());
}
catch (InterruptedException e) {
@@ -151,9 +155,11 @@ private void reconnect() {
private void disconnect() {
if (!connected) {
+ LOGGER.debug("No need to disconnect, not connected");
return;
}
try {
+ LOGGER.info("Disconnecting..");
relpConnection.disconnect();
}
catch (IOException | TimeoutException e) {
@@ -164,6 +170,7 @@ private void disconnect() {
}
public void stop() {
+ LOGGER.debug("Stop called");
stayRunning = false;
try {
if (!latch.await(5L, TimeUnit.SECONDS)) {
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..959d7dc
--- /dev/null
+++ b/src/main/resources/log4j2.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
index 7242110..4dc0791 100644
--- a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
+++ b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
@@ -81,8 +81,10 @@ public class ConnectionTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionTest.class);
@BeforeEach
- public void StartServer() {
- executorService = Executors.newFixedThreadPool(1);
+ public void startServer() {
+ LOGGER.info("Creating SingleThreadExecutor");
+ executorService = Executors.newSingleThreadExecutor();
+ LOGGER.info("Creating consumer");
Consumer syslogConsumer = new Consumer<>() {
@Override
@@ -92,30 +94,45 @@ public synchronized void accept(FrameContext frameContext) {
}
}
};
+
+ LOGGER.info("Creating FrameDelegateSuplpier");
Supplier frameDelegateSupplier = () -> new DefaultFrameDelegate(syslogConsumer);
+ LOGGER.info("Creating EventLoopFactory");
EventLoopFactory eventLoopFactory = new EventLoopFactory();
+ LOGGER.info("Craeting eventLoopp");
eventLoop = Assertions.assertDoesNotThrow(eventLoopFactory::create);
+ LOGGER.info("Creating eventLoopThread");
eventLoopThread = new Thread(eventLoop);
+ LOGGER.info("Starting eventLoppThread");
eventLoopThread.start();
+
+ LOGGER.info("Creating ServerFactory");
ServerFactory serverFactory = new ServerFactory(
eventLoop,
executorService,
new PlainFactory(),
new FrameDelegationClockFactory(frameDelegateSupplier)
);
+
+ LOGGER.info("Creating Server");
Assertions.assertDoesNotThrow(() -> serverFactory.create(serverPort));
+ LOGGER.info("Leaving startServer");
}
@AfterEach
- public void StopServer() {
+ public void stopServer() {
+ LOGGER.info("Stopping server");
eventLoop.stop();
+ LOGGER.info("Joining server");
Assertions.assertDoesNotThrow(() -> eventLoopThread.join());
+ LOGGER.info("Shutting down executorService");
executorService.shutdown();
+ LOGGER.info("Clearing records");
records.clear();
}
@Test
- public void ConnectToServerTest() {
+ public void connectToServerTest() {
RelpProbeConfiguration relpProbeConfiguration = Assertions
.assertDoesNotThrow(
() -> new RelpProbeConfiguration(
diff --git a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
index 6b015ae..2d83a8f 100644
--- a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
+++ b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
@@ -55,7 +55,7 @@ public class InvalidConfigValidationTest {
// event.hostname tests
@Test
- public void TestMissingEventHostname() {
+ public void testMissingEventHostname() {
Map map = getDefaultMap();
map.remove("event.hostname");
RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
From 882ac75204ad06b1a30fdca4977b10a6f7d526a8 Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Wed, 6 Nov 2024 16:09:28 +0200
Subject: [PATCH 04/14] Fixes server
---
src/main/java/com/teragrep/rlp_11/Main.java | 5 +-
.../java/com/teragrep/rlp_11/RelpProbe.java | 2 +
.../com/teragrep/rlp_11/ConnectionTest.java | 60 +++++++------------
3 files changed, 28 insertions(+), 39 deletions(-)
diff --git a/src/main/java/com/teragrep/rlp_11/Main.java b/src/main/java/com/teragrep/rlp_11/Main.java
index f9bf13a..2b67ee0 100644
--- a/src/main/java/com/teragrep/rlp_11/Main.java
+++ b/src/main/java/com/teragrep/rlp_11/Main.java
@@ -60,13 +60,13 @@ public static void main(final String[] args) {
PathConfiguration pathConfiguration = new PathConfiguration(
System.getProperty("configurationPath", "etc/rlp_11.properties")
);
- Map map;
+ Map map = null;
try {
map = pathConfiguration.asMap();
}
catch (ConfigurationException e) {
LOGGER.error("Failed to create PathConfiguration: <{}>", e.getMessage(), e);
- return;
+ System.exit(1);
}
RelpProbeConfiguration relpProbeConfiguration = new RelpProbeConfiguration(map);
try {
@@ -74,6 +74,7 @@ public static void main(final String[] args) {
}
catch (RelpProbeConfigurationError e) {
LOGGER.error("Failed to validate config: <{}>", e.getMessage(), e);
+ System.exit(1);
}
RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index bebbe11..24389e9 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -128,6 +128,7 @@ private void connect() {
try {
LOGGER.info("Connecting to <[{}:{}]>", config.getTargetHostname(), config.getTargetPort());
connected = relpConnection.connect(config.getTargetHostname(), config.getTargetPort());
+ LOGGER.info("Connected.");
}
catch (TimeoutException | IOException e) {
LOGGER
@@ -166,6 +167,7 @@ private void disconnect() {
LOGGER.warn("Failed to disconnect: <{}>", e.getMessage());
}
relpConnection.tearDown();
+ LOGGER.info("Disconnected.");
connected = false;
}
diff --git a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
index 4dc0791..80fa4cd 100644
--- a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
+++ b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
@@ -49,11 +49,10 @@
import com.teragrep.net_01.channel.socket.PlainFactory;
import com.teragrep.net_01.eventloop.EventLoop;
import com.teragrep.net_01.eventloop.EventLoopFactory;
+import com.teragrep.net_01.server.Server;
import com.teragrep.net_01.server.ServerFactory;
import com.teragrep.rlp_03.frame.FrameDelegationClockFactory;
-import com.teragrep.rlp_03.frame.RelpFrame;
import com.teragrep.rlp_03.frame.delegate.DefaultFrameDelegate;
-import com.teragrep.rlp_03.frame.delegate.FrameContext;
import com.teragrep.rlp_03.frame.delegate.FrameDelegate;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
@@ -66,68 +65,55 @@
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.function.Consumer;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
public class ConnectionTest {
- private static final int serverPort = 12345;
+ private final int serverPort = 12345;
private Thread eventLoopThread;
private EventLoop eventLoop;
- private ExecutorService executorService;
+ private ThreadPoolExecutor threadPoolExecutor;
private final List records = new ArrayList<>();
private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionTest.class);
+ private Server server;
@BeforeEach
public void startServer() {
- LOGGER.info("Creating SingleThreadExecutor");
- executorService = Executors.newSingleThreadExecutor();
- LOGGER.info("Creating consumer");
- Consumer syslogConsumer = new Consumer<>() {
-
- @Override
- public synchronized void accept(FrameContext frameContext) {
- try (RelpFrame relpFrame = frameContext.relpFrame()) {
- records.add(relpFrame.payload().toString());
- }
- }
- };
-
- LOGGER.info("Creating FrameDelegateSuplpier");
- Supplier frameDelegateSupplier = () -> new DefaultFrameDelegate(syslogConsumer);
- LOGGER.info("Creating EventLoopFactory");
EventLoopFactory eventLoopFactory = new EventLoopFactory();
- LOGGER.info("Craeting eventLoopp");
eventLoop = Assertions.assertDoesNotThrow(eventLoopFactory::create);
- LOGGER.info("Creating eventLoopThread");
+
eventLoopThread = new Thread(eventLoop);
- LOGGER.info("Starting eventLoppThread");
eventLoopThread.start();
- LOGGER.info("Creating ServerFactory");
+ Supplier frameDelegateSupplier = () -> new DefaultFrameDelegate(
+ frameContext -> records.add(frameContext.relpFrame().payload().toString())
+ );
+
+ threadPoolExecutor = new ThreadPoolExecutor(
+ 1,
+ 1,
+ Long.MAX_VALUE,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>()
+ );
ServerFactory serverFactory = new ServerFactory(
eventLoop,
- executorService,
+ threadPoolExecutor,
new PlainFactory(),
new FrameDelegationClockFactory(frameDelegateSupplier)
);
-
- LOGGER.info("Creating Server");
- Assertions.assertDoesNotThrow(() -> serverFactory.create(serverPort));
- LOGGER.info("Leaving startServer");
+ server = Assertions.assertDoesNotThrow(() -> serverFactory.create(serverPort));
}
@AfterEach
public void stopServer() {
- LOGGER.info("Stopping server");
eventLoop.stop();
- LOGGER.info("Joining server");
+ threadPoolExecutor.shutdown();
Assertions.assertDoesNotThrow(() -> eventLoopThread.join());
- LOGGER.info("Shutting down executorService");
- executorService.shutdown();
- LOGGER.info("Clearing records");
+ Assertions.assertDoesNotThrow(server::close);
records.clear();
}
From f63986345c16abf9b6f8d2661d56d382d1921de8 Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Wed, 6 Nov 2024 16:29:03 +0200
Subject: [PATCH 05/14] Adds json formatting to events, fixes checkstyle stuff
---
pom.xml | 13 ++++++++
src/main/java/com/teragrep/rlp_11/Main.java | 8 ++---
.../java/com/teragrep/rlp_11/RelpProbe.java | 31 ++++++++++++++-----
.../rlp_11/RelpProbeConfiguration.java | 24 +++++++-------
.../rlp_11/RelpProbeConfigurationError.java | 2 +-
src/test/resources/connectiontest.properties | 10 +++---
6 files changed, 60 insertions(+), 28 deletions(-)
diff --git a/pom.xml b/pom.xml
index 1109388..4eea39c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,6 +12,8 @@
-SNAPSHOT
0.0.1-SNAPSHOT
4.2.28
+ 1.1.7
+ 2.1.3
17
1.11.3
5.11.3
@@ -95,6 +97,17 @@
log4j-slf4j2-impl
${log4j2.version}
+
+
+ jakarta.json
+ jakarta.json-api
+ ${jakarta.json.version}
+
+
+ org.eclipse.parsson
+ parsson
+ ${eclipse.parsson.version}
+
com.teragrep
diff --git a/src/main/java/com/teragrep/rlp_11/Main.java b/src/main/java/com/teragrep/rlp_11/Main.java
index 2b67ee0..a5a41de 100644
--- a/src/main/java/com/teragrep/rlp_11/Main.java
+++ b/src/main/java/com/teragrep/rlp_11/Main.java
@@ -57,7 +57,7 @@ public class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
public static void main(final String[] args) {
- PathConfiguration pathConfiguration = new PathConfiguration(
+ final PathConfiguration pathConfiguration = new PathConfiguration(
System.getProperty("configurationPath", "etc/rlp_11.properties")
);
Map map = null;
@@ -68,7 +68,7 @@ public static void main(final String[] args) {
LOGGER.error("Failed to create PathConfiguration: <{}>", e.getMessage(), e);
System.exit(1);
}
- RelpProbeConfiguration relpProbeConfiguration = new RelpProbeConfiguration(map);
+ final RelpProbeConfiguration relpProbeConfiguration = new RelpProbeConfiguration(map);
try {
relpProbeConfiguration.validate();
}
@@ -77,8 +77,8 @@ public static void main(final String[] args) {
System.exit(1);
}
- RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
- Thread shutdownHook = new Thread(() -> {
+ final RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
+ final Thread shutdownHook = new Thread(() -> {
LOGGER.info("Stopping RelpProbe..");
relpProbe.stop();
LOGGER.info("Shutting down.");
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index 24389e9..c1eaeca 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -54,40 +54,57 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.concurrent.CountDownLatch;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
public class RelpProbe {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbe.class);
private final RelpProbeConfiguration config;
private boolean stayRunning = true;
private RelpConnection relpConnection;
private final CountDownLatch latch = new CountDownLatch(1);
- private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbe.class);
private boolean connected = false;
- public RelpProbe(RelpProbeConfiguration config) {
+ public RelpProbe(final RelpProbeConfiguration config) {
this.config = config;
}
public void start() {
+ String origin;
+ try {
+ origin = InetAddress.getLocalHost().getHostName();
+ }
+ catch (UnknownHostException e) {
+ origin = "localhost";
+ LOGGER.warn("Could not get hostname, using <{}> instead", origin);
+ }
relpConnection = new RelpConnection();
connect();
- int eventDelay = config.getEventDelay();
+ final int eventDelay = config.getEventDelay();
while (stayRunning) {
- RelpBatch relpBatch = new RelpBatch();
- Instant timestamp = Instant.now();
- byte[] record = new SyslogMessage()
+ final RelpBatch relpBatch = new RelpBatch();
+ final Instant timestamp = Instant.now();
+ final JsonObject event = Json
+ .createObjectBuilder()
+ .add("origin", origin)
+ .add("timestamp", timestamp.getEpochSecond() + "." + timestamp.getNano())
+ .build();
+ final byte[] record = new SyslogMessage()
.withTimestamp(timestamp.toEpochMilli())
.withAppName(config.getEventAppname())
.withHostname(config.getEventHostname())
.withFacility(Facility.USER)
.withSeverity(Severity.INFORMATIONAL)
- .withMsg(timestamp.getEpochSecond() + "." + timestamp.getNano())
+ .withMsg(event.toString())
.toRfc5424SyslogMessage()
.getBytes(StandardCharsets.UTF_8);
relpBatch.insert(record);
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
index bbcf1fa..5f066b1 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
@@ -53,9 +53,10 @@
public class RelpProbeConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbeConfiguration.class);
+ private static final int MAXIMUM_PORT = 65535;
private final Map config;
- public RelpProbeConfiguration(Map config) {
+ public RelpProbeConfiguration(final Map config) {
this.config = config;
}
@@ -74,13 +75,13 @@ public void validate() throws RelpProbeConfigurationError {
throw new RelpProbeConfigurationError("Missing property");
}
- String eventDelay = config.get("event.delay");
+ final String eventDelay = config.get("event.delay");
if (eventDelay == null) {
LOGGER.error("Missing property");
throw new RelpProbeConfigurationError("Missing property");
}
try {
- int eventDelayInt = Integer.parseInt(eventDelay);
+ final int eventDelayInt = Integer.parseInt(eventDelay);
if (eventDelayInt <= 0) {
LOGGER.error("Invalid property, expected > 0, received <[{}]>", eventDelay);
throw new RelpProbeConfigurationError(
@@ -100,21 +101,22 @@ public void validate() throws RelpProbeConfigurationError {
throw new RelpProbeConfigurationError("Missing property");
}
- String targetPort = config.get("target.port");
+ final String targetPort = config.get("target.port");
if (targetPort == null) {
LOGGER.error("Missing property");
throw new RelpProbeConfigurationError("Missing property");
}
try {
- int targetPortInt = Integer.parseInt(targetPort);
- if (targetPortInt <= 0 || targetPortInt > 65535) {
+ final int targetPortInt = Integer.parseInt(targetPort);
+ if (targetPortInt <= 0 || targetPortInt > MAXIMUM_PORT) {
LOGGER
.error(
- "Invalid property, expected between 1 and 65535, received <[{}]>",
- targetPort
+ "Invalid property, expected between 1 and {}, received <[{}]>",
+ MAXIMUM_PORT, targetPort
);
throw new RelpProbeConfigurationError(
- "Invalid property, expected between 1 and 65535, received <[" + targetPort + "]>"
+ "Invalid property, expected between 1 and " + MAXIMUM_PORT + ", received <["
+ + targetPort + "]>"
);
}
}
@@ -130,13 +132,13 @@ public void validate() throws RelpProbeConfigurationError {
throw new RelpProbeConfigurationError("Missing property");
}
- String reconnectInterval = config.get("target.reconnectinterval");
+ final String reconnectInterval = config.get("target.reconnectinterval");
if (reconnectInterval == null) {
LOGGER.error("Missing property");
throw new RelpProbeConfigurationError("Missing property");
}
try {
- int reconnectIntervalInt = Integer.parseInt(reconnectInterval);
+ final int reconnectIntervalInt = Integer.parseInt(reconnectInterval);
if (reconnectIntervalInt <= 0) {
LOGGER
.error(
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java b/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java
index f0c966d..ffc8741 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java
@@ -47,7 +47,7 @@
public class RelpProbeConfigurationError extends RuntimeException {
- public RelpProbeConfigurationError(String s) {
+ public RelpProbeConfigurationError(final String s) {
super(s);
}
}
diff --git a/src/test/resources/connectiontest.properties b/src/test/resources/connectiontest.properties
index ed8f4b2..2e86a33 100644
--- a/src/test/resources/connectiontest.properties
+++ b/src/test/resources/connectiontest.properties
@@ -1,9 +1,12 @@
-# Hostname used in RELP event
-event.hostname=rlp_11
# Appname used in RELP event
event.appname=rlp_11
# Delay between sending events, in milliseconds
event.delay=1000
+# Hostname used in RELP event
+event.hostname=rlp_11
+
+# Prometheus endpoint port
+prometheus.endpoint=127.0.0.1:8080
# RELP Server target address
target.hostname=127.0.0.1
@@ -11,6 +14,3 @@ target.hostname=127.0.0.1
target.port=12345
# RELP Server reconnect interval
target.reconnectinterval=1000
-
-# Prometheus endpoint port
-prometheus.endpoint=127.0.0.1:8080
From 577e5072aebf7a6906ba52f91f5ad4ba8f66e180 Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Wed, 6 Nov 2024 17:47:50 +0200
Subject: [PATCH 06/14] Adds some sort of Metrics printing
---
pom.xml | 10 +-
.../java/com/teragrep/rlp_11/Metrics.java | 78 +++++++++++
.../java/com/teragrep/rlp_11/RelpProbe.java | 50 ++++++-
.../rlp_11/RelpProbeConfiguration.java | 126 ++++++++----------
.../com/teragrep/rlp_11/ConnectionTest.java | 15 +--
.../rlp_11/InvalidConfigValidationTest.java | 47 ++++++-
src/test/resources/connectiontest.properties | 2 +-
7 files changed, 238 insertions(+), 90 deletions(-)
create mode 100644 src/main/java/com/teragrep/rlp_11/Metrics.java
diff --git a/pom.xml b/pom.xml
index 4eea39c..1cce21f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,6 +12,7 @@
-SNAPSHOT
0.0.1-SNAPSHOT
4.2.28
+ 11.0.24
1.1.7
2.1.3
17
@@ -81,6 +82,12 @@
simpleclient_hotspot
${prometheus.version}
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ ${eclipse.jetty.version}
+
org.slf4j
@@ -186,7 +193,8 @@
-
+
+
diff --git a/src/main/java/com/teragrep/rlp_11/Metrics.java b/src/main/java/com/teragrep/rlp_11/Metrics.java
new file mode 100644
index 0000000..c922522
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Metrics.java
@@ -0,0 +1,78 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.SlidingWindowReservoir;
+import com.codahale.metrics.Timer;
+
+import static com.codahale.metrics.MetricRegistry.name;
+
+public class Metrics {
+
+ public final Counter records;
+ public final Counter resends;
+ public final Counter connects;
+ public final Counter disconnects;
+ public final Counter retriedConnects;
+ public final Timer sendLatency;
+ public final Timer connectLatency;
+ public final MetricRegistry metricRegistry;
+
+ public Metrics(final String name) {
+ this.metricRegistry = new MetricRegistry();
+ this.records = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "records"));
+ this.resends = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "resends"));
+ this.connects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "connects"));
+ this.disconnects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "disconnects"));
+ this.retriedConnects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "retriedConnects"));
+ this.sendLatency = metricRegistry
+ .timer(name(Metrics.class, "<[" + name + "]>", "sendLatency"), () -> new Timer(new SlidingWindowReservoir(10000)));
+ this.connectLatency = metricRegistry
+ .timer(name(Metrics.class, "<[" + name + "]>", "connectLatency"), () -> new Timer(new SlidingWindowReservoir(10000)));
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index c1eaeca..dd70373 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -45,11 +45,15 @@
*/
package com.teragrep.rlp_11;
+import com.codahale.metrics.Slf4jReporter;
+import com.codahale.metrics.Timer;
+import com.codahale.metrics.jmx.JmxReporter;
import com.teragrep.rlo_14.Facility;
import com.teragrep.rlo_14.Severity;
import com.teragrep.rlo_14.SyslogMessage;
import com.teragrep.rlp_01.RelpBatch;
import com.teragrep.rlp_01.RelpConnection;
+import org.eclipse.jetty.server.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -73,12 +77,41 @@ public class RelpProbe {
private RelpConnection relpConnection;
private final CountDownLatch latch = new CountDownLatch(1);
private boolean connected = false;
+ public final Metrics metrics;
+ private final JmxReporter jmxReporter;
+ private final Slf4jReporter slf4jReporter;
+ private final Server jettyServer;
public RelpProbe(final RelpProbeConfiguration config) {
+ this(config, new Metrics(config.getTargetHostname() + ":" + config.getTargetPort()));
+ }
+
+ public RelpProbe(final RelpProbeConfiguration config, final Metrics metrics) {
+ this(
+ config,
+ metrics,
+ JmxReporter.forRegistry(metrics.metricRegistry).build(),
+ Slf4jReporter.forRegistry(metrics.metricRegistry).outputTo(LoggerFactory.getLogger(RelpProbe.class)).convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build(), new Server(config.getPrometheusPort())
+ );
+ }
+
+ public RelpProbe(
+ final RelpProbeConfiguration config,
+ final Metrics metrics,
+ JmxReporter jmxReporter,
+ Slf4jReporter slf4jReporter,
+ Server jettyServer
+ ) {
this.config = config;
+ this.metrics = metrics;
+ this.jmxReporter = jmxReporter;
+ this.slf4jReporter = slf4jReporter;
+ this.jettyServer = jettyServer;
}
public void start() {
+ this.jmxReporter.start();
+ this.slf4jReporter.start(1, TimeUnit.MINUTES);
String origin;
try {
origin = InetAddress.getLocalHost().getHostName();
@@ -111,9 +144,10 @@ public void start() {
boolean allSent = false;
while (!allSent && stayRunning) {
- try {
+ try (final Timer.Context context = metrics.sendLatency.time()) {
LOGGER.debug("Committing Relpbatch");
relpConnection.commit(relpBatch);
+ metrics.records.inc();
}
catch (IllegalStateException | IOException | java.util.concurrent.TimeoutException e) {
LOGGER.warn("Failed to commit: <{}>", e.getMessage());
@@ -124,6 +158,7 @@ public void start() {
allSent = relpBatch.verifyTransactionAll();
if (!allSent) {
LOGGER.warn("Transactions failed, retrying");
+ metrics.resends.inc();
relpBatch.retryAllFailed();
reconnect();
}
@@ -138,14 +173,23 @@ public void start() {
}
disconnect();
latch.countDown();
+ slf4jReporter.close();
+ jmxReporter.close();
+ try {
+ jettyServer.stop();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
private void connect() {
while (!connected && stayRunning) {
- try {
+ try (final Timer.Context context = metrics.connectLatency.time()) {
LOGGER.info("Connecting to <[{}:{}]>", config.getTargetHostname(), config.getTargetPort());
connected = relpConnection.connect(config.getTargetHostname(), config.getTargetPort());
LOGGER.info("Connected.");
+ metrics.connects.inc();
}
catch (TimeoutException | IOException e) {
LOGGER
@@ -158,6 +202,7 @@ private void connect() {
try {
LOGGER.info("Sleeping for <[{}]>ms before reconnecting", config.getReconnectInterval());
Thread.sleep(config.getReconnectInterval());
+ metrics.retriedConnects.inc();
}
catch (InterruptedException e) {
LOGGER.warn("Sleep was interrupted: <{}>", e.getMessage());
@@ -179,6 +224,7 @@ private void disconnect() {
try {
LOGGER.info("Disconnecting..");
relpConnection.disconnect();
+ metrics.disconnects.inc();
}
catch (IOException | TimeoutException e) {
LOGGER.warn("Failed to disconnect: <{}>", e.getMessage());
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
index 5f066b1..122b11d 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
@@ -65,96 +65,76 @@ public void validate() throws RelpProbeConfigurationError {
LOGGER.debug("Validating the following configuration: {}", config);
}
- if (config.get("event.hostname") == null) {
- LOGGER.error("Missing property");
- throw new RelpProbeConfigurationError("Missing property");
- }
+ getAndVerifyStringProperty("event.hostname");
+ getAndVerifyStringProperty("event.appname");
- if (config.get("event.appname") == null) {
- LOGGER.error("Missing property");
- throw new RelpProbeConfigurationError("Missing property");
+ int eventDelay = getAndVerifyNumberProperty("event.delay");
+ if (eventDelay <= 0) {
+ LOGGER.error("Invalid property, expected > 0, received <[{}]>", eventDelay);
+ throw new RelpProbeConfigurationError(
+ "Invalid property, expected > 0, received <[" + eventDelay + "]>"
+ );
}
- final String eventDelay = config.get("event.delay");
- if (eventDelay == null) {
- LOGGER.error("Missing property");
- throw new RelpProbeConfigurationError("Missing property");
- }
- try {
- final int eventDelayInt = Integer.parseInt(eventDelay);
- if (eventDelayInt <= 0) {
- LOGGER.error("Invalid property, expected > 0, received <[{}]>", eventDelay);
- throw new RelpProbeConfigurationError(
- "Invalid property, expected > 0, received <[" + eventDelay + "]>"
- );
- }
- }
- catch (NumberFormatException e) {
- LOGGER.error("Invalid property received, not a number: <{}>", e.getMessage());
+ getAndVerifyStringProperty("target.hostname");
+
+ int targetPort = getAndVerifyNumberProperty("target.port");
+ if (targetPort <= 0 || targetPort > MAXIMUM_PORT) {
+ LOGGER
+ .error(
+ "Invalid property, expected between 1 and {}, received <[{}]>", MAXIMUM_PORT,
+ targetPort
+ );
throw new RelpProbeConfigurationError(
- "Invalid property received, not a number: <" + e.getMessage() + ">"
+ "Invalid property, expected between 1 and " + MAXIMUM_PORT + ", received <["
+ + targetPort + "]>"
);
}
- if (config.get("target.hostname") == null) {
- LOGGER.error("Missing property");
- throw new RelpProbeConfigurationError("Missing property");
+ int prometheusPort = getAndVerifyNumberProperty("prometheus.port");
+ if (prometheusPort <= 0 || prometheusPort > MAXIMUM_PORT) {
+ LOGGER
+ .error(
+ "Invalid property, expected between 1 and {}, received <[{}]>",
+ MAXIMUM_PORT, prometheusPort
+ );
+ throw new RelpProbeConfigurationError(
+ "Invalid property, expected between 1 and " + MAXIMUM_PORT + ", received <["
+ + prometheusPort + "]>"
+ );
}
- final String targetPort = config.get("target.port");
- if (targetPort == null) {
- LOGGER.error("Missing property");
- throw new RelpProbeConfigurationError("Missing property");
- }
- try {
- final int targetPortInt = Integer.parseInt(targetPort);
- if (targetPortInt <= 0 || targetPortInt > MAXIMUM_PORT) {
- LOGGER
- .error(
- "Invalid property, expected between 1 and {}, received <[{}]>",
- MAXIMUM_PORT, targetPort
- );
- throw new RelpProbeConfigurationError(
- "Invalid property, expected between 1 and " + MAXIMUM_PORT + ", received <["
- + targetPort + "]>"
- );
- }
- }
- catch (NumberFormatException e) {
- LOGGER.error("Invalid property received, not a number: <{}>", e.getMessage());
+ int reconnectInterval = getAndVerifyNumberProperty("target.reconnectinterval");
+ if (reconnectInterval <= 0) {
+ LOGGER
+ .error(
+ "Invalid property, property, expected > 0, received <[{}]>",
+ reconnectInterval
+ );
throw new RelpProbeConfigurationError(
- "Invalid property received, not a number: <" + e.getMessage() + ">"
+ "Invalid property, expected > 0, received <[" + reconnectInterval + "]>"
);
}
+ }
- if (config.get("prometheus.endpoint") == null) {
- LOGGER.error("Missing property");
- throw new RelpProbeConfigurationError("Missing property");
+ private String getAndVerifyStringProperty(String name) {
+ String property = config.get(name);
+ if (property == null) {
+ LOGGER.error("Missing <{}> property", name);
+ throw new RelpProbeConfigurationError("Missing <" + name + "> property");
}
+ return property;
+ }
- final String reconnectInterval = config.get("target.reconnectinterval");
- if (reconnectInterval == null) {
- LOGGER.error("Missing property");
- throw new RelpProbeConfigurationError("Missing property");
- }
+ private int getAndVerifyNumberProperty(String name) {
+ String property = getAndVerifyStringProperty(name);
try {
- final int reconnectIntervalInt = Integer.parseInt(reconnectInterval);
- if (reconnectIntervalInt <= 0) {
- LOGGER
- .error(
- "Invalid property, property, expected > 0, received <[{}]>",
- reconnectIntervalInt
- );
- throw new RelpProbeConfigurationError(
- "Invalid property, expected > 0, received <[" + reconnectInterval
- + "]>"
- );
- }
+ return Integer.parseInt(property);
}
catch (NumberFormatException e) {
- LOGGER.error("Invalid property received, not a number: <{}>", e.getMessage());
+ LOGGER.error("Invalid <{}> property received, not a number: <{}>", name, e.getMessage());
throw new RelpProbeConfigurationError(
- "Invalid property received, not a number: <" + e.getMessage() + ">"
+ "Invalid <" + name + "> property received, not a number: <" + e.getMessage() + ">"
);
}
}
@@ -179,8 +159,8 @@ public int getTargetPort() {
return Integer.parseInt(config.get("target.port"));
}
- public String getPrometheusEndpoint() {
- return config.get("prometheus.endpoint");
+ public int getPrometheusPort() {
+ return Integer.parseInt(config.get("prometheus.port"));
}
public int getReconnectInterval() {
diff --git a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
index 80fa4cd..28bf92c 100644
--- a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
+++ b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
@@ -58,8 +58,6 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
@@ -77,7 +75,6 @@ public class ConnectionTest {
private EventLoop eventLoop;
private ThreadPoolExecutor threadPoolExecutor;
private final List records = new ArrayList<>();
- private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionTest.class);
private Server server;
@BeforeEach
@@ -88,9 +85,11 @@ public void startServer() {
eventLoopThread = new Thread(eventLoop);
eventLoopThread.start();
- Supplier frameDelegateSupplier = () -> new DefaultFrameDelegate(
- frameContext -> records.add(frameContext.relpFrame().payload().toString())
- );
+ Supplier frameDelegateSupplier = () -> new DefaultFrameDelegate((frameContext) -> {
+ // Adds random latency before finishing and acking the event
+ Assertions.assertDoesNotThrow(() -> Thread.sleep((long) (Math.random() * 500)));
+ records.add(frameContext.relpFrame().payload().toString());
+ });
threadPoolExecutor = new ThreadPoolExecutor(
1,
@@ -134,10 +133,8 @@ public void run() {
}
};
Timer timer = new Timer("Timer");
- timer.schedule(task, 5000L);
+ timer.schedule(task, 10000L);
relpProbe.start();
-
- LOGGER.info("Got records: {}", records);
}
}
diff --git a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
index 2d83a8f..0c54c10 100644
--- a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
+++ b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
@@ -117,7 +117,7 @@ public void testMissingTargetHostname() {
// target.port tests
@Test
- public void testMissingPort() {
+ public void testMissingTargetPort() {
Map map = getDefaultMap();
map.remove("target.port");
RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
@@ -202,10 +202,49 @@ public void testNonNumericReconnectInterval() {
@Test
public void testMissingPrometheusEndpoint() {
Map map = getDefaultMap();
- map.remove("prometheus.endpoint");
+ map.remove("prometheus.port");
RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
+ Assertions.assertEquals("Missing property", e.getMessage());
+ }
+
+ @Test
+ public void testTooSmallPrometheusPort() {
+ Map map = getDefaultMap();
+ map.put("prometheus.port", "0");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals(
+ "Invalid property, expected between 1 and 65535, received <[0]>",
+ e.getMessage()
+ );
+ }
+
+ @Test
+ public void testTooHighPrometheusPort() {
+ Map map = getDefaultMap();
+ map.put("prometheus.port", "65536");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals(
+ "Invalid property, expected between 1 and 65535, received <[65536]>",
+ e.getMessage()
+ );
+ }
+
+ @Test
+ public void testNonNumericPrometheusPort() {
+ Map map = getDefaultMap();
+ map.put("prometheus.port", "not a number");
+ RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
+ Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
+ Assertions
+ .assertEquals(
+ "Invalid property received, not a number: ",
+ e.getMessage()
+ );
}
private Map getDefaultMap() {
@@ -216,7 +255,7 @@ private Map getDefaultMap() {
map.put("target.hostname", "127.0.0.1");
map.put("target.port", "12345");
map.put("target.reconnectinterval", "1000");
- map.put("prometheus.endpoint", "127.0.0.1:8080");
+ map.put("prometheus.port", "8080");
return map;
}
}
diff --git a/src/test/resources/connectiontest.properties b/src/test/resources/connectiontest.properties
index 2e86a33..01384c9 100644
--- a/src/test/resources/connectiontest.properties
+++ b/src/test/resources/connectiontest.properties
@@ -6,7 +6,7 @@ event.delay=1000
event.hostname=rlp_11
# Prometheus endpoint port
-prometheus.endpoint=127.0.0.1:8080
+prometheus.port=8080
# RELP Server target address
target.hostname=127.0.0.1
From a7cfab26a0767bdfc6684712d19d9bb641ca2faa Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Wed, 6 Nov 2024 17:58:57 +0200
Subject: [PATCH 07/14] Adds two extra error logging calls, a todo note
---
src/main/java/com/teragrep/rlp_11/Metrics.java | 1 +
src/main/java/com/teragrep/rlp_11/RelpProbe.java | 2 ++
2 files changed, 3 insertions(+)
diff --git a/src/main/java/com/teragrep/rlp_11/Metrics.java b/src/main/java/com/teragrep/rlp_11/Metrics.java
index c922522..8adaccd 100644
--- a/src/main/java/com/teragrep/rlp_11/Metrics.java
+++ b/src/main/java/com/teragrep/rlp_11/Metrics.java
@@ -70,6 +70,7 @@ public Metrics(final String name) {
this.connects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "connects"));
this.disconnects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "disconnects"));
this.retriedConnects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "retriedConnects"));
+ // TODO: Configurable window?
this.sendLatency = metricRegistry
.timer(name(Metrics.class, "<[" + name + "]>", "sendLatency"), () -> new Timer(new SlidingWindowReservoir(10000)));
this.connectLatency = metricRegistry
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index dd70373..6116d9e 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -239,10 +239,12 @@ public void stop() {
stayRunning = false;
try {
if (!latch.await(5L, TimeUnit.SECONDS)) {
+ LOGGER.error("Timed out while waiting for probe to shutdown.");
throw new RuntimeException("Timed out while waiting for probe to shutdown.");
}
}
catch (InterruptedException e) {
+ LOGGER.error("Interrupted while waiting for latch countdown");
throw new RuntimeException(e);
}
LOGGER.info("RelpProbe stopped.");
From 9b3ac390577bea310aaa647efaa9ab0c16d0a70d Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Thu, 7 Nov 2024 10:05:45 +0200
Subject: [PATCH 08/14] Re-enable IllegalCatch but add SuppressionCommentFilter
to allow disabling it momentarily
---
pom.xml | 5 +++--
src/main/java/com/teragrep/rlp_11/RelpProbe.java | 2 ++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 1cce21f..624dea0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -193,8 +193,7 @@
-
-
+
@@ -231,6 +230,8 @@
+
+
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index 6116d9e..76e6da0 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -178,9 +178,11 @@ public void start() {
try {
jettyServer.stop();
}
+ //CHECKSTYLE:OFF
catch (Exception e) {
throw new RuntimeException(e);
}
+ //CHECKSTYLE:ON
}
private void connect() {
From f3d1afb228641b1c3cf08a768485e0f90b10942c Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Thu, 7 Nov 2024 12:44:32 +0200
Subject: [PATCH 09/14] First batch of easy changes
---
src/main/java/com/teragrep/rlp_11/Main.java | 14 +++++------
.../java/com/teragrep/rlp_11/RelpProbe.java | 24 ++++++++++---------
.../com/teragrep/rlp_11/ConnectionTest.java | 2 +-
3 files changed, 21 insertions(+), 19 deletions(-)
diff --git a/src/main/java/com/teragrep/rlp_11/Main.java b/src/main/java/com/teragrep/rlp_11/Main.java
index a5a41de..06eb2e2 100644
--- a/src/main/java/com/teragrep/rlp_11/Main.java
+++ b/src/main/java/com/teragrep/rlp_11/Main.java
@@ -56,7 +56,7 @@ public class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
- public static void main(final String[] args) {
+ public static void main(final String[] args) throws ConfigurationException {
final PathConfiguration pathConfiguration = new PathConfiguration(
System.getProperty("configurationPath", "etc/rlp_11.properties")
);
@@ -65,23 +65,23 @@ public static void main(final String[] args) {
map = pathConfiguration.asMap();
}
catch (ConfigurationException e) {
- LOGGER.error("Failed to create PathConfiguration: <{}>", e.getMessage(), e);
- System.exit(1);
+ LOGGER.error("Failed to create PathConfiguration: <{}>", e.getMessage());
+ throw e;
}
final RelpProbeConfiguration relpProbeConfiguration = new RelpProbeConfiguration(map);
try {
relpProbeConfiguration.validate();
}
catch (RelpProbeConfigurationError e) {
- LOGGER.error("Failed to validate config: <{}>", e.getMessage(), e);
- System.exit(1);
+ LOGGER.error("Failed to validate config: <{}>", e.getMessage());
+ throw e;
}
final RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
final Thread shutdownHook = new Thread(() -> {
- LOGGER.info("Stopping RelpProbe..");
+ LOGGER.debug("Stopping RelpProbe..");
relpProbe.stop();
- LOGGER.info("Shutting down.");
+ LOGGER.debug("Shutting down.");
});
Runtime.getRuntime().addShutdownHook(shutdownHook);
LOGGER
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index 76e6da0..017156c 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -66,6 +66,8 @@
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import jakarta.json.Json;
import jakarta.json.JsonObject;
@@ -73,7 +75,7 @@ public class RelpProbe {
private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbe.class);
private final RelpProbeConfiguration config;
- private boolean stayRunning = true;
+ private AtomicBoolean stayRunning = new AtomicBoolean(true);
private RelpConnection relpConnection;
private final CountDownLatch latch = new CountDownLatch(1);
private boolean connected = false;
@@ -123,7 +125,7 @@ public void start() {
relpConnection = new RelpConnection();
connect();
final int eventDelay = config.getEventDelay();
- while (stayRunning) {
+ while (stayRunning.get()) {
final RelpBatch relpBatch = new RelpBatch();
final Instant timestamp = Instant.now();
final JsonObject event = Json
@@ -143,7 +145,7 @@ public void start() {
relpBatch.insert(record);
boolean allSent = false;
- while (!allSent && stayRunning) {
+ while (!allSent && stayRunning.get()) {
try (final Timer.Context context = metrics.sendLatency.time()) {
LOGGER.debug("Committing Relpbatch");
relpConnection.commit(relpBatch);
@@ -186,11 +188,11 @@ public void start() {
}
private void connect() {
- while (!connected && stayRunning) {
+ while (!connected && stayRunning.get()) {
try (final Timer.Context context = metrics.connectLatency.time()) {
- LOGGER.info("Connecting to <[{}:{}]>", config.getTargetHostname(), config.getTargetPort());
+ LOGGER.debug("Connecting to <[{}:{}]>", config.getTargetHostname(), config.getTargetPort());
connected = relpConnection.connect(config.getTargetHostname(), config.getTargetPort());
- LOGGER.info("Connected.");
+ LOGGER.debug("Connected.");
metrics.connects.inc();
}
catch (TimeoutException | IOException e) {
@@ -202,7 +204,7 @@ private void connect() {
}
if (!connected) {
try {
- LOGGER.info("Sleeping for <[{}]>ms before reconnecting", config.getReconnectInterval());
+ LOGGER.debug("Sleeping for <[{}]>ms before reconnecting", config.getReconnectInterval());
Thread.sleep(config.getReconnectInterval());
metrics.retriedConnects.inc();
}
@@ -224,7 +226,7 @@ private void disconnect() {
return;
}
try {
- LOGGER.info("Disconnecting..");
+ LOGGER.debug("Disconnecting..");
relpConnection.disconnect();
metrics.disconnects.inc();
}
@@ -232,13 +234,13 @@ private void disconnect() {
LOGGER.warn("Failed to disconnect: <{}>", e.getMessage());
}
relpConnection.tearDown();
- LOGGER.info("Disconnected.");
+ LOGGER.debug("Disconnected.");
connected = false;
}
public void stop() {
LOGGER.debug("Stop called");
- stayRunning = false;
+ stayRunning.set(false);
try {
if (!latch.await(5L, TimeUnit.SECONDS)) {
LOGGER.error("Timed out while waiting for probe to shutdown.");
@@ -249,6 +251,6 @@ public void stop() {
LOGGER.error("Interrupted while waiting for latch countdown");
throw new RuntimeException(e);
}
- LOGGER.info("RelpProbe stopped.");
+ LOGGER.debug("RelpProbe stopped.");
}
}
diff --git a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
index 28bf92c..db9974a 100644
--- a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
+++ b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
@@ -133,7 +133,7 @@ public void run() {
}
};
Timer timer = new Timer("Timer");
- timer.schedule(task, 10000L);
+ timer.schedule(task, 10_000);
relpProbe.start();
}
From 51162ead8cd28d9c5152d6d012a0675a056713b0 Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Thu, 7 Nov 2024 14:16:52 +0200
Subject: [PATCH 10/14] Refactor configuration management, split start to more
components
---
.../ConfigurationException.java} | 6 +-
.../EventConfiguration.java} | 65 +++--
.../EventConfigurationBuilder.java | 62 +++++
.../Configuration/MetricsConfiguration.java | 79 ++++++
.../MetricsConfigurationBuilder.java | 61 ++++
.../PrometheusConfiguration.java | 69 +++++
.../PrometheusConfigurationBuilder.java | 60 ++++
.../Configuration/TargetConfiguration.java | 90 ++++++
.../TargetConfigurationBuilder.java | 62 +++++
src/main/java/com/teragrep/rlp_11/Main.java | 44 +--
.../java/com/teragrep/rlp_11/RelpProbe.java | 170 +++++++-----
.../rlp_11/RelpProbeConfiguration.java | 169 ------------
.../com/teragrep/rlp_11/ConnectionTest.java | 29 +-
.../rlp_11/InvalidConfigValidationTest.java | 261 ------------------
src/test/resources/connectiontest.properties | 5 +
15 files changed, 675 insertions(+), 557 deletions(-)
rename src/main/java/com/teragrep/rlp_11/{RelpProbeConfigurationError.java => Configuration/ConfigurationException.java} (92%)
rename src/main/java/com/teragrep/rlp_11/{Metrics.java => Configuration/EventConfiguration.java} (55%)
create mode 100644 src/main/java/com/teragrep/rlp_11/Configuration/EventConfigurationBuilder.java
create mode 100644 src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java
create mode 100644 src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationBuilder.java
create mode 100644 src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java
create mode 100644 src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationBuilder.java
create mode 100644 src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java
create mode 100644 src/main/java/com/teragrep/rlp_11/Configuration/TargetConfigurationBuilder.java
delete mode 100644 src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
delete mode 100644 src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java b/src/main/java/com/teragrep/rlp_11/Configuration/ConfigurationException.java
similarity index 92%
rename from src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java
rename to src/main/java/com/teragrep/rlp_11/Configuration/ConfigurationException.java
index ffc8741..69daa51 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbeConfigurationError.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/ConfigurationException.java
@@ -43,11 +43,11 @@
* Teragrep, the applicable Commercial License may apply to this file if you as
* a licensee so wish it.
*/
-package com.teragrep.rlp_11;
+package com.teragrep.rlp_11.Configuration;
-public class RelpProbeConfigurationError extends RuntimeException {
+public class ConfigurationException extends RuntimeException {
- public RelpProbeConfigurationError(final String s) {
+ public ConfigurationException(final String s) {
super(s);
}
}
diff --git a/src/main/java/com/teragrep/rlp_11/Metrics.java b/src/main/java/com/teragrep/rlp_11/Configuration/EventConfiguration.java
similarity index 55%
rename from src/main/java/com/teragrep/rlp_11/Metrics.java
rename to src/main/java/com/teragrep/rlp_11/Configuration/EventConfiguration.java
index 8adaccd..c2cc30d 100644
--- a/src/main/java/com/teragrep/rlp_11/Metrics.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/EventConfiguration.java
@@ -43,37 +43,48 @@
* Teragrep, the applicable Commercial License may apply to this file if you as
* a licensee so wish it.
*/
-package com.teragrep.rlp_11;
+package com.teragrep.rlp_11.Configuration;
-import com.codahale.metrics.Counter;
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.SlidingWindowReservoir;
-import com.codahale.metrics.Timer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import static com.codahale.metrics.MetricRegistry.name;
+public class EventConfiguration {
-public class Metrics {
+ private static final Logger LOGGER = LoggerFactory.getLogger(EventConfiguration.class);
+ private final String appname;
+ private final String hostname;
+ private final int delay;
- public final Counter records;
- public final Counter resends;
- public final Counter connects;
- public final Counter disconnects;
- public final Counter retriedConnects;
- public final Timer sendLatency;
- public final Timer connectLatency;
- public final MetricRegistry metricRegistry;
+ public EventConfiguration(final String appname, final String hostname, final int delay) {
+ this.appname = appname;
+ this.hostname = hostname;
+ this.delay = delay;
+ }
+
+ public String appname() {
+ if (appname == null) {
+ final String errorMessage = "Appname is null";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return appname;
+ }
+
+ public String hostname() {
+ if (appname == null) {
+ final String errorMessage = "Hostname is null";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return hostname;
+ }
- public Metrics(final String name) {
- this.metricRegistry = new MetricRegistry();
- this.records = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "records"));
- this.resends = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "resends"));
- this.connects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "connects"));
- this.disconnects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "disconnects"));
- this.retriedConnects = metricRegistry.counter(name(Metrics.class, "<[" + name + "]>", "retriedConnects"));
- // TODO: Configurable window?
- this.sendLatency = metricRegistry
- .timer(name(Metrics.class, "<[" + name + "]>", "sendLatency"), () -> new Timer(new SlidingWindowReservoir(10000)));
- this.connectLatency = metricRegistry
- .timer(name(Metrics.class, "<[" + name + "]>", "connectLatency"), () -> new Timer(new SlidingWindowReservoir(10000)));
+ public int delay() {
+ if (delay <= 0) {
+ final String errorMessage = "Delay too small, expected to be >0";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return delay;
}
}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/EventConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/EventConfigurationBuilder.java
new file mode 100644
index 0000000..41086f6
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/EventConfigurationBuilder.java
@@ -0,0 +1,62 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import java.util.Map;
+
+public final class EventConfigurationBuilder {
+
+ private EventConfigurationBuilder() {
+
+ }
+
+ public static EventConfiguration build(final Map config) {
+ final String appname = config.get("event.appname");
+ final String hostname = config.get("event.hostname");
+ final int delay = Integer.parseInt(config.get("event.delay"));
+ return new EventConfiguration(appname, hostname, delay);
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java
new file mode 100644
index 0000000..b8b808c
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java
@@ -0,0 +1,79 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MetricsConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MetricsConfiguration.class);
+ private final String name;
+ private final int window;
+
+ public MetricsConfiguration(final String name, final int window) {
+ this.name = name;
+ this.window = window;
+ }
+
+ public String name() {
+ if (name == null) {
+ final String errorMessage = "Name is null";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return name;
+ }
+
+ public int window() {
+ if (window <= 0) {
+ final String errorMessage = "Window too small, expected to be >0";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return window;
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationBuilder.java
new file mode 100644
index 0000000..2b55572
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationBuilder.java
@@ -0,0 +1,61 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import java.util.Map;
+
+public final class MetricsConfigurationBuilder {
+
+ private MetricsConfigurationBuilder() {
+
+ }
+
+ public static MetricsConfiguration build(final Map config) {
+ final String name = config.get("metrics.name");
+ final int window = Integer.parseInt(config.get("metrics.window"));
+ return new MetricsConfiguration(name, window);
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java
new file mode 100644
index 0000000..19c1450
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java
@@ -0,0 +1,69 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PrometheusConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MetricsConfiguration.class);
+
+ private final int port;
+
+ public PrometheusConfiguration(final int port) {
+ this.port = port;
+ }
+
+ public int port() {
+ if (port < 1 || port > 65535) {
+ final String errorMessage = "Port is in invalid range, expected between 1 and 65535";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return port;
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationBuilder.java
new file mode 100644
index 0000000..ad047ef
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationBuilder.java
@@ -0,0 +1,60 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import java.util.Map;
+
+public final class PrometheusConfigurationBuilder {
+
+ private PrometheusConfigurationBuilder() {
+
+ }
+
+ public static PrometheusConfiguration build(final Map config) {
+ final int port = Integer.parseInt(config.get("prometheus.port"));
+ return new PrometheusConfiguration(port);
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java
new file mode 100644
index 0000000..c38e0d6
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java
@@ -0,0 +1,90 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TargetConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TargetConfiguration.class);
+ private final String hostname;
+ private final int port;
+ private final int reconnectInterval;
+
+ public TargetConfiguration(final String hostname, final int port, final int reconnectInterval) {
+ this.hostname = hostname;
+ this.port = port;
+ this.reconnectInterval = reconnectInterval;
+ }
+
+ public String hostname() {
+ if (hostname == null) {
+ final String errorMessage = "Hostname is null";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return hostname;
+ }
+
+ public int port() {
+ if (port < 1 || port > 65535) {
+ final String errorMessage = "Port is in invalid range, expected between 1 and 65535";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return port;
+ }
+
+ public int reconnectInterval() {
+ if (reconnectInterval <= 0) {
+ final String errorMessage = "Reconnect interval too small, expected to be >0";
+ LOGGER.error(errorMessage);
+ throw new ConfigurationException(errorMessage);
+ }
+ return reconnectInterval;
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfigurationBuilder.java
new file mode 100644
index 0000000..f433926
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfigurationBuilder.java
@@ -0,0 +1,62 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import java.util.Map;
+
+public final class TargetConfigurationBuilder {
+
+ private TargetConfigurationBuilder() {
+
+ }
+
+ public static TargetConfiguration build(final Map config) {
+ final String hostname = config.get("target.hostname");
+ final int port = Integer.parseInt(config.get("target.port"));
+ final int reconnectInterval = Integer.parseInt(config.get("target.reconnectinterval"));
+ return new TargetConfiguration(hostname, port, reconnectInterval);
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/Main.java b/src/main/java/com/teragrep/rlp_11/Main.java
index 06eb2e2..7c63436 100644
--- a/src/main/java/com/teragrep/rlp_11/Main.java
+++ b/src/main/java/com/teragrep/rlp_11/Main.java
@@ -45,8 +45,15 @@
*/
package com.teragrep.rlp_11;
-import com.teragrep.cnf_01.ConfigurationException;
import com.teragrep.cnf_01.PathConfiguration;
+import com.teragrep.rlp_11.Configuration.EventConfiguration;
+import com.teragrep.rlp_11.Configuration.EventConfigurationBuilder;
+import com.teragrep.rlp_11.Configuration.MetricsConfiguration;
+import com.teragrep.rlp_11.Configuration.MetricsConfigurationBuilder;
+import com.teragrep.rlp_11.Configuration.PrometheusConfiguration;
+import com.teragrep.rlp_11.Configuration.PrometheusConfigurationBuilder;
+import com.teragrep.rlp_11.Configuration.TargetConfiguration;
+import com.teragrep.rlp_11.Configuration.TargetConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,43 +63,40 @@ public class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
- public static void main(final String[] args) throws ConfigurationException {
+ public static void main(final String[] args) throws com.teragrep.cnf_01.ConfigurationException {
final PathConfiguration pathConfiguration = new PathConfiguration(
System.getProperty("configurationPath", "etc/rlp_11.properties")
);
- Map map = null;
+ final Map map;
try {
map = pathConfiguration.asMap();
}
- catch (ConfigurationException e) {
+ catch (com.teragrep.cnf_01.ConfigurationException e) {
LOGGER.error("Failed to create PathConfiguration: <{}>", e.getMessage());
throw e;
}
- final RelpProbeConfiguration relpProbeConfiguration = new RelpProbeConfiguration(map);
- try {
- relpProbeConfiguration.validate();
- }
- catch (RelpProbeConfigurationError e) {
- LOGGER.error("Failed to validate config: <{}>", e.getMessage());
- throw e;
- }
+ final PrometheusConfiguration prometheusConfiguration = PrometheusConfigurationBuilder.build(map);
+ final EventConfiguration eventConfiguration = EventConfigurationBuilder.build(map);
+ final TargetConfiguration targetConfiguration = TargetConfigurationBuilder.build(map);
+ final MetricsConfiguration metricsConfiguration = MetricsConfigurationBuilder.build(map);
- final RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
+ final RelpProbe relpProbe = new RelpProbe(
+ targetConfiguration,
+ eventConfiguration,
+ prometheusConfiguration,
+ metricsConfiguration
+ );
final Thread shutdownHook = new Thread(() -> {
LOGGER.debug("Stopping RelpProbe..");
relpProbe.stop();
LOGGER.debug("Shutting down.");
});
Runtime.getRuntime().addShutdownHook(shutdownHook);
+ LOGGER.info("Sending events to <[{}:{}]>", targetConfiguration.hostname(), targetConfiguration.port());
LOGGER
.info(
- "Sending events to <[{}:{}]>", relpProbeConfiguration.getTargetHostname(),
- relpProbeConfiguration.getTargetPort()
- );
- LOGGER
- .info(
- "Using hostname <[{}]> and appname <[{}]> for the events.",
- relpProbeConfiguration.getEventHostname(), relpProbeConfiguration.getEventAppname()
+ "Using hostname <[{}]> and appname <[{}]> for the events.", eventConfiguration.hostname(),
+ eventConfiguration.appname()
);
relpProbe.start();
}
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbe.java b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
index 017156c..3df53b3 100644
--- a/src/main/java/com/teragrep/rlp_11/RelpProbe.java
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -45,7 +45,10 @@
*/
package com.teragrep.rlp_11;
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Slf4jReporter;
+import com.codahale.metrics.SlidingWindowReservoir;
import com.codahale.metrics.Timer;
import com.codahale.metrics.jmx.JmxReporter;
import com.teragrep.rlo_14.Facility;
@@ -53,6 +56,10 @@
import com.teragrep.rlo_14.SyslogMessage;
import com.teragrep.rlp_01.RelpBatch;
import com.teragrep.rlp_01.RelpConnection;
+import com.teragrep.rlp_11.Configuration.EventConfiguration;
+import com.teragrep.rlp_11.Configuration.MetricsConfiguration;
+import com.teragrep.rlp_11.Configuration.PrometheusConfiguration;
+import com.teragrep.rlp_11.Configuration.TargetConfiguration;
import org.eclipse.jetty.server.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,47 +78,44 @@
import jakarta.json.Json;
import jakarta.json.JsonObject;
+import static com.codahale.metrics.MetricRegistry.name;
+
public class RelpProbe {
private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbe.class);
- private final RelpProbeConfiguration config;
- private AtomicBoolean stayRunning = new AtomicBoolean(true);
+ private final TargetConfiguration targetConfiguration;
+ private final EventConfiguration eventConfiguration;
+ private final PrometheusConfiguration prometheusConfiguration;
+ private final MetricsConfiguration metricsConfiguration;
+ private final AtomicBoolean stayRunning = new AtomicBoolean(true);
private RelpConnection relpConnection;
private final CountDownLatch latch = new CountDownLatch(1);
private boolean connected = false;
- public final Metrics metrics;
- private final JmxReporter jmxReporter;
- private final Slf4jReporter slf4jReporter;
- private final Server jettyServer;
-
- public RelpProbe(final RelpProbeConfiguration config) {
- this(config, new Metrics(config.getTargetHostname() + ":" + config.getTargetPort()));
- }
-
- public RelpProbe(final RelpProbeConfiguration config, final Metrics metrics) {
- this(
- config,
- metrics,
- JmxReporter.forRegistry(metrics.metricRegistry).build(),
- Slf4jReporter.forRegistry(metrics.metricRegistry).outputTo(LoggerFactory.getLogger(RelpProbe.class)).convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build(), new Server(config.getPrometheusPort())
- );
- }
+ private Counter records;
+ private Counter resends;
+ private Counter connects;
+ private Counter disconnects;
+ private Counter retriedConnects;
+ private Timer sendLatency;
+ private Timer connectLatency;
+ private JmxReporter jmxReporter;
+ private Slf4jReporter slf4jReporter;
+ private Server jettyServer;
public RelpProbe(
- final RelpProbeConfiguration config,
- final Metrics metrics,
- JmxReporter jmxReporter,
- Slf4jReporter slf4jReporter,
- Server jettyServer
+ final TargetConfiguration targetConfiguration,
+ final EventConfiguration eventConfiguration,
+ final PrometheusConfiguration prometheusConfiguration,
+ final MetricsConfiguration metricsConfiguration
) {
- this.config = config;
- this.metrics = metrics;
- this.jmxReporter = jmxReporter;
- this.slf4jReporter = slf4jReporter;
- this.jettyServer = jettyServer;
+ this.targetConfiguration = targetConfiguration;
+ this.eventConfiguration = eventConfiguration;
+ this.prometheusConfiguration = prometheusConfiguration;
+ this.metricsConfiguration = metricsConfiguration;
}
public void start() {
+ createMetrics(metricsConfiguration.name());
this.jmxReporter.start();
this.slf4jReporter.start(1, TimeUnit.MINUTES);
String origin;
@@ -124,32 +128,16 @@ public void start() {
}
relpConnection = new RelpConnection();
connect();
- final int eventDelay = config.getEventDelay();
while (stayRunning.get()) {
final RelpBatch relpBatch = new RelpBatch();
- final Instant timestamp = Instant.now();
- final JsonObject event = Json
- .createObjectBuilder()
- .add("origin", origin)
- .add("timestamp", timestamp.getEpochSecond() + "." + timestamp.getNano())
- .build();
- final byte[] record = new SyslogMessage()
- .withTimestamp(timestamp.toEpochMilli())
- .withAppName(config.getEventAppname())
- .withHostname(config.getEventHostname())
- .withFacility(Facility.USER)
- .withSeverity(Severity.INFORMATIONAL)
- .withMsg(event.toString())
- .toRfc5424SyslogMessage()
- .getBytes(StandardCharsets.UTF_8);
- relpBatch.insert(record);
+ relpBatch.insert(createPayload(origin));
boolean allSent = false;
while (!allSent && stayRunning.get()) {
- try (final Timer.Context context = metrics.sendLatency.time()) {
+ try (final Timer.Context context = sendLatency.time()) {
LOGGER.debug("Committing Relpbatch");
relpConnection.commit(relpBatch);
- metrics.records.inc();
+ records.inc();
}
catch (IllegalStateException | IOException | java.util.concurrent.TimeoutException e) {
LOGGER.warn("Failed to commit: <{}>", e.getMessage());
@@ -160,14 +148,14 @@ public void start() {
allSent = relpBatch.verifyTransactionAll();
if (!allSent) {
LOGGER.warn("Transactions failed, retrying");
- metrics.resends.inc();
+ resends.inc();
relpBatch.retryAllFailed();
reconnect();
}
}
try {
LOGGER.debug("Sleeping before sending next event");
- Thread.sleep(eventDelay);
+ Thread.sleep(eventConfiguration.delay());
}
catch (InterruptedException e) {
LOGGER.warn("Sleep interrupted: <{}>", e.getMessage());
@@ -175,38 +163,29 @@ public void start() {
}
disconnect();
latch.countDown();
- slf4jReporter.close();
- jmxReporter.close();
- try {
- jettyServer.stop();
- }
- //CHECKSTYLE:OFF
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- //CHECKSTYLE:ON
+ teardownMetrics();
}
private void connect() {
while (!connected && stayRunning.get()) {
- try (final Timer.Context context = metrics.connectLatency.time()) {
- LOGGER.debug("Connecting to <[{}:{}]>", config.getTargetHostname(), config.getTargetPort());
- connected = relpConnection.connect(config.getTargetHostname(), config.getTargetPort());
+ try (final Timer.Context context = connectLatency.time()) {
+ LOGGER.debug("Connecting to <[{}:{}]>", targetConfiguration.hostname(), targetConfiguration.port());
+ connected = relpConnection.connect(targetConfiguration.hostname(), targetConfiguration.port());
LOGGER.debug("Connected.");
- metrics.connects.inc();
+ connects.inc();
}
catch (TimeoutException | IOException e) {
LOGGER
.warn(
- "Failed to connect to <[{}:{}]>: <{}>", config.getTargetHostname(),
- config.getTargetPort(), e.getMessage()
+ "Failed to connect to <[{}:{}]>: <{}>", targetConfiguration.hostname(),
+ targetConfiguration.port(), e.getMessage()
);
}
if (!connected) {
try {
- LOGGER.debug("Sleeping for <[{}]>ms before reconnecting", config.getReconnectInterval());
- Thread.sleep(config.getReconnectInterval());
- metrics.retriedConnects.inc();
+ LOGGER.debug("Sleeping for <[{}]>ms before reconnecting", targetConfiguration.reconnectInterval());
+ Thread.sleep(targetConfiguration.reconnectInterval());
+ retriedConnects.inc();
}
catch (InterruptedException e) {
LOGGER.warn("Sleep was interrupted: <{}>", e.getMessage());
@@ -228,7 +207,7 @@ private void disconnect() {
try {
LOGGER.debug("Disconnecting..");
relpConnection.disconnect();
- metrics.disconnects.inc();
+ disconnects.inc();
}
catch (IOException | TimeoutException e) {
LOGGER.warn("Failed to disconnect: <{}>", e.getMessage());
@@ -253,4 +232,55 @@ public void stop() {
}
LOGGER.debug("RelpProbe stopped.");
}
+
+ private byte[] createPayload(final String origin) {
+ final Instant timestamp = Instant.now();
+ final JsonObject event = Json
+ .createObjectBuilder()
+ .add("origin", origin)
+ .add("timestamp", timestamp.getEpochSecond() + "." + timestamp.getNano())
+ .build();
+ return new SyslogMessage()
+ .withTimestamp(timestamp.toEpochMilli())
+ .withAppName(eventConfiguration.appname())
+ .withHostname(eventConfiguration.hostname())
+ .withFacility(Facility.USER)
+ .withSeverity(Severity.INFORMATIONAL)
+ .withMsg(event.toString())
+ .toRfc5424SyslogMessage()
+ .getBytes(StandardCharsets.UTF_8);
+ }
+
+ private void createMetrics(final String name) {
+ final MetricRegistry metricRegistry = new MetricRegistry();
+ this.records = metricRegistry.counter(name(RelpProbe.class, "<[" + name + "]>", "records"));
+ this.resends = metricRegistry.counter(name(RelpProbe.class, "<[" + name + "]>", "resends"));
+ this.connects = metricRegistry.counter(name(RelpProbe.class, "<[" + name + "]>", "connects"));
+ this.disconnects = metricRegistry.counter(name(RelpProbe.class, "<[" + name + "]>", "disconnects"));
+ this.retriedConnects = metricRegistry.counter(name(RelpProbe.class, "<[" + name + "]>", "retriedConnects"));
+ // TODO: Configurable window?
+ this.sendLatency = metricRegistry
+ .timer(name(RelpProbe.class, "<[" + name + "]>", "sendLatency"), () -> new Timer(new SlidingWindowReservoir(metricsConfiguration.window())));
+ this.connectLatency = metricRegistry
+ .timer(name(RelpProbe.class, "<[" + name + "]>", "connectLatency"), () -> new Timer(new SlidingWindowReservoir(metricsConfiguration.window())));
+ jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
+ slf4jReporter = Slf4jReporter
+ .forRegistry(metricRegistry)
+ .outputTo(LoggerFactory.getLogger(RelpProbe.class))
+ .build();
+ jettyServer = new Server(prometheusConfiguration.port());
+ }
+
+ private void teardownMetrics() {
+ slf4jReporter.close();
+ jmxReporter.close();
+ try {
+ jettyServer.stop();
+ }
+ //CHECKSTYLE:OFF
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ //CHECKSTYLE:ON
+ }
}
diff --git a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java b/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
deleted file mode 100644
index 122b11d..0000000
--- a/src/main/java/com/teragrep/rlp_11/RelpProbeConfiguration.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * RELP Commit Latency Probe RLP-11
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.rlp_11;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Map;
-
-public class RelpProbeConfiguration {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbeConfiguration.class);
- private static final int MAXIMUM_PORT = 65535;
- private final Map config;
-
- public RelpProbeConfiguration(final Map config) {
- this.config = config;
- }
-
- public void validate() throws RelpProbeConfigurationError {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Validating the following configuration: {}", config);
- }
-
- getAndVerifyStringProperty("event.hostname");
- getAndVerifyStringProperty("event.appname");
-
- int eventDelay = getAndVerifyNumberProperty("event.delay");
- if (eventDelay <= 0) {
- LOGGER.error("Invalid property, expected > 0, received <[{}]>", eventDelay);
- throw new RelpProbeConfigurationError(
- "Invalid property, expected > 0, received <[" + eventDelay + "]>"
- );
- }
-
- getAndVerifyStringProperty("target.hostname");
-
- int targetPort = getAndVerifyNumberProperty("target.port");
- if (targetPort <= 0 || targetPort > MAXIMUM_PORT) {
- LOGGER
- .error(
- "Invalid property, expected between 1 and {}, received <[{}]>", MAXIMUM_PORT,
- targetPort
- );
- throw new RelpProbeConfigurationError(
- "Invalid property, expected between 1 and " + MAXIMUM_PORT + ", received <["
- + targetPort + "]>"
- );
- }
-
- int prometheusPort = getAndVerifyNumberProperty("prometheus.port");
- if (prometheusPort <= 0 || prometheusPort > MAXIMUM_PORT) {
- LOGGER
- .error(
- "Invalid property, expected between 1 and {}, received <[{}]>",
- MAXIMUM_PORT, prometheusPort
- );
- throw new RelpProbeConfigurationError(
- "Invalid property, expected between 1 and " + MAXIMUM_PORT + ", received <["
- + prometheusPort + "]>"
- );
- }
-
- int reconnectInterval = getAndVerifyNumberProperty("target.reconnectinterval");
- if (reconnectInterval <= 0) {
- LOGGER
- .error(
- "Invalid property, property, expected > 0, received <[{}]>",
- reconnectInterval
- );
- throw new RelpProbeConfigurationError(
- "Invalid property, expected > 0, received <[" + reconnectInterval + "]>"
- );
- }
- }
-
- private String getAndVerifyStringProperty(String name) {
- String property = config.get(name);
- if (property == null) {
- LOGGER.error("Missing <{}> property", name);
- throw new RelpProbeConfigurationError("Missing <" + name + "> property");
- }
- return property;
- }
-
- private int getAndVerifyNumberProperty(String name) {
- String property = getAndVerifyStringProperty(name);
- try {
- return Integer.parseInt(property);
- }
- catch (NumberFormatException e) {
- LOGGER.error("Invalid <{}> property received, not a number: <{}>", name, e.getMessage());
- throw new RelpProbeConfigurationError(
- "Invalid <" + name + "> property received, not a number: <" + e.getMessage() + ">"
- );
- }
- }
-
- public String getEventHostname() {
- return config.get("event.hostname");
- }
-
- public String getEventAppname() {
- return config.get("event.appname");
- }
-
- public int getEventDelay() {
- return Integer.parseInt(config.get("event.delay"));
- }
-
- public String getTargetHostname() {
- return config.get("target.hostname");
- }
-
- public int getTargetPort() {
- return Integer.parseInt(config.get("target.port"));
- }
-
- public int getPrometheusPort() {
- return Integer.parseInt(config.get("prometheus.port"));
- }
-
- public int getReconnectInterval() {
- return Integer.parseInt(config.get("target.reconnectinterval"));
- }
-}
diff --git a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
index db9974a..b8e4c23 100644
--- a/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
+++ b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
@@ -54,6 +54,14 @@
import com.teragrep.rlp_03.frame.FrameDelegationClockFactory;
import com.teragrep.rlp_03.frame.delegate.DefaultFrameDelegate;
import com.teragrep.rlp_03.frame.delegate.FrameDelegate;
+import com.teragrep.rlp_11.Configuration.EventConfiguration;
+import com.teragrep.rlp_11.Configuration.EventConfigurationBuilder;
+import com.teragrep.rlp_11.Configuration.MetricsConfiguration;
+import com.teragrep.rlp_11.Configuration.MetricsConfigurationBuilder;
+import com.teragrep.rlp_11.Configuration.PrometheusConfiguration;
+import com.teragrep.rlp_11.Configuration.PrometheusConfigurationBuilder;
+import com.teragrep.rlp_11.Configuration.TargetConfiguration;
+import com.teragrep.rlp_11.Configuration.TargetConfigurationBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -61,6 +69,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.LinkedBlockingQueue;
@@ -118,13 +127,19 @@ public void stopServer() {
@Test
public void connectToServerTest() {
- RelpProbeConfiguration relpProbeConfiguration = Assertions
- .assertDoesNotThrow(
- () -> new RelpProbeConfiguration(
- new PathConfiguration("src/test/resources/connectiontest.properties").asMap()
- )
- );
- RelpProbe relpProbe = new RelpProbe(relpProbeConfiguration);
+ Map map = Assertions
+ .assertDoesNotThrow(() -> new PathConfiguration("src/test/resources/connectiontest.properties").asMap());
+ final PrometheusConfiguration prometheusConfiguration = PrometheusConfigurationBuilder.build(map);
+ final EventConfiguration eventConfiguration = EventConfigurationBuilder.build(map);
+ final TargetConfiguration targetConfiguration = TargetConfigurationBuilder.build(map);
+ final MetricsConfiguration metricsConfiguration = MetricsConfigurationBuilder.build(map);
+
+ RelpProbe relpProbe = new RelpProbe(
+ targetConfiguration,
+ eventConfiguration,
+ prometheusConfiguration,
+ metricsConfiguration
+ );
TimerTask task = new TimerTask() {
diff --git a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java b/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
deleted file mode 100644
index 0c54c10..0000000
--- a/src/test/java/com/teragrep/rlp_11/InvalidConfigValidationTest.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * RELP Commit Latency Probe RLP-11
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.rlp_11;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class InvalidConfigValidationTest {
-
- // event.hostname tests
- @Test
- public void testMissingEventHostname() {
- Map map = getDefaultMap();
- map.remove("event.hostname");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
- }
-
- // event.appname tests
- @Test
- public void testMissingAppname() {
- Map map = getDefaultMap();
- map.remove("event.appname");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
- }
-
- // event.delay tests
- @Test
- public void testMissingEventDelay() {
- Map map = getDefaultMap();
- map.remove("event.delay");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
- }
-
- @Test
- public void testZeroEventDelay() {
- Map map = getDefaultMap();
- map.put("event.delay", "0");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Invalid property, expected > 0, received <[0]>", e.getMessage());
- }
-
- @Test
- public void testNonNumericEventDelay() {
- Map map = getDefaultMap();
- map.put("event.delay", "not a number");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property received, not a number: ",
- e.getMessage()
- );
- }
-
- // target.hostname tests
- @Test
- public void testMissingTargetHostname() {
- Map map = getDefaultMap();
- map.remove("target.hostname");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
- }
-
- // target.port tests
- @Test
- public void testMissingTargetPort() {
- Map map = getDefaultMap();
- map.remove("target.port");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
- }
-
- @Test
- public void testTooSmallTargetPort() {
- Map map = getDefaultMap();
- map.put("target.port", "0");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property, expected between 1 and 65535, received <[0]>", e.getMessage()
- );
- }
-
- @Test
- public void testTooHighTargetPort() {
- Map map = getDefaultMap();
- map.put("target.port", "65536");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property, expected between 1 and 65535, received <[65536]>",
- e.getMessage()
- );
- }
-
- @Test
- public void testNonNumericTargetPort() {
- Map map = getDefaultMap();
- map.put("target.port", "not a number");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property received, not a number: ",
- e.getMessage()
- );
- }
-
- // relp.reconnectinterval tests
- @Test
- public void testMissingReconnectInterval() {
- Map map = getDefaultMap();
- map.remove("target.reconnectinterval");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
- }
-
- @Test
- public void testZeroReconnectInterval() {
- Map map = getDefaultMap();
- map.put("target.reconnectinterval", "0");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property, expected > 0, received <[0]>", e.getMessage()
- );
- }
-
- @Test
- public void testNonNumericReconnectInterval() {
- Map map = getDefaultMap();
- map.put("target.reconnectinterval", "not a number");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property received, not a number: ",
- e.getMessage()
- );
- }
-
- // prometheus.endport tests
- @Test
- public void testMissingPrometheusEndpoint() {
- Map map = getDefaultMap();
- map.remove("prometheus.port");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions.assertEquals("Missing property", e.getMessage());
- }
-
- @Test
- public void testTooSmallPrometheusPort() {
- Map map = getDefaultMap();
- map.put("prometheus.port", "0");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property, expected between 1 and 65535, received <[0]>",
- e.getMessage()
- );
- }
-
- @Test
- public void testTooHighPrometheusPort() {
- Map map = getDefaultMap();
- map.put("prometheus.port", "65536");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property, expected between 1 and 65535, received <[65536]>",
- e.getMessage()
- );
- }
-
- @Test
- public void testNonNumericPrometheusPort() {
- Map map = getDefaultMap();
- map.put("prometheus.port", "not a number");
- RelpProbeConfiguration configuration = new RelpProbeConfiguration(map);
- Exception e = Assertions.assertThrowsExactly(RelpProbeConfigurationError.class, configuration::validate);
- Assertions
- .assertEquals(
- "Invalid property received, not a number: ",
- e.getMessage()
- );
- }
-
- private Map getDefaultMap() {
- Map map = new HashMap<>();
- map.put("event.hostname", "rlp_11");
- map.put("event.appname", "rlp_11");
- map.put("event.delay", "1000");
- map.put("target.hostname", "127.0.0.1");
- map.put("target.port", "12345");
- map.put("target.reconnectinterval", "1000");
- map.put("prometheus.port", "8080");
- return map;
- }
-}
diff --git a/src/test/resources/connectiontest.properties b/src/test/resources/connectiontest.properties
index 01384c9..9719305 100644
--- a/src/test/resources/connectiontest.properties
+++ b/src/test/resources/connectiontest.properties
@@ -5,6 +5,11 @@ event.delay=1000
# Hostname used in RELP event
event.hostname=rlp_11
+# Metrics reporting name. Arbitrary string, only used for reporting purposes
+metrics.name=target
+# Metrics window size
+metrics.window=10000
+
# Prometheus endpoint port
prometheus.port=8080
From 6af67623d6a56925fd627a48a8f6675b3904dc16 Mon Sep 17 00:00:00 2001
From: StrongestNumber9 <16169054+StrongestNumber9@users.noreply.github.com>
Date: Thu, 7 Nov 2024 15:24:29 +0200
Subject: [PATCH 11/14] Adds some tests for configurations
---
.../Configuration/EventConfiguration.java | 31 ++--
.../EventConfigurationBuilder.java | 6 +-
.../IntConfigurationBuilder.java | 68 ++++++++
.../Configuration/MetricsConfiguration.java | 10 +-
.../MetricsConfigurationBuilder.java | 2 +-
.../PrometheusConfiguration.java | 9 +-
.../PrometheusConfigurationBuilder.java | 2 +-
.../Configuration/TargetConfiguration.java | 23 +--
.../TargetConfigurationBuilder.java | 10 +-
.../Configuration/EventConfigurationTest.java | 125 +++++++++++++++
.../MetricsConfigurationTest.java | 108 +++++++++++++
.../PrometheusConfigurationTest.java | 99 ++++++++++++
.../TargetConfigurationTest.java | 147 ++++++++++++++++++
.../com/teragrep/rlp_11/ConnectionTest.java | 2 +-
src/test/resources/missing.properties | 0
15 files changed, 599 insertions(+), 43 deletions(-)
create mode 100644 src/main/java/com/teragrep/rlp_11/Configuration/IntConfigurationBuilder.java
create mode 100644 src/test/java/com/teragrep/rlp_11/Configuration/EventConfigurationTest.java
create mode 100644 src/test/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationTest.java
create mode 100644 src/test/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationTest.java
create mode 100644 src/test/java/com/teragrep/rlp_11/Configuration/TargetConfigurationTest.java
create mode 100644 src/test/resources/missing.properties
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/EventConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/EventConfiguration.java
index c2cc30d..312858c 100644
--- a/src/main/java/com/teragrep/rlp_11/Configuration/EventConfiguration.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/EventConfiguration.java
@@ -51,39 +51,36 @@
public class EventConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(EventConfiguration.class);
- private final String appname;
private final String hostname;
+ private final String appname;
private final int delay;
- public EventConfiguration(final String appname, final String hostname, final int delay) {
- this.appname = appname;
+ public EventConfiguration(final String hostname, final String appname, final int delay) {
this.hostname = hostname;
+ this.appname = appname;
this.delay = delay;
}
- public String appname() {
- if (appname == null) {
- final String errorMessage = "Appname is null";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ public String hostname() {
+ if (hostname == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
}
- return appname;
+ return hostname;
}
- public String hostname() {
+ public String appname() {
if (appname == null) {
- final String errorMessage = "Hostname is null";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
}
- return hostname;
+ return appname;
}
public int delay() {
if (delay <= 0) {
- final String errorMessage = "Delay too small, expected to be >0";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ LOGGER.error("Configuration failure: <[{}]> too small, expected to be >0", delay);
+ throw new ConfigurationException("Invalid value for received");
}
return delay;
}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/EventConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/EventConfigurationBuilder.java
index 41086f6..6e850a5 100644
--- a/src/main/java/com/teragrep/rlp_11/Configuration/EventConfigurationBuilder.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/EventConfigurationBuilder.java
@@ -54,9 +54,9 @@ private EventConfigurationBuilder() {
}
public static EventConfiguration build(final Map config) {
- final String appname = config.get("event.appname");
final String hostname = config.get("event.hostname");
- final int delay = Integer.parseInt(config.get("event.delay"));
- return new EventConfiguration(appname, hostname, delay);
+ final String appname = config.get("event.appname");
+ final int delay = IntConfigurationBuilder.get("event.delay", config.get("event.delay"));
+ return new EventConfiguration(hostname, appname, delay);
}
}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/IntConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/IntConfigurationBuilder.java
new file mode 100644
index 0000000..2030cfc
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/IntConfigurationBuilder.java
@@ -0,0 +1,68 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class IntConfigurationBuilder {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(IntConfigurationBuilder.class);
+
+ private IntConfigurationBuilder() {
+
+ }
+
+ public static int get(final String name, final String value) {
+ try {
+ return Integer.parseInt(value);
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Configuration failure: Invalid value for <{}> received: <{}>", name, e.getMessage());
+ throw new ConfigurationException("Invalid value for <" + name + "> received: <" + e.getMessage() + ">");
+ }
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java
index b8b808c..94b90b9 100644
--- a/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java
@@ -61,18 +61,16 @@ public MetricsConfiguration(final String name, final int window) {
public String name() {
if (name == null) {
- final String errorMessage = "Name is null";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
}
return name;
}
public int window() {
if (window <= 0) {
- final String errorMessage = "Window too small, expected to be >0";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ LOGGER.error("Configuration failure: <[{}]> too small, expected to be >0", window);
+ throw new ConfigurationException("Invalid value for received");
}
return window;
}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationBuilder.java
index 2b55572..b00690d 100644
--- a/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationBuilder.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationBuilder.java
@@ -55,7 +55,7 @@ private MetricsConfigurationBuilder() {
public static MetricsConfiguration build(final Map config) {
final String name = config.get("metrics.name");
- final int window = Integer.parseInt(config.get("metrics.window"));
+ final int window = IntConfigurationBuilder.get("metrics.window", config.get("metrics.window"));
return new MetricsConfiguration(name, window);
}
}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java
index 19c1450..da8aaae 100644
--- a/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java
@@ -60,9 +60,12 @@ public PrometheusConfiguration(final int port) {
public int port() {
if (port < 1 || port > 65535) {
- final String errorMessage = "Port is in invalid range, expected between 1 and 65535";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ LOGGER
+ .error(
+ "Configuration failure: <[{}]> is in invalid range, expected between 1 and 65535",
+ port
+ );
+ throw new ConfigurationException("Invalid value for received");
}
return port;
}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationBuilder.java
index ad047ef..2897ec5 100644
--- a/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationBuilder.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationBuilder.java
@@ -54,7 +54,7 @@ private PrometheusConfigurationBuilder() {
}
public static PrometheusConfiguration build(final Map config) {
- final int port = Integer.parseInt(config.get("prometheus.port"));
+ final int port = IntConfigurationBuilder.get("prometheus.port", config.get("prometheus.port"));
return new PrometheusConfiguration(port);
}
}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java
index c38e0d6..d619d38 100644
--- a/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java
@@ -63,27 +63,32 @@ public TargetConfiguration(final String hostname, final int port, final int reco
public String hostname() {
if (hostname == null) {
- final String errorMessage = "Hostname is null";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
}
return hostname;
}
public int port() {
if (port < 1 || port > 65535) {
- final String errorMessage = "Port is in invalid range, expected between 1 and 65535";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ LOGGER
+ .error(
+ "Configuration failure: <[{}]> is in invalid range, expected between 1 and 65535",
+ port
+ );
+ throw new ConfigurationException("Invalid value for received");
}
return port;
}
public int reconnectInterval() {
if (reconnectInterval <= 0) {
- final String errorMessage = "Reconnect interval too small, expected to be >0";
- LOGGER.error(errorMessage);
- throw new ConfigurationException(errorMessage);
+ LOGGER
+ .error(
+ "Configuration failure: <[{}]> too small, expected to be >0",
+ reconnectInterval
+ );
+ throw new ConfigurationException("Invalid value for received");
}
return reconnectInterval;
}
diff --git a/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfigurationBuilder.java b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfigurationBuilder.java
index f433926..da0f961 100644
--- a/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfigurationBuilder.java
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfigurationBuilder.java
@@ -45,18 +45,24 @@
*/
package com.teragrep.rlp_11.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.util.Map;
public final class TargetConfigurationBuilder {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TargetConfigurationBuilder.class);
+
private TargetConfigurationBuilder() {
}
public static TargetConfiguration build(final Map config) {
final String hostname = config.get("target.hostname");
- final int port = Integer.parseInt(config.get("target.port"));
- final int reconnectInterval = Integer.parseInt(config.get("target.reconnectinterval"));
+ final int port = IntConfigurationBuilder.get("target.port", config.get("target.port"));
+ final int reconnectInterval = IntConfigurationBuilder
+ .get("target.reconnectinterval", config.get("target.reconnectinterval"));
return new TargetConfiguration(hostname, port, reconnectInterval);
}
}
diff --git a/src/test/java/com/teragrep/rlp_11/Configuration/EventConfigurationTest.java b/src/test/java/com/teragrep/rlp_11/Configuration/EventConfigurationTest.java
new file mode 100644
index 0000000..d9852f4
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/EventConfigurationTest.java
@@ -0,0 +1,125 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EventConfigurationTest {
+
+ // event.hostname
+ @Test
+ public void testNonNullHostname() {
+ Map map = baseConfig();
+ EventConfiguration eventConfiguration = EventConfigurationBuilder.build(map);
+ Assertions.assertEquals("my-hostname", eventConfiguration.hostname());
+ }
+
+ @Test
+ public void testNullHostname() {
+ Map map = baseConfig();
+ map.remove("event.hostname");
+ EventConfiguration eventConfiguration = EventConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, eventConfiguration::hostname);
+ }
+
+ // event.appname
+ @Test
+ public void testNonNullAppname() {
+ Map map = baseConfig();
+ EventConfiguration eventConfiguration = EventConfigurationBuilder.build(map);
+ Assertions.assertEquals("my-appname", eventConfiguration.appname());
+ }
+
+ @Test
+ public void testNullAppname() {
+ Map map = baseConfig();
+ map.remove("event.appname");
+ EventConfiguration eventConfiguration = EventConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, eventConfiguration::appname);
+ }
+
+ // event.delay
+ @Test
+ public void testGoodDelay() {
+ Map map = baseConfig();
+ EventConfiguration eventConfiguration = EventConfigurationBuilder.build(map);
+ Assertions.assertEquals(15000, eventConfiguration.delay());
+ }
+
+ @Test
+ public void testNullDelay() {
+ Map map = baseConfig();
+ map.remove("event.delay");
+ Assertions.assertThrowsExactly(ConfigurationException.class, () -> EventConfigurationBuilder.build(map));
+ }
+
+ @Test
+ public void testTooSmallDelay() {
+ Map map = baseConfig();
+ map.put("event.delay", "0");
+ EventConfiguration eventConfiguration = EventConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, eventConfiguration::delay);
+ }
+
+ @Test
+ public void testNonNumericDelay() {
+ Map map = baseConfig();
+ map.put("event.delay", "not a number");
+ Assertions.assertThrowsExactly(ConfigurationException.class, () -> EventConfigurationBuilder.build(map));
+ }
+
+ private Map baseConfig() {
+ Map map = new HashMap<>();
+ map.put("event.hostname", "my-hostname");
+ map.put("event.appname", "my-appname");
+ map.put("event.delay", "15000");
+ return map;
+ }
+}
diff --git a/src/test/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationTest.java b/src/test/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationTest.java
new file mode 100644
index 0000000..9ae9dcf
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationTest.java
@@ -0,0 +1,108 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MetricsConfigurationTest {
+
+ // metrics.name
+ @Test
+ public void testNonNullName() {
+ Map map = baseConfig();
+ MetricsConfiguration metricsConfiguration = MetricsConfigurationBuilder.build(map);
+ Assertions.assertEquals("target-name", metricsConfiguration.name());
+ }
+
+ @Test
+ public void testNullName() {
+ Map map = baseConfig();
+ map.remove("metrics.name");
+ MetricsConfiguration metricsConfiguration = MetricsConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, metricsConfiguration::name);
+ }
+
+ // metrics.window
+ @Test
+ public void testGoodWindow() {
+ Map map = baseConfig();
+ MetricsConfiguration metricsConfiguration = MetricsConfigurationBuilder.build(map);
+ Assertions.assertEquals(1337, metricsConfiguration.window());
+ }
+
+ @Test
+ public void testNullWindow() {
+ Map map = baseConfig();
+ map.remove("metrics.window");
+ Assertions.assertThrowsExactly(ConfigurationException.class, () -> MetricsConfigurationBuilder.build(map));
+ }
+
+ @Test
+ public void testTooSmallWindow() {
+ Map map = baseConfig();
+ map.put("metrics.window", "0");
+ MetricsConfiguration metricsConfiguration = MetricsConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, metricsConfiguration::window);
+ }
+
+ @Test
+ public void testNonNumericWindow() {
+ Map map = baseConfig();
+ map.put("metrics.window", "Not a number here");
+ Assertions.assertThrowsExactly(ConfigurationException.class, () -> MetricsConfigurationBuilder.build(map));
+ }
+
+ private Map baseConfig() {
+ Map map = new HashMap<>();
+ map.put("metrics.name", "target-name");
+ map.put("metrics.window", "1337");
+ return map;
+ }
+}
diff --git a/src/test/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationTest.java b/src/test/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationTest.java
new file mode 100644
index 0000000..9e498c3
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationTest.java
@@ -0,0 +1,99 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PrometheusConfigurationTest {
+
+ // prometheus.port
+ @Test
+ public void testGoodPort() {
+ Map map = baseConfig();
+ PrometheusConfiguration prometheusConfiguration = PrometheusConfigurationBuilder.build(map);
+ Assertions.assertEquals(8080, prometheusConfiguration.port());
+ }
+
+ @Test
+ public void testNullPort() {
+ Map map = baseConfig();
+ map.remove("prometheus.port");
+ Assertions.assertThrowsExactly(ConfigurationException.class, () -> PrometheusConfigurationBuilder.build(map));
+ }
+
+ @Test
+ public void testTooSmallPort() {
+ Map map = baseConfig();
+ map.put("prometheus.port", "0");
+ PrometheusConfiguration prometheusConfiguration = PrometheusConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, prometheusConfiguration::port);
+ }
+
+ @Test
+ public void testTooHighPort() {
+ Map map = baseConfig();
+ map.put("prometheus.port", "65536");
+ PrometheusConfiguration prometheusConfiguration = PrometheusConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, prometheusConfiguration::port);
+ }
+
+ @Test
+ public void testNonNumericport() {
+ Map map = baseConfig();
+ map.put("prometheus.port", "not a number");
+ Assertions.assertThrowsExactly(ConfigurationException.class, () -> PrometheusConfigurationBuilder.build(map));
+ }
+
+ private Map baseConfig() {
+ Map map = new HashMap<>();
+ map.put("prometheus.port", "8080");
+ return map;
+ }
+}
diff --git a/src/test/java/com/teragrep/rlp_11/Configuration/TargetConfigurationTest.java b/src/test/java/com/teragrep/rlp_11/Configuration/TargetConfigurationTest.java
new file mode 100644
index 0000000..980254f
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/TargetConfigurationTest.java
@@ -0,0 +1,147 @@
+/*
+ * RELP Commit Latency Probe RLP-11
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
+package com.teragrep.rlp_11.Configuration;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TargetConfigurationTest {
+
+ // target.hostname
+ @Test
+ public void testNonNullHostname() {
+ Map map = baseConfig();
+ TargetConfiguration targetConfiguration = TargetConfigurationBuilder.build(map);
+ Assertions.assertEquals("target-hostname", targetConfiguration.hostname());
+ }
+
+ @Test
+ public void testNullHostname() {
+ Map map = baseConfig();
+ map.remove("target.hostname");
+ TargetConfiguration targetConfiguration = TargetConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::hostname);
+ }
+
+ // target.port
+ @Test
+ public void testGoodPort() {
+ Map map = baseConfig();
+ TargetConfiguration targetConfiguration = TargetConfigurationBuilder.build(map);
+ Assertions.assertEquals(601, targetConfiguration.port());
+ }
+
+ @Test
+ public void testNullPort() {
+ Map map = baseConfig();
+ map.remove("target.port");
+ Assertions.assertThrowsExactly(ConfigurationException.class, () -> TargetConfigurationBuilder.build(map));
+ }
+
+ @Test
+ public void testTooSmallPort() {
+ Map map = baseConfig();
+ map.put("target.port", "0");
+ TargetConfiguration targetConfiguration = TargetConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::port);
+ }
+
+ @Test
+ public void testTooHighPort() {
+ Map map = baseConfig();
+ map.put("target.port", "65536");
+ TargetConfiguration targetConfiguration = TargetConfigurationBuilder.build(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::port);
+ }
+
+ @Test
+ public void testNonNumericPort() {
+ Map map = baseConfig();
+ map.put("target.port", "not a number");
+ Assertions.assertThrowsExactly(ConfigurationException.class, () -> TargetConfigurationBuilder.build(map));
+ }
+
+ // target.reconnectinterval
+ @Test
+ public void testGoodReconnectInterval() {
+ Map map = baseConfig();
+ TargetConfiguration targetConfiguration = TargetConfigurationBuilder.build(map);
+ Assertions.assertEquals(15000, targetConfiguration.reconnectInterval());
+ }
+
+ @Test
+ public void testNullReconnectInterval() {
+ Map