diff --git a/modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java b/modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java index d20b178c..34af9848 100644 --- a/modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java +++ b/modules/testcontainers/src/main/java/org/microshed/testing/testcontainers/ApplicationContainer.java @@ -23,6 +23,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -444,11 +446,25 @@ public void setWaitStrategy(WaitStrategy waitStrategy) { * Configures the application container with the supplied MicroProfile REST Client class that * will reference the supplied {@code hostUrl} * - * @param restClientClass The MicroProfile REST Client class + * @param restClientClass The MicroProfile REST Client interface, which must be annotated with + * @RegisterRestClient * @param hostUrl The URL that the {@code restClientClass} will act as a REST client for + * @throws IllegalArgumentException If the provided restClientClass is not an interface or not + * annotated with @RegisterRestClient + * @throws IllegalArgumentException If hostUrl is not a valid URL * @return the current instance */ public ApplicationContainer withMpRestClient(Class restClientClass, String hostUrl) { + Objects.requireNonNull(restClientClass, "restClientClass must be non-null"); + Objects.requireNonNull(hostUrl, "hostUrl must be non-null"); + if (!restClientClass.isInterface()) { + throw new IllegalArgumentException("Provided restClientClass " + restClientClass.getCanonicalName() + " must be an interface"); + } + try { + new URL(hostUrl); + } catch (MalformedURLException e) { + throw new IllegalArgumentException(e); + } String configToken = readMpRestClientConfigKey(restClientClass); if (configToken == null || configToken.isEmpty()) configToken = restClientClass.getCanonicalName(); @@ -467,9 +483,8 @@ private String readMpRestClientConfigKey(Class restClientClass) { false, getClass().getClassLoader()); } catch (ClassNotFoundException | LinkageError notFound) { - return null; + throw new ExtensionConfigurationException("Unable to load @RegisterRestClient", notFound); } - Method getConfigKey = null; try { getConfigKey = RegisterRestClient.getMethod("configKey"); @@ -479,14 +494,16 @@ private String readMpRestClientConfigKey(Class restClientClass) { } Optional foundAnno = (Optional) AnnotationSupport.findAnnotation(restClientClass, RegisterRestClient); - if (!foundAnno.isPresent()) - return null; + if (!foundAnno.isPresent()) { + throw new IllegalArgumentException("Provided restClientClass " + restClientClass + " must be annotated with " + + RegisterRestClient.getSimpleName()); + } Annotation anno = foundAnno.get(); try { return (String) getConfigKey.invoke(anno); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - return null; + throw new IllegalArgumentException("Unable to obtain configKey from " + anno + " found on " + restClientClass.getCanonicalName()); } } @@ -496,6 +513,7 @@ private String readMpRestClientConfigKey(Class restClientClass) { * * @param restClientClass The MicroProfile REST Client class * @param hostUrl The URL that the {@code restClientClass} will act as a REST client for + * @throws IllegalArgumentException If hostUrl is not a valid URL * @return the current instance */ public ApplicationContainer withMpRestClient(String restClientClass, String hostUrl) { @@ -506,6 +524,11 @@ public ApplicationContainer withMpRestClient(String restClientClass, String host } else { restClientClass += "/mp-rest/url"; } + try { + new URL(hostUrl); + } catch (MalformedURLException e) { + throw new IllegalArgumentException(e); + } return withEnv(restClientClass, hostUrl); } diff --git a/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/ApplicationContainerTest.java b/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/ApplicationContainerTest.java index edeab572..a96b76c6 100644 --- a/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/ApplicationContainerTest.java +++ b/modules/testcontainers/src/test/java/org/microshed/testing/testcontainers/ApplicationContainerTest.java @@ -19,6 +19,7 @@ package org.microshed.testing.testcontainers; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Arrays; import java.util.Map; @@ -31,17 +32,24 @@ public class ApplicationContainerTest { // Base uri configured with: com_example_StringRestClient_mp_rest_url @RegisterRestClient - public static class SampleRestClient1 { + public static interface SampleRestClient1 { } // Base uri configured with: rc_config_key_mp_rest_url @RegisterRestClient(configKey = "rc-config-key") - public static class SampleRestClient2 { + public static interface SampleRestClient2 { } // Base uri configured with: CLIENT_CONFIG_KEY_mp_rest_url @RegisterRestClient(configKey = "CLIENT_CONFIG_KEY") - public static class SampleRestClient3 { + public static interface SampleRestClient3 { + } + + public static interface NoAnnotationClient { + } + + @RegisterRestClient + public static class ConcreteClassClient { } @Test @@ -61,6 +69,19 @@ public void testMpRestClient() { assertEquals(clientUrl, appEnv.get("CLIENT_CONFIG_KEY/mp-rest/url"), appEnv.toString()); } + @Test + public void testMpRestClientValidation() { + final String clientUrl = "http://example.com"; + + assertThrows(IllegalArgumentException.class, () -> dummyApp().withMpRestClient(NoAnnotationClient.class, clientUrl)); + assertThrows(IllegalArgumentException.class, () -> dummyApp().withMpRestClient(ConcreteClassClient.class, clientUrl)); + assertThrows(NullPointerException.class, () -> dummyApp().withMpRestClient(SampleRestClient1.class, null)); + Class nullClass = null; + assertThrows(NullPointerException.class, () -> dummyApp().withMpRestClient(nullClass, clientUrl)); + assertThrows(IllegalArgumentException.class, () -> dummyApp().withMpRestClient(SampleRestClient1.class, "bogus")); + assertThrows(IllegalArgumentException.class, () -> dummyApp().withMpRestClient("com.example.StringRestClient/mp-rest/url", "bogus")); + } + @Test public void testCorrectServerAdapter() { ApplicationContainer app = dummyApp();