From 0fb799193ec55b4e7a55a1713aba325b013e1028 Mon Sep 17 00:00:00 2001 From: Jochen Schalanda Date: Thu, 14 Dec 2023 13:21:46 +0100 Subject: [PATCH] Remove dependency on Hamcrest (#3851) --- metrics-core/pom.xml | 6 -- .../SlidingTimeWindowMovingAveragesTest.java | 84 +++++++++---------- metrics-ehcache/pom.xml | 6 -- ...InstrumentedCacheDecoratorFactoryTest.java | 8 +- metrics-httpclient/pom.xml | 6 -- .../HttpClientMetricNameStrategiesTest.java | 55 ++++++------ metrics-httpclient5/pom.xml | 6 -- .../HttpClientMetricNameStrategiesTest.java | 38 ++++----- pom.xml | 1 - 9 files changed, 86 insertions(+), 124 deletions(-) diff --git a/metrics-core/pom.xml b/metrics-core/pom.xml index 88d6e9c122..e5bc687301 100644 --- a/metrics-core/pom.xml +++ b/metrics-core/pom.xml @@ -42,12 +42,6 @@ ${junit.version} test - - org.hamcrest - hamcrest-core - ${hamcrest.version} - test - org.assertj assertj-core diff --git a/metrics-core/src/test/java/com/codahale/metrics/SlidingTimeWindowMovingAveragesTest.java b/metrics-core/src/test/java/com/codahale/metrics/SlidingTimeWindowMovingAveragesTest.java index 924d5d7369..878b36f682 100644 --- a/metrics-core/src/test/java/com/codahale/metrics/SlidingTimeWindowMovingAveragesTest.java +++ b/metrics-core/src/test/java/com/codahale/metrics/SlidingTimeWindowMovingAveragesTest.java @@ -1,14 +1,12 @@ package com.codahale.metrics; -import static com.codahale.metrics.SlidingTimeWindowMovingAverages.NUMBER_OF_BUCKETS; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.MatcherAssert.assertThat; +import org.junit.Before; +import org.junit.Test; import java.time.Instant; -import org.junit.Before; -import org.junit.Test; +import static com.codahale.metrics.SlidingTimeWindowMovingAverages.NUMBER_OF_BUCKETS; +import static org.assertj.core.api.Assertions.assertThat; public class SlidingTimeWindowMovingAveragesTest { @@ -28,16 +26,16 @@ public void normalizeIndex() { SlidingTimeWindowMovingAverages stwm = new SlidingTimeWindowMovingAverages(); - assertThat(stwm.normalizeIndex(0), is(0)); - assertThat(stwm.normalizeIndex(900), is(0)); - assertThat(stwm.normalizeIndex(9000), is(0)); - assertThat(stwm.normalizeIndex(-900), is(0)); + assertThat(stwm.normalizeIndex(0)).isEqualTo(0); + assertThat(stwm.normalizeIndex(900)).isEqualTo(0); + assertThat(stwm.normalizeIndex(9000)).isEqualTo(0); + assertThat(stwm.normalizeIndex(-900)).isEqualTo(0); - assertThat(stwm.normalizeIndex(1), is(1)); + assertThat(stwm.normalizeIndex(1)).isEqualTo(1); - assertThat(stwm.normalizeIndex(899), is(899)); - assertThat(stwm.normalizeIndex(-1), is(899)); - assertThat(stwm.normalizeIndex(-901), is(899)); + assertThat(stwm.normalizeIndex(899)).isEqualTo(899); + assertThat(stwm.normalizeIndex(-1)).isEqualTo(899); + assertThat(stwm.normalizeIndex(-901)).isEqualTo(899); } @Test @@ -45,8 +43,8 @@ public void calculateIndexOfTick() { SlidingTimeWindowMovingAverages stwm = new SlidingTimeWindowMovingAverages(clock); - assertThat(stwm.calculateIndexOfTick(Instant.ofEpochSecond(0L)), is(0)); - assertThat(stwm.calculateIndexOfTick(Instant.ofEpochSecond(1L)), is(1)); + assertThat(stwm.calculateIndexOfTick(Instant.ofEpochSecond(0L))).isEqualTo(0); + assertThat(stwm.calculateIndexOfTick(Instant.ofEpochSecond(1L))).isEqualTo(1); } @Test @@ -63,11 +61,11 @@ public void mark_max_without_cleanup() { } // verify that no cleanup happened yet - assertThat(movingAverages.oldestBucketTime, is(Instant.ofEpochSecond(0L))); + assertThat(movingAverages.oldestBucketTime).isEqualTo(Instant.ofEpochSecond(0L)); - assertThat(meter.getOneMinuteRate(), is(60.0)); - assertThat(meter.getFiveMinuteRate(), is(300.0)); - assertThat(meter.getFifteenMinuteRate(), is(900.0)); + assertThat(meter.getOneMinuteRate()).isEqualTo(60.0); + assertThat(meter.getFiveMinuteRate()).isEqualTo(300.0); + assertThat(meter.getFifteenMinuteRate()).isEqualTo(900.0); } @Test @@ -84,11 +82,11 @@ public void mark_first_cleanup() { } // verify that at least one cleanup happened - assertThat(movingAverages.oldestBucketTime, not(is(Instant.ofEpochSecond(0L)))); + assertThat(movingAverages.oldestBucketTime).isNotEqualTo(Instant.EPOCH); - assertThat(meter.getOneMinuteRate(), is(60.0)); - assertThat(meter.getFiveMinuteRate(), is(300.0)); - assertThat(meter.getFifteenMinuteRate(), is(900.0)); + assertThat(meter.getOneMinuteRate()).isEqualTo(60.0); + assertThat(meter.getFiveMinuteRate()).isEqualTo(300.0); + assertThat(meter.getFifteenMinuteRate()).isEqualTo(900.0); } @Test @@ -102,10 +100,10 @@ public void mark_10_values() { meter.mark(); } - assertThat(meter.getCount(), is(10L)); - assertThat(meter.getOneMinuteRate(), is(10.0)); - assertThat(meter.getFiveMinuteRate(), is(10.0)); - assertThat(meter.getFifteenMinuteRate(), is(10.0)); + assertThat(meter.getCount()).isEqualTo(10L); + assertThat(meter.getOneMinuteRate()).isEqualTo(10.0); + assertThat(meter.getFiveMinuteRate()).isEqualTo(10.0); + assertThat(meter.getFifteenMinuteRate()).isEqualTo(10.0); } @Test @@ -117,9 +115,9 @@ public void mark_1000_values() { } // only 60/300/900 of the 1000 events took place in the last 1/5/15 minute(s) - assertThat(meter.getOneMinuteRate(), is(60.0)); - assertThat(meter.getFiveMinuteRate(), is(300.0)); - assertThat(meter.getFifteenMinuteRate(), is(900.0)); + assertThat(meter.getOneMinuteRate()).isEqualTo(60.0); + assertThat(meter.getFiveMinuteRate()).isEqualTo(300.0); + assertThat(meter.getFifteenMinuteRate()).isEqualTo(900.0); } @Test @@ -129,9 +127,9 @@ public void cleanup_pause_shorter_than_window() { // no mark for three minutes clock.addSeconds(180); - assertThat(meter.getOneMinuteRate(), is(0.0)); - assertThat(meter.getFiveMinuteRate(), is(10.0)); - assertThat(meter.getFifteenMinuteRate(), is(10.0)); + assertThat(meter.getOneMinuteRate()).isEqualTo(0.0); + assertThat(meter.getFiveMinuteRate()).isEqualTo(10.0); + assertThat(meter.getFifteenMinuteRate()).isEqualTo(10.0); } @Test @@ -143,15 +141,15 @@ public void cleanup_window_wrap_around() { // and query at 15:30 minutes (the bucket index must have wrapped around) clock.addSeconds(50); - assertThat(meter.getOneMinuteRate(), is(10.0)); - assertThat(meter.getFiveMinuteRate(), is(10.0)); - assertThat(meter.getFifteenMinuteRate(), is(10.0)); + assertThat(meter.getOneMinuteRate()).isEqualTo(10.0); + assertThat(meter.getFiveMinuteRate()).isEqualTo(10.0); + assertThat(meter.getFifteenMinuteRate()).isEqualTo(10.0); // and query at 30:10 minutes (the bucket index must have wrapped around for the second time) clock.addSeconds(880); - assertThat(meter.getOneMinuteRate(), is(0.0)); - assertThat(meter.getFiveMinuteRate(), is(0.0)); - assertThat(meter.getFifteenMinuteRate(), is(0.0)); + assertThat(meter.getOneMinuteRate()).isEqualTo(0.0); + assertThat(meter.getFiveMinuteRate()).isEqualTo(0.0); + assertThat(meter.getFifteenMinuteRate()).isEqualTo(0.0); } @Test @@ -161,8 +159,8 @@ public void cleanup_pause_longer_than_two_windows() { // after forty minutes all rates should be zero clock.addSeconds(2400); - assertThat(meter.getOneMinuteRate(), is(0.0)); - assertThat(meter.getFiveMinuteRate(), is(0.0)); - assertThat(meter.getFifteenMinuteRate(), is(0.0)); + assertThat(meter.getOneMinuteRate()).isEqualTo(0.0); + assertThat(meter.getFiveMinuteRate()).isEqualTo(0.0); + assertThat(meter.getFifteenMinuteRate()).isEqualTo(0.0); } } \ No newline at end of file diff --git a/metrics-ehcache/pom.xml b/metrics-ehcache/pom.xml index cc3bd2c2a9..36b24b9ff8 100644 --- a/metrics-ehcache/pom.xml +++ b/metrics-ehcache/pom.xml @@ -54,12 +54,6 @@ ${junit.version} test - - org.hamcrest - hamcrest-core - ${hamcrest.version} - test - org.assertj assertj-core diff --git a/metrics-ehcache/src/test/java/com/codahale/metrics/ehcache/InstrumentedCacheDecoratorFactoryTest.java b/metrics-ehcache/src/test/java/com/codahale/metrics/ehcache/InstrumentedCacheDecoratorFactoryTest.java index 13cd82eff9..c9177e0740 100644 --- a/metrics-ehcache/src/test/java/com/codahale/metrics/ehcache/InstrumentedCacheDecoratorFactoryTest.java +++ b/metrics-ehcache/src/test/java/com/codahale/metrics/ehcache/InstrumentedCacheDecoratorFactoryTest.java @@ -6,14 +6,12 @@ import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; -import org.hamcrest.CoreMatchers; import org.junit.Before; import org.junit.Test; import static com.codahale.metrics.MetricRegistry.name; +import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assume.assumeThat; public class InstrumentedCacheDecoratorFactoryTest { private static final CacheManager MANAGER = CacheManager.create(); @@ -23,9 +21,7 @@ public class InstrumentedCacheDecoratorFactoryTest { @Before public void setUp() { - this.cache = MANAGER.getEhcache("test-config"); - assumeThat(cache, is(CoreMatchers.notNullValue())); - + this.cache = requireNonNull(MANAGER.getEhcache("test-config")); this.registry = SharedMetricRegistries.getOrCreate("cache-metrics"); } diff --git a/metrics-httpclient/pom.xml b/metrics-httpclient/pom.xml index 05f1845c5c..22f609a03b 100644 --- a/metrics-httpclient/pom.xml +++ b/metrics-httpclient/pom.xml @@ -63,12 +63,6 @@ ${junit.version} test - - org.hamcrest - hamcrest-core - ${hamcrest.version} - test - org.assertj assertj-core diff --git a/metrics-httpclient/src/test/java/com/codahale/metrics/httpclient/HttpClientMetricNameStrategiesTest.java b/metrics-httpclient/src/test/java/com/codahale/metrics/httpclient/HttpClientMetricNameStrategiesTest.java index f58d47024b..5015b757d0 100644 --- a/metrics-httpclient/src/test/java/com/codahale/metrics/httpclient/HttpClientMetricNameStrategiesTest.java +++ b/metrics-httpclient/src/test/java/com/codahale/metrics/httpclient/HttpClientMetricNameStrategiesTest.java @@ -15,97 +15,94 @@ import static com.codahale.metrics.httpclient.HttpClientMetricNameStrategies.METHOD_ONLY; import static com.codahale.metrics.httpclient.HttpClientMetricNameStrategies.PATH_AND_METHOD; import static com.codahale.metrics.httpclient.HttpClientMetricNameStrategies.QUERYLESS_URL_AND_METHOD; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class HttpClientMetricNameStrategiesTest { @Test public void methodOnlyWithName() { - assertThat(METHOD_ONLY.getNameFor("some-service", new HttpGet("/whatever")), - is("org.apache.http.client.HttpClient.some-service.get-requests")); + assertThat(METHOD_ONLY.getNameFor("some-service", new HttpGet("/whatever"))) + .isEqualTo("org.apache.http.client.HttpClient.some-service.get-requests"); } @Test public void methodOnlyWithoutName() { - assertThat(METHOD_ONLY.getNameFor(null, new HttpGet("/whatever")), - is("org.apache.http.client.HttpClient.get-requests")); + assertThat(METHOD_ONLY.getNameFor(null, new HttpGet("/whatever"))) + .isEqualTo("org.apache.http.client.HttpClient.get-requests"); } @Test public void hostAndMethodWithName() { - assertThat(HOST_AND_METHOD.getNameFor("some-service", new HttpPost("http://my.host.com/whatever")), - is("org.apache.http.client.HttpClient.some-service.my.host.com.post-requests")); + assertThat(HOST_AND_METHOD.getNameFor("some-service", new HttpPost("http://my.host.com/whatever"))) + .isEqualTo("org.apache.http.client.HttpClient.some-service.my.host.com.post-requests"); } @Test public void hostAndMethodWithoutName() { - assertThat(HOST_AND_METHOD.getNameFor(null, new HttpPost("http://my.host.com/whatever")), - is("org.apache.http.client.HttpClient.my.host.com.post-requests")); + assertThat(HOST_AND_METHOD.getNameFor(null, new HttpPost("http://my.host.com/whatever"))) + .isEqualTo("org.apache.http.client.HttpClient.my.host.com.post-requests"); } @Test public void hostAndMethodWithNameInWrappedRequest() throws URISyntaxException { HttpRequest request = rewriteRequestURI(new HttpPost("http://my.host.com/whatever")); - assertThat(HOST_AND_METHOD.getNameFor("some-service", request), - is("org.apache.http.client.HttpClient.some-service.my.host.com.post-requests")); + assertThat(HOST_AND_METHOD.getNameFor("some-service", request)) + .isEqualTo("org.apache.http.client.HttpClient.some-service.my.host.com.post-requests"); } @Test public void hostAndMethodWithoutNameInWrappedRequest() throws URISyntaxException { HttpRequest request = rewriteRequestURI(new HttpPost("http://my.host.com/whatever")); - assertThat(HOST_AND_METHOD.getNameFor(null, request), - is("org.apache.http.client.HttpClient.my.host.com.post-requests")); + assertThat(HOST_AND_METHOD.getNameFor(null, request)) + .isEqualTo("org.apache.http.client.HttpClient.my.host.com.post-requests"); } @Test public void pathAndMethodWithName() { - assertThat(PATH_AND_METHOD.getNameFor("some-service", new HttpPost("http://my.host.com/whatever/happens")), - is("org.apache.http.client.HttpClient.some-service./whatever/happens.post-requests")); + assertThat(PATH_AND_METHOD.getNameFor("some-service", new HttpPost("http://my.host.com/whatever/happens"))) + .isEqualTo("org.apache.http.client.HttpClient.some-service./whatever/happens.post-requests"); } @Test public void pathAndMethodWithoutName() { - assertThat(PATH_AND_METHOD.getNameFor(null, new HttpPost("http://my.host.com/whatever/happens")), - is("org.apache.http.client.HttpClient./whatever/happens.post-requests")); + assertThat(PATH_AND_METHOD.getNameFor(null, new HttpPost("http://my.host.com/whatever/happens"))) + .isEqualTo("org.apache.http.client.HttpClient./whatever/happens.post-requests"); } @Test public void pathAndMethodWithNameInWrappedRequest() throws URISyntaxException { HttpRequest request = rewriteRequestURI(new HttpPost("http://my.host.com/whatever/happens")); - assertThat(PATH_AND_METHOD.getNameFor("some-service", request), - is("org.apache.http.client.HttpClient.some-service./whatever/happens.post-requests")); + assertThat(PATH_AND_METHOD.getNameFor("some-service", request)) + .isEqualTo("org.apache.http.client.HttpClient.some-service./whatever/happens.post-requests"); } @Test public void pathAndMethodWithoutNameInWrappedRequest() throws URISyntaxException { HttpRequest request = rewriteRequestURI(new HttpPost("http://my.host.com/whatever/happens")); - assertThat(PATH_AND_METHOD.getNameFor(null, request), - is("org.apache.http.client.HttpClient./whatever/happens.post-requests")); + assertThat(PATH_AND_METHOD.getNameFor(null, request)) + .isEqualTo("org.apache.http.client.HttpClient./whatever/happens.post-requests"); } @Test public void querylessUrlAndMethodWithName() { assertThat(QUERYLESS_URL_AND_METHOD.getNameFor( "some-service", - new HttpPut("https://thing.com:8090/my/path?ignore=this&and=this")), - is("org.apache.http.client.HttpClient.some-service.https://thing.com:8090/my/path.put-requests")); + new HttpPut("https://thing.com:8090/my/path?ignore=this&and=this"))) + .isEqualTo("org.apache.http.client.HttpClient.some-service.https://thing.com:8090/my/path.put-requests"); } @Test public void querylessUrlAndMethodWithNameInWrappedRequest() throws URISyntaxException { HttpRequest request = rewriteRequestURI(new HttpPut("https://thing.com:8090/my/path?ignore=this&and=this")); - assertThat(QUERYLESS_URL_AND_METHOD.getNameFor( - "some-service", - request), - is("org.apache.http.client.HttpClient.some-service.https://thing.com:8090/my/path.put-requests")); + assertThat(QUERYLESS_URL_AND_METHOD.getNameFor("some-service", request)) + .isEqualTo("org.apache.http.client.HttpClient.some-service.https://thing.com:8090/my/path.put-requests"); } private static HttpRequest rewriteRequestURI(HttpRequest request) throws URISyntaxException { HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(request); - URI uri = URIUtils.rewriteURI(wrapper.getURI(), null, true); + URI uri = URIUtils.rewriteURI(wrapper.getURI(), null, URIUtils.DROP_FRAGMENT); wrapper.setURI(uri); return wrapper; diff --git a/metrics-httpclient5/pom.xml b/metrics-httpclient5/pom.xml index e3d4b336c5..e1841018cd 100644 --- a/metrics-httpclient5/pom.xml +++ b/metrics-httpclient5/pom.xml @@ -73,12 +73,6 @@ ${junit.version} test - - org.hamcrest - hamcrest-core - ${hamcrest.version} - test - org.assertj assertj-core diff --git a/metrics-httpclient5/src/test/java/com/codahale/metrics/httpclient5/HttpClientMetricNameStrategiesTest.java b/metrics-httpclient5/src/test/java/com/codahale/metrics/httpclient5/HttpClientMetricNameStrategiesTest.java index 04954c8260..25fa771a1c 100644 --- a/metrics-httpclient5/src/test/java/com/codahale/metrics/httpclient5/HttpClientMetricNameStrategiesTest.java +++ b/metrics-httpclient5/src/test/java/com/codahale/metrics/httpclient5/HttpClientMetricNameStrategiesTest.java @@ -14,66 +14,62 @@ import static com.codahale.metrics.httpclient5.HttpClientMetricNameStrategies.HOST_AND_METHOD; import static com.codahale.metrics.httpclient5.HttpClientMetricNameStrategies.METHOD_ONLY; import static com.codahale.metrics.httpclient5.HttpClientMetricNameStrategies.QUERYLESS_URL_AND_METHOD; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class HttpClientMetricNameStrategiesTest { @Test public void methodOnlyWithName() { - assertThat(METHOD_ONLY.getNameFor("some-service", new HttpGet("/whatever")), - is("org.apache.hc.client5.http.classic.HttpClient.some-service.get-requests")); + assertThat(METHOD_ONLY.getNameFor("some-service", new HttpGet("/whatever"))) + .isEqualTo("org.apache.hc.client5.http.classic.HttpClient.some-service.get-requests"); } @Test public void methodOnlyWithoutName() { - assertThat(METHOD_ONLY.getNameFor(null, new HttpGet("/whatever")), - is("org.apache.hc.client5.http.classic.HttpClient.get-requests")); + assertThat(METHOD_ONLY.getNameFor(null, new HttpGet("/whatever"))) + .isEqualTo("org.apache.hc.client5.http.classic.HttpClient.get-requests"); } @Test public void hostAndMethodWithName() { - assertThat(HOST_AND_METHOD.getNameFor("some-service", new HttpPost("http://my.host.com/whatever")), - is("org.apache.hc.client5.http.classic.HttpClient.some-service.my.host.com.post-requests")); + assertThat(HOST_AND_METHOD.getNameFor("some-service", new HttpPost("http://my.host.com/whatever"))) + .isEqualTo("org.apache.hc.client5.http.classic.HttpClient.some-service.my.host.com.post-requests"); } @Test public void hostAndMethodWithoutName() { - assertThat(HOST_AND_METHOD.getNameFor(null, new HttpPost("http://my.host.com/whatever")), - is("org.apache.hc.client5.http.classic.HttpClient.my.host.com.post-requests")); + assertThat(HOST_AND_METHOD.getNameFor(null, new HttpPost("http://my.host.com/whatever"))) + .isEqualTo("org.apache.hc.client5.http.classic.HttpClient.my.host.com.post-requests"); } @Test public void hostAndMethodWithNameInWrappedRequest() throws URISyntaxException { HttpRequest request = rewriteRequestURI(new HttpPost("http://my.host.com/whatever")); - assertThat(HOST_AND_METHOD.getNameFor("some-service", request), - is("org.apache.hc.client5.http.classic.HttpClient.some-service.my.host.com.post-requests")); + assertThat(HOST_AND_METHOD.getNameFor("some-service", request)) + .isEqualTo("org.apache.hc.client5.http.classic.HttpClient.some-service.my.host.com.post-requests"); } @Test public void hostAndMethodWithoutNameInWrappedRequest() throws URISyntaxException { HttpRequest request = rewriteRequestURI(new HttpPost("http://my.host.com/whatever")); - assertThat(HOST_AND_METHOD.getNameFor(null, request), - is("org.apache.hc.client5.http.classic.HttpClient.my.host.com.post-requests")); + assertThat(HOST_AND_METHOD.getNameFor(null, request)) + .isEqualTo("org.apache.hc.client5.http.classic.HttpClient.my.host.com.post-requests"); } @Test public void querylessUrlAndMethodWithName() { assertThat(QUERYLESS_URL_AND_METHOD.getNameFor( - "some-service", - new HttpPut("https://thing.com:8090/my/path?ignore=this&and=this")), - is("org.apache.hc.client5.http.classic.HttpClient.some-service.https://thing.com:8090/my/path.put-requests")); + "some-service", new HttpPut("https://thing.com:8090/my/path?ignore=this&and=this"))) + .isEqualTo("org.apache.hc.client5.http.classic.HttpClient.some-service.https://thing.com:8090/my/path.put-requests"); } @Test public void querylessUrlAndMethodWithNameInWrappedRequest() throws URISyntaxException { HttpRequest request = rewriteRequestURI(new HttpPut("https://thing.com:8090/my/path?ignore=this&and=this")); - assertThat(QUERYLESS_URL_AND_METHOD.getNameFor( - "some-service", - request), - is("org.apache.hc.client5.http.classic.HttpClient.some-service.https://thing.com:8090/my/path.put-requests")); + assertThat(QUERYLESS_URL_AND_METHOD.getNameFor("some-service", request)) + .isEqualTo("org.apache.hc.client5.http.classic.HttpClient.some-service.https://thing.com:8090/my/path.put-requests"); } private static HttpRequest rewriteRequestURI(HttpRequest request) throws URISyntaxException { diff --git a/pom.xml b/pom.xml index 95cc30f0aa..c56a59cfab 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,6 @@ 1.14.10 5.8.0 4.13.1 - 1.3 3.14.0 3.11.0 2.23.0