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..624dea0
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,623 @@
+
+
+ 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
+ 11.0.24
+ 1.1.7
+ 2.1.3
+ 17
+ 1.11.3
+ 5.11.3
+ 2.24.1
+ 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.eclipse.jetty
+ jetty-servlet
+ ${eclipse.jetty.version}
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+ org.apache.logging.log4j
+ log4j-core
+ ${log4j2.version}
+
+
+ org.apache.logging.log4j
+ log4j-slf4j2-impl
+ ${log4j2.version}
+
+
+
+ jakarta.json
+ jakarta.json-api
+ ${jakarta.json.version}
+
+
+ org.eclipse.parsson
+ parsson
+ ${eclipse.parsson.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
+
+ src/main/resources/log4j2.xml
+
+ 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/Configuration/ConfigurationException.java b/src/main/java/com/teragrep/rlp_11/Configuration/ConfigurationException.java
new file mode 100644
index 0000000..69daa51
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/ConfigurationException.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.Configuration;
+
+public class ConfigurationException extends RuntimeException {
+
+ public ConfigurationException(final String s) {
+ super(s);
+ }
+}
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..c096a1b
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/MetricsConfiguration.java
@@ -0,0 +1,91 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+public class MetricsConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MetricsConfiguration.class);
+ private final Map config;
+
+ public MetricsConfiguration(final Map config) {
+ this.config = config;
+ }
+
+ public String name() {
+ final String name = config.get("metrics.name");
+ if (name == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ return name;
+ }
+
+ public int window() {
+ final String windowString = config.get("metrics.window");
+ if (windowString == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ final int window;
+ try {
+ window = Integer.parseInt(windowString);
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Configuration failure: Invalid value for : <{}>", e.getMessage());
+ throw e;
+ }
+ if (window <= 0) {
+ 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/ProbeConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/ProbeConfiguration.java
new file mode 100644
index 0000000..83315ec
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/ProbeConfiguration.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+public class ProbeConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ProbeConfiguration.class);
+ private final Map config;
+
+ public ProbeConfiguration(final Map config) {
+ this.config = config;
+ }
+
+ public int interval() {
+ final String intervalString = config.get("probe.interval");
+ if (intervalString == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ final int interval;
+ try {
+ interval = Integer.parseInt(intervalString);
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Configuration failure: Invalid value for : <{}>", e.getMessage());
+ throw e;
+ }
+ if (interval <= 0) {
+ LOGGER.error("Configuration failure: <[{}]> too small, expected to be >0", interval);
+ throw new ConfigurationException("Invalid value for received");
+ }
+ return interval;
+ }
+}
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..817b987
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/PrometheusConfiguration.java
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+public class PrometheusConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(PrometheusConfiguration.class);
+ private final Map config;
+
+ public PrometheusConfiguration(final Map config) {
+ this.config = config;
+ }
+
+ public int port() {
+ final String portString = config.get("prometheus.port");
+ if (portString == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ final int port;
+ try {
+ port = Integer.parseInt(portString);
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Configuration failure: Invalid value for : <{}>", e.getMessage());
+ throw e;
+ }
+ if (port < 1 || port > 65535) {
+ 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/RecordConfiguration.java b/src/main/java/com/teragrep/rlp_11/Configuration/RecordConfiguration.java
new file mode 100644
index 0000000..9d3cfc6
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/RecordConfiguration.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;
+
+import java.util.Map;
+
+public class RecordConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(RecordConfiguration.class);
+ private final Map config;
+
+ public RecordConfiguration(final Map config) {
+ this.config = config;
+ }
+
+ public String hostname() {
+ final String hostname = config.get("record.hostname");
+ if (hostname == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ return hostname;
+ }
+
+ public String appname() {
+ final String appname = config.get("record.appname");
+ if (appname == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ return appname;
+ }
+}
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..ac2ee11
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Configuration/TargetConfiguration.java
@@ -0,0 +1,120 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+public class TargetConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TargetConfiguration.class);
+ private final Map config;
+
+ public TargetConfiguration(final Map config) {
+ this.config = config;
+ }
+
+ public String hostname() {
+ final String hostname = config.get("target.hostname");
+ if (hostname == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ return hostname;
+ }
+
+ public int port() {
+ final String portString = config.get("target.port");
+ if (portString == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ final int port;
+ try {
+ port = Integer.parseInt(portString);
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Configuration failure: Invalid value for : <{}>", e.getMessage());
+ throw e;
+ }
+ if (port < 1 || port > 65535) {
+ 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() {
+ final String reconnectIntervalString = config.get("target.reconnectinterval");
+ if (reconnectIntervalString == null) {
+ LOGGER.error("Configuration failure: is null");
+ throw new ConfigurationException("Invalid value for received");
+ }
+ final int reconnectInterval;
+ try {
+ reconnectInterval = Integer.parseInt(reconnectIntervalString);
+ }
+ catch (NumberFormatException e) {
+ LOGGER.error("Configuration failure: Invalid value for : <{}>", e.getMessage());
+ throw e;
+ }
+ if (reconnectInterval <= 0) {
+ 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/Main.java b/src/main/java/com/teragrep/rlp_11/Main.java
new file mode 100644
index 0000000..503e377
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/Main.java
@@ -0,0 +1,124 @@
+/*
+ * 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.rlp_11.Configuration.ProbeConfiguration;
+import com.teragrep.rlp_11.Configuration.RecordConfiguration;
+import com.teragrep.rlp_11.Configuration.MetricsConfiguration;
+import com.teragrep.rlp_11.Configuration.PrometheusConfiguration;
+import com.teragrep.rlp_11.Configuration.TargetConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Map;
+
+public class Main {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
+
+ 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")
+ );
+ final Map map;
+ try {
+ map = pathConfiguration.asMap();
+ }
+ catch (com.teragrep.cnf_01.ConfigurationException e) {
+ LOGGER.error("Failed to create PathConfiguration: <{}>", e.getMessage());
+ throw e;
+ }
+ final PrometheusConfiguration prometheusConfiguration = new PrometheusConfiguration(map);
+ final RecordConfiguration recordConfiguration = new RecordConfiguration(map);
+ final TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ final MetricsConfiguration metricsConfiguration = new MetricsConfiguration(map);
+ final RecordFactory recordFactory = new RecordFactory(
+ getHostname(),
+ recordConfiguration.hostname(),
+ recordConfiguration.appname()
+ );
+ final ProbeConfiguration probeConfiguration = new ProbeConfiguration(map);
+ final RelpProbe relpProbe = new RelpProbe(
+ targetConfiguration,
+ probeConfiguration,
+ prometheusConfiguration,
+ metricsConfiguration,
+ recordFactory
+ );
+ final Thread shutdownHook = new Thread(() -> {
+ LOGGER.debug("Stopping RelpProbe..");
+ relpProbe.stop();
+ LOGGER.debug("Shutting down.");
+ });
+ Runtime.getRuntime().addShutdownHook(shutdownHook);
+ LOGGER
+ .info(
+ "Sending records to <[{}:{}]> every <[{}]> milliseconds", targetConfiguration.hostname(),
+ targetConfiguration.port(), probeConfiguration.interval()
+ );
+ LOGGER
+ .info(
+ "Using hostname <[{}]> and appname <[{}]> for the records.", recordConfiguration.hostname(),
+ recordConfiguration.appname()
+ );
+ relpProbe.start();
+ }
+
+ private static String getHostname() {
+ String origin;
+ try {
+ origin = InetAddress.getLocalHost().getHostName();
+ }
+ catch (UnknownHostException e) {
+ origin = "localhost";
+ LOGGER.warn("Could not get hostname, using <{}> instead", origin);
+ }
+ return origin;
+ }
+}
diff --git a/src/main/java/com/teragrep/rlp_11/RecordFactory.java b/src/main/java/com/teragrep/rlp_11/RecordFactory.java
new file mode 100644
index 0000000..07cc514
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/RecordFactory.java
@@ -0,0 +1,87 @@
+/*
+ * 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 jakarta.json.Json;
+import jakarta.json.JsonObject;
+
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+
+public class RecordFactory {
+
+ private final String origin;
+ private final String hostname;
+ private final String appname;
+
+ public RecordFactory(final String origin, final String hostname, final String appname) {
+ this.origin = origin;
+ this.hostname = hostname;
+ this.appname = appname;
+ }
+
+ public byte[] createRecord() {
+ final Instant timestamp = Instant.now();
+ final String timestampString = timestamp.getEpochSecond() + "." + timestamp.getNano();
+ final JsonObject event = Json
+ .createObjectBuilder()
+ .add("origin", origin)
+ .add("timestamp", timestampString)
+ .build();
+ return new SyslogMessage()
+ .withTimestamp(timestamp.toEpochMilli())
+ .withAppName(appname)
+ .withHostname(hostname)
+ .withFacility(Facility.USER)
+ .withSeverity(Severity.INFORMATIONAL)
+ .withMsg(event.toString())
+ .toRfc5424SyslogMessage()
+ .getBytes(StandardCharsets.UTF_8);
+ }
+}
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..277138d
--- /dev/null
+++ b/src/main/java/com/teragrep/rlp_11/RelpProbe.java
@@ -0,0 +1,252 @@
+/*
+ * 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.Slf4jReporter;
+import com.codahale.metrics.SlidingWindowReservoir;
+import com.codahale.metrics.Timer;
+import com.codahale.metrics.jmx.JmxReporter;
+import com.teragrep.rlp_01.RelpBatch;
+import com.teragrep.rlp_01.RelpConnection;
+import com.teragrep.rlp_11.Configuration.ProbeConfiguration;
+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;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static com.codahale.metrics.MetricRegistry.name;
+
+public class RelpProbe {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(RelpProbe.class);
+ private final TargetConfiguration targetConfiguration;
+ private final RecordFactory recordFactory;
+ private final PrometheusConfiguration prometheusConfiguration;
+ private final MetricsConfiguration metricsConfiguration;
+ private final ProbeConfiguration probeConfiguration;
+ private final AtomicBoolean stayRunning = new AtomicBoolean(true);
+ private RelpConnection relpConnection;
+ private final CountDownLatch latch = new CountDownLatch(1);
+ private boolean connected = false;
+ 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 TargetConfiguration targetConfiguration,
+ final ProbeConfiguration probeConfiguration,
+ final PrometheusConfiguration prometheusConfiguration,
+ final MetricsConfiguration metricsConfiguration,
+ final RecordFactory recordFactory
+ ) {
+ this.targetConfiguration = targetConfiguration;
+ this.probeConfiguration = probeConfiguration;
+ this.recordFactory = recordFactory;
+ this.prometheusConfiguration = prometheusConfiguration;
+ this.metricsConfiguration = metricsConfiguration;
+ }
+
+ public void start() {
+ createMetrics(metricsConfiguration.name());
+ this.jmxReporter.start();
+ this.slf4jReporter.start(1, TimeUnit.MINUTES);
+ relpConnection = new RelpConnection();
+ connect();
+ while (stayRunning.get()) {
+ final RelpBatch relpBatch = new RelpBatch();
+ relpBatch.insert(recordFactory.createRecord());
+
+ boolean allSent = false;
+ while (!allSent && stayRunning.get()) {
+ try (final Timer.Context context = sendLatency.time()) {
+ LOGGER.debug("Committing Relpbatch");
+ relpConnection.commit(relpBatch);
+ records.inc();
+ }
+ catch (IllegalStateException | IOException | java.util.concurrent.TimeoutException e) {
+ LOGGER.warn("Failed to commit: <{}>", e.getMessage());
+ relpConnection.tearDown();
+ connected = false;
+ }
+ LOGGER.debug("Verifying Transaction");
+ allSent = relpBatch.verifyTransactionAll();
+ if (!allSent) {
+ LOGGER.warn("Transactions failed, retrying");
+ resends.inc();
+ relpBatch.retryAllFailed();
+ reconnect();
+ }
+ }
+ try {
+ LOGGER.debug("Sleeping before sending next event");
+ Thread.sleep(probeConfiguration.interval());
+ }
+ catch (InterruptedException e) {
+ LOGGER.warn("Sleep interrupted: <{}>", e.getMessage());
+ }
+ }
+ disconnect();
+ latch.countDown();
+ teardownMetrics();
+ }
+
+ private void connect() {
+ while (!connected && stayRunning.get()) {
+ 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.");
+ connects.inc();
+ }
+ catch (TimeoutException | IOException e) {
+ LOGGER
+ .warn(
+ "Failed to connect to <[{}:{}]>: <{}>", targetConfiguration.hostname(),
+ targetConfiguration.port(), e.getMessage()
+ );
+ }
+ if (!connected) {
+ try {
+ 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());
+ }
+ }
+ }
+ }
+
+ private void reconnect() {
+ disconnect();
+ connect();
+ }
+
+ private void disconnect() {
+ if (!connected) {
+ LOGGER.debug("No need to disconnect, not connected");
+ return;
+ }
+ try {
+ LOGGER.debug("Disconnecting..");
+ relpConnection.disconnect();
+ disconnects.inc();
+ }
+ catch (IOException | TimeoutException e) {
+ LOGGER.warn("Failed to disconnect: <{}>", e.getMessage());
+ }
+ relpConnection.tearDown();
+ LOGGER.debug("Disconnected.");
+ connected = false;
+ }
+
+ public void stop() {
+ LOGGER.debug("Stop called");
+ stayRunning.set(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.debug("RelpProbe stopped.");
+ }
+
+ 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"));
+ 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() {
+ jmxReporter.close();
+ slf4jReporter.close();
+ try {
+ jettyServer.stop();
+ }
+ //CHECKSTYLE:OFF
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ //CHECKSTYLE:ON
+ }
+}
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/Configuration/MetricsConfigurationTest.java b/src/test/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationTest.java
new file mode 100644
index 0000000..aee9f41
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/MetricsConfigurationTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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 = new MetricsConfiguration(map);
+ Assertions.assertEquals("target-name", metricsConfiguration.name());
+ }
+
+ @Test
+ public void testNullName() {
+ Map map = baseConfig();
+ map.remove("metrics.name");
+ MetricsConfiguration metricsConfiguration = new MetricsConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, metricsConfiguration::name);
+ }
+
+ // metrics.window
+ @Test
+ public void testGoodWindow() {
+ Map map = baseConfig();
+ MetricsConfiguration metricsConfiguration = new MetricsConfiguration(map);
+ Assertions.assertEquals(1337, metricsConfiguration.window());
+ }
+
+ @Test
+ public void testNullWindow() {
+ Map map = baseConfig();
+ map.remove("metrics.window");
+ MetricsConfiguration metricsConfiguration = new MetricsConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, metricsConfiguration::window);
+ }
+
+ @Test
+ public void testTooSmallWindow() {
+ Map map = baseConfig();
+ map.put("metrics.window", "0");
+ MetricsConfiguration metricsConfiguration = new MetricsConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, metricsConfiguration::window);
+ }
+
+ @Test
+ public void testNonNumericWindow() {
+ Map map = baseConfig();
+ map.put("metrics.window", "Not a number here");
+ MetricsConfiguration metricsConfiguration = new MetricsConfiguration(map);
+ Assertions.assertThrowsExactly(NumberFormatException.class, metricsConfiguration::window);
+ }
+
+ 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/ProbeConfigurationTest.java b/src/test/java/com/teragrep/rlp_11/Configuration/ProbeConfigurationTest.java
new file mode 100644
index 0000000..b7b0276
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/ProbeConfigurationTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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 ProbeConfigurationTest {
+
+ // probe.interval
+ @Test
+ public void testGoodInterval() {
+ Map map = baseConfig();
+ ProbeConfiguration probeConfiguration = new ProbeConfiguration(map);
+ Assertions.assertEquals(12500, probeConfiguration.interval());
+ }
+
+ @Test
+ public void testNullInterval() {
+ Map map = baseConfig();
+ map.remove("probe.interval");
+ ProbeConfiguration probeConfiguration = new ProbeConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, probeConfiguration::interval);
+ }
+
+ @Test
+ public void testTooSmallInterval() {
+ Map map = baseConfig();
+ map.put("probe.interval", "0");
+ ProbeConfiguration probeConfiguration = new ProbeConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, probeConfiguration::interval);
+ }
+
+ @Test
+ public void testNonNumericInterval() {
+ Map map = baseConfig();
+ map.put("probe.interval", "not a number");
+ ProbeConfiguration probeConfiguration = new ProbeConfiguration(map);
+ Assertions.assertThrowsExactly(NumberFormatException.class, probeConfiguration::interval);
+ }
+
+ private Map baseConfig() {
+ Map map = new HashMap<>();
+ map.put("probe.interval", "12500");
+ 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..008e6f4
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/PrometheusConfigurationTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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 = new PrometheusConfiguration(map);
+ Assertions.assertEquals(8080, prometheusConfiguration.port());
+ }
+
+ @Test
+ public void testNullPort() {
+ Map map = baseConfig();
+ map.remove("prometheus.port");
+ PrometheusConfiguration prometheusConfiguration = new PrometheusConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, prometheusConfiguration::port);
+ }
+
+ @Test
+ public void testTooSmallPort() {
+ Map map = baseConfig();
+ map.put("prometheus.port", "0");
+ PrometheusConfiguration prometheusConfiguration = new PrometheusConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, prometheusConfiguration::port);
+ }
+
+ @Test
+ public void testTooHighPort() {
+ Map map = baseConfig();
+ map.put("prometheus.port", "65536");
+ PrometheusConfiguration prometheusConfiguration = new PrometheusConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, prometheusConfiguration::port);
+ }
+
+ @Test
+ public void testNonNumericPort() {
+ Map map = baseConfig();
+ map.put("prometheus.port", "not a number");
+ PrometheusConfiguration prometheusConfiguration = new PrometheusConfiguration(map);
+ Assertions.assertThrowsExactly(NumberFormatException.class, prometheusConfiguration::port);
+ }
+
+ 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/RecordConfigurationTest.java b/src/test/java/com/teragrep/rlp_11/Configuration/RecordConfigurationTest.java
new file mode 100644
index 0000000..ee53329
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/RecordConfigurationTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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 RecordConfigurationTest {
+
+ // event.hostname
+ @Test
+ public void testNonNullHostname() {
+ Map map = baseConfig();
+ RecordConfiguration eventConfiguration = new RecordConfiguration(map);
+ Assertions.assertEquals("my-hostname", eventConfiguration.hostname());
+ }
+
+ @Test
+ public void testNullHostname() {
+ Map map = baseConfig();
+ map.remove("record.hostname");
+ RecordConfiguration eventConfiguration = new RecordConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, eventConfiguration::hostname);
+ }
+
+ // event.appname
+ @Test
+ public void testNonNullAppname() {
+ Map map = baseConfig();
+ RecordConfiguration eventConfiguration = new RecordConfiguration(map);
+ Assertions.assertEquals("my-appname", eventConfiguration.appname());
+ }
+
+ @Test
+ public void testNullAppname() {
+ Map map = baseConfig();
+ map.remove("record.appname");
+ RecordConfiguration eventConfiguration = new RecordConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, eventConfiguration::appname);
+ }
+
+ private Map baseConfig() {
+ Map map = new HashMap<>();
+ map.put("record.hostname", "my-hostname");
+ map.put("record.appname", "my-appname");
+ 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..9fe0693
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/Configuration/TargetConfigurationTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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 = new TargetConfiguration(map);
+ Assertions.assertEquals("target-hostname", targetConfiguration.hostname());
+ }
+
+ @Test
+ public void testNullHostname() {
+ Map map = baseConfig();
+ map.remove("target.hostname");
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::hostname);
+ }
+
+ // target.port
+ @Test
+ public void testGoodPort() {
+ Map map = baseConfig();
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertEquals(601, targetConfiguration.port());
+ }
+
+ @Test
+ public void testNullPort() {
+ Map map = baseConfig();
+ map.remove("target.port");
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::port);
+ }
+
+ @Test
+ public void testTooSmallPort() {
+ Map map = baseConfig();
+ map.put("target.port", "0");
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::port);
+ }
+
+ @Test
+ public void testTooHighPort() {
+ Map map = baseConfig();
+ map.put("target.port", "65536");
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::port);
+ }
+
+ @Test
+ public void testNonNumericPort() {
+ Map map = baseConfig();
+ map.put("target.port", "not a number");
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertThrowsExactly(NumberFormatException.class, targetConfiguration::port);
+ }
+
+ // target.reconnectinterval
+ @Test
+ public void testGoodReconnectInterval() {
+ Map map = baseConfig();
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertEquals(15000, targetConfiguration.reconnectInterval());
+ }
+
+ @Test
+ public void testNullReconnectInterval() {
+ Map map = baseConfig();
+ map.remove("target.reconnectinterval");
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::reconnectInterval);
+ }
+
+ @Test
+ public void testTooSmallReconnectInterval() {
+ Map map = baseConfig();
+ map.put("target.reconnectinterval", "0");
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertThrowsExactly(ConfigurationException.class, targetConfiguration::reconnectInterval);
+ }
+
+ @Test
+ public void testNonNumericReconnectInterval() {
+ Map map = baseConfig();
+ map.put("target.reconnectinterval", "not a number");
+ TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ Assertions.assertThrowsExactly(NumberFormatException.class, targetConfiguration::reconnectInterval);
+ }
+
+ private Map baseConfig() {
+ Map map = new HashMap<>();
+ map.put("target.hostname", "target-hostname");
+ map.put("target.port", "601");
+ map.put("target.reconnectinterval", "15000");
+ return map;
+ }
+}
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..d9fd278
--- /dev/null
+++ b/src/test/java/com/teragrep/rlp_11/ConnectionTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.Server;
+import com.teragrep.net_01.server.ServerFactory;
+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.ProbeConfiguration;
+import com.teragrep.rlp_11.Configuration.MetricsConfiguration;
+import com.teragrep.rlp_11.Configuration.PrometheusConfiguration;
+import com.teragrep.rlp_11.Configuration.TargetConfiguration;
+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.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+public class ConnectionTest {
+
+ private final int serverPort = 12345;
+ private Thread eventLoopThread;
+ private EventLoop eventLoop;
+ private ThreadPoolExecutor threadPoolExecutor;
+ private final List records = new ArrayList<>();
+ private Server server;
+
+ @BeforeEach
+ public void startServer() {
+ EventLoopFactory eventLoopFactory = new EventLoopFactory();
+ eventLoop = Assertions.assertDoesNotThrow(eventLoopFactory::create);
+
+ eventLoopThread = new Thread(eventLoop);
+ eventLoopThread.start();
+
+ 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,
+ 1,
+ Long.MAX_VALUE,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>()
+ );
+ ServerFactory serverFactory = new ServerFactory(
+ eventLoop,
+ threadPoolExecutor,
+ new PlainFactory(),
+ new FrameDelegationClockFactory(frameDelegateSupplier)
+ );
+ server = Assertions.assertDoesNotThrow(() -> serverFactory.create(serverPort));
+ }
+
+ @AfterEach
+ public void stopServer() {
+ eventLoop.stop();
+ threadPoolExecutor.shutdown();
+ Assertions.assertDoesNotThrow(() -> eventLoopThread.join());
+ Assertions.assertDoesNotThrow(server::close);
+ records.clear();
+ }
+
+ @Test
+ public void connectToServerTest() {
+ Map map = Assertions
+ .assertDoesNotThrow(() -> new PathConfiguration("src/test/resources/connectiontest.properties").asMap());
+ final PrometheusConfiguration prometheusConfiguration = new PrometheusConfiguration(map);
+ final ProbeConfiguration probeConfiguration = new ProbeConfiguration(map);
+ final RecordFactory recordFactory = new RecordFactory("localhost", "rlp_11", "rlp_11");
+ final TargetConfiguration targetConfiguration = new TargetConfiguration(map);
+ final MetricsConfiguration metricsConfiguration = new MetricsConfiguration(map);
+
+ RelpProbe relpProbe = new RelpProbe(
+ targetConfiguration,
+ probeConfiguration,
+ prometheusConfiguration,
+ metricsConfiguration,
+ recordFactory
+ );
+
+ TimerTask task = new TimerTask() {
+
+ public void run() {
+ relpProbe.stop();
+ }
+ };
+ Timer timer = new Timer("Timer");
+ timer.schedule(task, 5_000L);
+
+ relpProbe.start();
+ }
+}
diff --git a/src/test/resources/connectiontest.properties b/src/test/resources/connectiontest.properties
new file mode 100644
index 0000000..079c639
--- /dev/null
+++ b/src/test/resources/connectiontest.properties
@@ -0,0 +1,22 @@
+# Metrics reporting name. Arbitrary string, only used for reporting purposes
+metrics.name=target
+# Metrics window size
+metrics.window=10000
+
+# Delay between sending events, in milliseconds
+probe.interval=1000
+
+# Prometheus endpoint port
+prometheus.port=8080
+
+# Appname used in RELP record
+record.appname=rlp_11
+# Hostname used in RELP record
+record.hostname=rlp_11
+
+# RELP Server target address
+target.hostname=127.0.0.1
+# Relp Server target port
+target.port=12345
+# RELP Server reconnect interval
+target.reconnectinterval=1000
diff --git a/src/test/resources/missing.properties b/src/test/resources/missing.properties
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/test/resources/missing.properties
@@ -0,0 +1 @@
+