From e4313f4c06a53684e9d3bd59d072d69f9663b21a Mon Sep 17 00:00:00 2001 From: Dudi Edri Date: Thu, 2 Feb 2023 13:52:34 +0200 Subject: [PATCH] Add Protection against Epoch Transition null values received from Koios Instances. Bump version to 1.16.3 --- README.md | 6 +-- pom.xml | 2 +- .../api/epoch/impl/EpochServiceImpl.java | 41 +++++++++---------- .../backend/api/base/BaseServiceTest.java | 1 + .../koios/client/utils/Bech32UtilTest.java | 26 +++++++++--- 5 files changed, 45 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 2692891..b72f962 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ Resource and maintenance requirements for Cardano blockchain components (e.g. ca | Koios Instance | Koios Java Client | |:--------------:|:-----------------:| -| 1.0.9 | 1.16.2 | +| 1.0.9 | 1.16.3 | | 1.0.8 | 1.15.2 | | 1.0.7 | 1.14.1 | | 1.0.6 | 1.13 | @@ -281,13 +281,13 @@ Resource and maintenance requirements for Cardano blockchain components (e.g. ca io.github.cardano-community koios-java-client - 1.16.2 + 1.16.3 ``` - For Gradle, add the following dependency to build.gradle ``` -compile group: 'io.github.cardano-community', name: 'koios-java-client', version: '1.16.2' +compile group: 'io.github.cardano-community', name: 'koios-java-client', version: '1.16.3' ``` ### Get Koios Backend Service diff --git a/pom.xml b/pom.xml index a85c625..9fd7b35 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 io.github.cardano-community koios-java-client - 1.16.2 + 1.16.3 ${project.groupId}:${project.artifactId} Koios Java Client is a Java REST Client library which allows interacting with Koios Server Instances using Java Objects https://github.com/cardano-community/koios-java-client diff --git a/src/main/java/rest/koios/client/backend/api/epoch/impl/EpochServiceImpl.java b/src/main/java/rest/koios/client/backend/api/epoch/impl/EpochServiceImpl.java index 846ac06..8546791 100644 --- a/src/main/java/rest/koios/client/backend/api/epoch/impl/EpochServiceImpl.java +++ b/src/main/java/rest/koios/client/backend/api/epoch/impl/EpochServiceImpl.java @@ -39,20 +39,7 @@ public EpochServiceImpl(BaseService baseService) { @Override public Result getLatestEpochInfo() throws ApiException { - Integer epochNo; - Call> tipCall = networkApi.getChainTip(); - try { - Response> tipResponse = (Response) execute(tipCall); - Result tipResult = processResponseGetOne(tipResponse); - if (tipResult.isSuccessful() && tipResult.getValue() != null && tipResult.getValue().getEpochNo() != null) { - epochNo = tipResult.getValue().getEpochNo(); - } else { - throw new ApiException("Missing EpochNo Value from Tip Response: "+tipResult); - } - } catch (IOException e) { - throw new ApiException(e.getMessage(), e); - } - return getEpochInformationByEpoch(epochNo); + return getEpochInformationByEpoch(getEpochNoFromTip()); } @Override @@ -80,14 +67,7 @@ public Result> getEpochInformation(Options options) throws ApiEx @Override public Result getLatestEpochParameters() throws ApiException { - Options options = Options.builder().option(Limit.of(1)).build(); - Call> call = epochApi.getEpochParameters(optionsToParamMap(options)); - try { - Response> response = (Response) execute(call); - return processResponseGetOne(response); - } catch (IOException e) { - throw new ApiException(e.getMessage(), e); - } + return getEpochParametersByEpoch(getEpochNoFromTip()); } @Override @@ -135,4 +115,21 @@ public Result> getEpochBlockProtocols(Options options) throw new ApiException(e.getMessage(), e); } } + + private Integer getEpochNoFromTip() throws ApiException { + Integer epochNo; + Call> tipCall = networkApi.getChainTip(); + try { + Response> tipResponse = (Response) execute(tipCall); + Result tipResult = processResponseGetOne(tipResponse); + if (tipResult.isSuccessful() && tipResult.getValue() != null && tipResult.getValue().getEpochNo() != null) { + epochNo = tipResult.getValue().getEpochNo(); + } else { + throw new ApiException("Missing EpochNo Value from Tip Response: "+tipResult); + } + } catch (IOException e) { + throw new ApiException(e.getMessage(), e); + } + return epochNo; + } } diff --git a/src/test/java/rest/koios/client/backend/api/base/BaseServiceTest.java b/src/test/java/rest/koios/client/backend/api/base/BaseServiceTest.java index 6d0c5c1..6f8fbba 100644 --- a/src/test/java/rest/koios/client/backend/api/base/BaseServiceTest.java +++ b/src/test/java/rest/koios/client/backend/api/base/BaseServiceTest.java @@ -18,6 +18,7 @@ void validateHexFormatTest() { Assertions.assertDoesNotThrow(() -> baseService.validateHexFormat("")); Assertions.assertDoesNotThrow(() -> baseService.validateHexFormat("0123456789abcdef")); Assertions.assertThrows(ApiException.class, () -> baseService.validateHexFormat("asdf")); + Assertions.assertThrows(NullPointerException.class, () -> baseService.validateHexFormat(null)); } @Test diff --git a/src/test/java/rest/koios/client/utils/Bech32UtilTest.java b/src/test/java/rest/koios/client/utils/Bech32UtilTest.java index 4e5b54a..a747a2c 100644 --- a/src/test/java/rest/koios/client/utils/Bech32UtilTest.java +++ b/src/test/java/rest/koios/client/utils/Bech32UtilTest.java @@ -1,18 +1,34 @@ package rest.koios.client.utils; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; + +import static org.junit.jupiter.api.Assertions.*; + class Bech32UtilTest { @Test void invalidCharsTest() { - Assertions.assertFalse(Bech32Util.hasValidChars(null)); + assertFalse(Bech32Util.hasValidChars(null)); - Assertions.assertFalse(Bech32Util.hasValidChars("")); + assertFalse(Bech32Util.hasValidChars("")); - Assertions.assertFalse(Bech32Util.hasValidChars("IQoJb3JpZ2luX2VjEJP//////////wEaCXVzLWVhc3QtMSJGMEQCIFEdcXP1FbfLBZSp1OCWP6eB6pofyWx/plHVZe4BSuUEAiAKVZYe5340wvB5uDvg/K1SbBJzvEBEyZLPDMZvlb+hjCr4AQjr//////////8BEAAaDDA1NjYxMjc1NDY1OCIMxtO9x0MsdST4bqy0KswBXPQZkMVN6+NRKkhvhkBsKnkrFn43TBFbwNJPRD0y4j2Ov1dikgpzzWGK+gff4pDec6e/vhcK0rZtQ3X7J7Id6NyoKrrt+XAzXdg8s7DWzMw6FkN0yaGIhvtqQATIkt+X5rKm0M9wwS+eNjurTQlqJdYjm94MuVCGWiQ1/xD/ZM2ECKfAV8FcnKLI+scT/kfP+weCQy1+iv8v8caS+uE8LclFINf4UOcBl4fF80vlU8qmXPVQjxXV/j9GqIwJ1+F08gEe2XbiYfHe/+g+MOXC8pAGOpkBeHgMzPDkljTJ244SO/vk1BGNNBrJeBZKLLTPsH/bynI2QSQlZcq8zreLh4GoalS+0QSRcsvPhCainLeZkxOqsK1+kfUBJpe3TW6lGLaqc8DIqUBMkhCwCbSDKWMe/o2RmlzLKZSSeJ/gABoNulUXxPpkfIBemCYi377DD5szO6dWAcLdny1FK2cZqVtRNDwh7XLpunvhMsiA")); + assertFalse(Bech32Util.hasValidChars("IQoJb3JpZ2luX2VjEJP//////////wEaCXVzLWVhc3QtMSJGMEQCIFEdcXP1FbfLBZSp1OCWP6eB6pofyWx/plHVZe4BSuUEAiAKVZYe5340wvB5uDvg/K1SbBJzvEBEyZLPDMZvlb+hjCr4AQjr//////////8BEAAaDDA1NjYxMjc1NDY1OCIMxtO9x0MsdST4bqy0KswBXPQZkMVN6+NRKkhvhkBsKnkrFn43TBFbwNJPRD0y4j2Ov1dikgpzzWGK+gff4pDec6e/vhcK0rZtQ3X7J7Id6NyoKrrt+XAzXdg8s7DWzMw6FkN0yaGIhvtqQATIkt+X5rKm0M9wwS+eNjurTQlqJdYjm94MuVCGWiQ1/xD/ZM2ECKfAV8FcnKLI+scT/kfP+weCQy1+iv8v8caS+uE8LclFINf4UOcBl4fF80vlU8qmXPVQjxXV/j9GqIwJ1+F08gEe2XbiYfHe/+g+MOXC8pAGOpkBeHgMzPDkljTJ244SO/vk1BGNNBrJeBZKLLTPsH/bynI2QSQlZcq8zreLh4GoalS+0QSRcsvPhCainLeZkxOqsK1+kfUBJpe3TW6lGLaqc8DIqUBMkhCwCbSDKWMe/o2RmlzLKZSSeJ/gABoNulUXxPpkfIBemCYi377DD5szO6dWAcLdny1FK2cZqVtRNDwh7XLpunvhMsiA")); - Assertions.assertFalse(Bech32Util.hasValidChars("pooL1rcsezjrma577f06yp40lsz76uvwh7gne35afx3zrq2ktx50f8t8")); + assertFalse(Bech32Util.hasValidChars("pooL1rcsezjrma577f06yp40lsz76uvwh7gne35afx3zrq2ktx50f8t8")); + } + + @Test + void testConstructorIsPrivate() throws NoSuchMethodException { + Constructor constructor = Bech32Util.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + InvocationTargetException exception = assertThrows(InvocationTargetException.class, constructor::newInstance); + assertInstanceOf(InvocationTargetException.class, exception); + assertInstanceOf(IllegalStateException.class, exception.getCause()); + assertEquals("Utility Class", exception.getCause().getMessage()); } }