From 160f5077678b7a8ae2559f4dc88469d81eccc17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20K=C3=B6rber?= Date: Fri, 19 May 2023 12:21:46 +0200 Subject: [PATCH] Add method to get optional resource URL --- .../java/org/shredzone/acme4j/Session.java | 32 +++++++++++++------ .../org/shredzone/acme4j/AccountTest.java | 13 +++++--- .../org/shredzone/acme4j/SessionTest.java | 12 ++++++- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Session.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Session.java index f7e065d4..49a54b4e 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Session.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Session.java @@ -13,6 +13,8 @@ */ package org.shredzone.acme4j; +import static java.util.Objects.requireNonNull; + import java.net.URI; import java.net.URL; import java.security.KeyPair; @@ -20,7 +22,7 @@ import java.time.ZonedDateTime; import java.util.EnumMap; import java.util.Locale; import java.util.Map; -import java.util.Objects; +import java.util.Optional; import java.util.ServiceLoader; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.StreamSupport; @@ -30,6 +32,7 @@ import org.shredzone.acme4j.connector.Connection; import org.shredzone.acme4j.connector.NetworkSettings; import org.shredzone.acme4j.connector.Resource; import org.shredzone.acme4j.exception.AcmeException; +import org.shredzone.acme4j.exception.AcmeNotSupportedException; import org.shredzone.acme4j.provider.AcmeProvider; import org.shredzone.acme4j.provider.GenericAcmeProvider; import org.shredzone.acme4j.toolbox.AcmeUtils; @@ -85,7 +88,7 @@ public class Session { * if no ACME provider was found for the server URI. */ public Session(URI serverUri) { - this.serverUri = Objects.requireNonNull(serverUri, "serverUri"); + this.serverUri = requireNonNull(serverUri, "serverUri"); if (GENERIC_PROVIDER.accepts(serverUri)) { provider = GENERIC_PROVIDER; @@ -116,8 +119,8 @@ public class Session { * @since 2.8 */ public Session(URI serverUri, AcmeProvider provider) { - this.serverUri = Objects.requireNonNull(serverUri, "serverUri"); - this.provider = Objects.requireNonNull(provider, "provider"); + this.serverUri = requireNonNull(serverUri, "serverUri"); + this.provider = requireNonNull(provider, "provider"); if (!provider.accepts(serverUri)) { throw new IllegalArgumentException("Provider does not accept " + serverUri); @@ -230,12 +233,23 @@ public class Session { * if the server does not offer the {@link Resource} */ public URL resourceUrl(Resource resource) throws AcmeException { + return resourceUrlOptional(resource) + .orElseThrow(() -> new AcmeNotSupportedException(resource.path())); + } + + /** + * Gets the {@link URL} of the given {@link Resource}. This may involve connecting to + * the server and fetching the directory. The result is cached. + * + * @param resource + * {@link Resource} to get the {@link URL} of + * @return {@link URL} of the resource, or empty if the resource is not available. + * @since 3.0.0 + */ + public Optional resourceUrlOptional(Resource resource) throws AcmeException { readDirectory(); - var result = resourceMap.get().get(Objects.requireNonNull(resource, "resource")); - if (result == null) { - throw new AcmeException("Server does not offer " + resource.path()); - } - return result; + return Optional.ofNullable(resourceMap.get() + .get(requireNonNull(resource, "resource"))); } /** diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java index b052b0a4..1c2854da 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java @@ -16,7 +16,7 @@ package org.shredzone.acme4j; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.fail; import static org.shredzone.acme4j.toolbox.TestUtils.getJSON; @@ -37,6 +37,7 @@ import org.shredzone.acme4j.challenge.Dns01Challenge; import org.shredzone.acme4j.challenge.Http01Challenge; import org.shredzone.acme4j.connector.Resource; import org.shredzone.acme4j.exception.AcmeException; +import org.shredzone.acme4j.exception.AcmeNotSupportedException; import org.shredzone.acme4j.exception.AcmeServerException; import org.shredzone.acme4j.provider.TestableConnectionProvider; import org.shredzone.acme4j.toolbox.JSON; @@ -273,9 +274,13 @@ public class AccountTest { var login = provider.createLogin(); var account = login.getAccount(); - assertThrows(NullPointerException.class, () -> account.preAuthorizeDomain(null)); - assertThrows(IllegalArgumentException.class, () -> account.preAuthorizeDomain("")); - assertThrows(AcmeException.class, () -> account.preAuthorizeDomain("example.com")); + assertThatNullPointerException() + .isThrownBy(() -> account.preAuthorizeDomain(null)); + assertThatIllegalArgumentException() + .isThrownBy(() -> account.preAuthorizeDomain("")); + assertThatExceptionOfType(AcmeNotSupportedException.class) + .isThrownBy(() -> account.preAuthorizeDomain("example.com")) + .withMessage("Server does not support newAuthz"); provider.close(); } diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/SessionTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/SessionTest.java index cadcd056..e249aba9 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/SessionTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/SessionTest.java @@ -14,6 +14,7 @@ package org.shredzone.acme4j; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.*; import static org.shredzone.acme4j.toolbox.TestUtils.*; @@ -159,7 +160,16 @@ public class SessionTest { assertThat(session.resourceUrl(Resource.NEW_ORDER)) .isEqualTo(new URL("https://example.com/acme/new-order")); - assertThrows(AcmeException.class, () -> session.resourceUrl(Resource.REVOKE_CERT)); + assertThatExceptionOfType(AcmeNotSupportedException.class) + .isThrownBy(() -> session.resourceUrl(Resource.REVOKE_CERT)) + .withMessage("Server does not support revokeCert"); + + assertThat(session.resourceUrlOptional(Resource.NEW_AUTHZ)) + .isNotEmpty() + .contains(new URL("https://example.com/acme/new-authz")); + + assertThat(session.resourceUrlOptional(Resource.REVOKE_CERT)) + .isEmpty(); var meta = session.getMetadata(); try (var softly = new AutoCloseableSoftAssertions()) {