[java-shib-shared] branch main updated: Convert additional tests to EmbeddedJetty class, requiring dup of class.

Codeberg noreply at shibboleth.net
Tue Jul 14 13:45:46 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-shib-shared.

View the commit online:
https://codeberg.org/Shibboleth/java-shib-shared/commit/04ad6d1d5f9390ca13bec003ff446c0b122b4ccf

The following commit(s) were added to refs/heads/main by this push:
     new 04ad6d1d Convert additional tests to EmbeddedJetty class, requiring dup of class.
04ad6d1d is described below

commit 04ad6d1d5f9390ca13bec003ff446c0b122b4ccf
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Tue Jul 14 09:45:34 2026 -0400

    Convert additional tests to EmbeddedJetty class, requiring dup of class.
---
 pom.xml                                            |   2 +
 shib-networking-spring/pom.xml                     |  14 +
 .../resource/ConditionalResourceTest.java          |  64 +++--
 .../spring/httpclient/resource/EmbeddedJetty.java  | 300 +++++++++++++++++++++
 .../resource/FileBackedHTTPResourceTest.java       |  74 +++--
 .../httpclient/resource/HTTPResourceTest.java      |  85 ++++--
 .../httpclient/resource/RepositorySupport.java     |  89 ------
 shib-testing/pom.xml                               |   1 -
 8 files changed, 474 insertions(+), 155 deletions(-)

diff --git a/pom.xml b/pom.xml
index b0399b0a..cf0c7f3b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,6 +45,8 @@
     <properties>
         <shibboleth.projectName>java-shib-shared</shibboleth.projectName>
         <checkstyle.configLocation>${project.basedir}/resources/checkstyle/checkstyle.xml</checkstyle.configLocation>
+        <!-- Controls embedded version used for testing. -->
+        <jetty.version>12.1.9</jetty.version>
     </properties>
 
     <dependencies>
diff --git a/shib-networking-spring/pom.xml b/shib-networking-spring/pom.xml
index 9c1fe487..010fdb33 100644
--- a/shib-networking-spring/pom.xml
+++ b/shib-networking-spring/pom.xml
@@ -87,6 +87,20 @@
           <artifactId>spring-test</artifactId>
           <scope>test</scope>
         </dependency>
+        
+        <dependency>
+            <groupId>${jetty.groupId}</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty.version}</version>
+          <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${jetty.groupId}</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty.version}</version>
+          <scope>test</scope>
+        </dependency>
+        
     </dependencies>
 
 </project>
diff --git a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/ConditionalResourceTest.java b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/ConditionalResourceTest.java
index af09c45c..27d14c13 100644
--- a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/ConditionalResourceTest.java
+++ b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/ConditionalResourceTest.java
@@ -16,12 +16,16 @@ package net.shibboleth.shared.spring.httpclient.resource;
 
 import java.io.IOException;
 
+import javax.annotation.Nonnull;
+
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.httpclient.HttpClientBuilder;
 import net.shibboleth.shared.httpclient.HttpClientContextHandler;
+import net.shibboleth.shared.primitive.NonnullSupplier;
 import net.shibboleth.shared.spring.custom.SchemaTypeAwareXMLBeanDefinitionReader;
 import net.shibboleth.shared.spring.resource.ConditionalResource;
 import net.shibboleth.shared.spring.resource.ConditionalResourceResolver;
+import net.shibboleth.shared.spring.resource.ResourceHelper;
 
 import org.apache.hc.client5.http.classic.HttpClient;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
@@ -30,7 +34,9 @@ import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
 import org.springframework.context.support.GenericApplicationContext;
 import org.springframework.core.io.ClassPathResource;
 import org.testng.Assert;
+import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 /**
@@ -39,42 +45,66 @@ import org.testng.annotations.Test;
 @SuppressWarnings("javadoc")
 public class ConditionalResourceTest {
 
-    private final String documentPath = "/net/shibboleth/shared/spring/httpclient/resource/document.xml";
-
-    private final String existsURL = RepositorySupport.buildHTTPResourceURL("java-shib-shared", "shib-networking-spring/src/test/resources/net/shibboleth/shared/spring/httpclient/resource/document.xml",false);
+    private static final String TEST_URL = "http://localhost:8080/document.xml";
 
-    private final String nonExistsURL = RepositorySupport.buildHTTPResourceURL("java-shib-shared", "trunk/src/test/resources/data/document.xml",false);
+    private static final String TEST_PATH = "net/shibboleth/shared/spring/httpclient/resource/document.xml";
 
+    private EmbeddedJetty jetty;
+    private int jettyStatus;
     private HttpClient client;
 
-    @BeforeClass public void setupClient() throws Exception {
+    @BeforeClass public void startJetty() throws Exception {
         client = (new HttpClientBuilder()).buildClient();
+
+        jetty = new EmbeddedJetty();
+        
+        final EmbeddedJetty.ResourceHandler handler = new EmbeddedJetty.ResourceHandler(
+                new NonnullSupplier<Integer>() {
+                    @Nonnull public Integer get() {
+                        return jettyStatus;
+                    }
+                },
+                NonnullSupplier.of(ResourceHelper.of(new ClassPathResource(TEST_PATH))));
+        handler.setContentType("application/json");
+        jetty.startServer(handler);
     }
 
+    @AfterClass
+    public void stopJetty() throws IOException {
+        if (jetty != null) {
+            jetty.stopServer();
+            jetty = null;
+        }
+    }
+    
+    @BeforeMethod
+    public void resetStatus() {
+        jettyStatus = 200;        
+    }
+    
     @Test public void existsTest() throws IOException, ComponentInitializationException {
-        System.out.println(existsURL);
-        final HTTPResource existsHTTPResource = new HTTPResource(client, existsURL);
-        final HTTPResource notExistsHTTPResource = new HTTPResource(client, nonExistsURL);
+        final HTTPResource existsHTTPResource = new HTTPResource(client, TEST_URL);
         
         final ConditionalResource existsResource = new ConditionalResource(existsHTTPResource);
-        final ConditionalResource notExistsResource = new ConditionalResource(notExistsHTTPResource);
-        
         existsResource.setId("test");
         existsResource.initialize();
 
+        Assert.assertTrue(existsHTTPResource.exists());
+        Assert.assertTrue(existsResource.exists());
+        
+        jettyStatus = 404;
+        final HTTPResource notExistsHTTPResource = new HTTPResource(client, TEST_URL);
+        final ConditionalResource notExistsResource = new ConditionalResource(notExistsHTTPResource);
         notExistsResource.setId("test");
         notExistsResource.initialize();
 
-        Assert.assertTrue(existsHTTPResource.exists());
         Assert.assertFalse(notExistsHTTPResource.exists());
-
-        Assert.assertTrue(existsResource.exists());
         Assert.assertTrue(notExistsResource.exists());
     }
     
     
     @Test public void contextHandlerFailBeforeTest() throws IOException, ComponentInitializationException {
-        final HTTPResource existsHTTPResource = new HTTPResource(client, existsURL);
+        final HTTPResource existsHTTPResource = new HTTPResource(client, TEST_URL);
         existsHTTPResource.setHttpClientContextHandler(new HttpClientContextHandler() {
             public void invokeBefore(HttpClientContext context, ClassicHttpRequest request) throws IOException {
                 throw new IOException("Fail");
@@ -91,7 +121,7 @@ public class ConditionalResourceTest {
     }
     
     @Test public void contextHandlerFailAfterTest() throws IOException, ComponentInitializationException {
-        final HTTPResource existsHTTPResource = new HTTPResource(client, existsURL);
+        final HTTPResource existsHTTPResource = new HTTPResource(client, TEST_URL);
         existsHTTPResource.setHttpClientContextHandler(new HttpClientContextHandler() {
             public void invokeBefore(HttpClientContext context, ClassicHttpRequest request) throws IOException {
             }
@@ -109,13 +139,13 @@ public class ConditionalResourceTest {
 
     @Test public void testCompare() throws IOException, ComponentInitializationException {
 
-        final HTTPResource existsHTTPResource = new HTTPResource(client, existsURL);
+        final HTTPResource existsHTTPResource = new HTTPResource(client, TEST_URL);
         
         final ConditionalResource existsResource = new ConditionalResource(existsHTTPResource);
         existsResource.setId("test");
         existsResource.initialize();
 
-        Assert.assertTrue(ResourceTestHelper.compare(existsResource, new ClassPathResource(documentPath)));
+        Assert.assertTrue(ResourceTestHelper.compare(existsResource, new ClassPathResource(TEST_PATH)));
     }
     
     @Test public void testBeanExists() throws ComponentInitializationException {
diff --git a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/EmbeddedJetty.java b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/EmbeddedJetty.java
new file mode 100644
index 00000000..bffe0086
--- /dev/null
+++ b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/EmbeddedJetty.java
@@ -0,0 +1,300 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.shared.spring.httpclient.resource;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.hc.client5.http.SystemDefaultDnsResolver;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.resource.ResourceFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.springframework.core.io.ClassPathResource;
+
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.NonnullSupplier;
+import net.shibboleth.shared.resource.Resource;
+import net.shibboleth.shared.spring.resource.ResourceHelper;
+
+/**
+ * Testing fixture using Jetty to server a specified handler.
+ */
+public class EmbeddedJetty implements Closeable {
+
+    /** Addresses to listen on. */
+    private List<InetAddress> jettyListenAddrs;
+    
+    /** Non-TLS port */
+    private int port = 8080;
+    
+    /** TLS port */
+    private int securePort = 8443;
+    
+    /** Captures server. */
+    @Nullable Server jettyServer;
+
+    /**
+     * Sets the non-TLS port to listen on.
+     * 
+     * <p>Defaults to 8080.</p>
+     * 
+     * @param p port
+     */
+    public void setPort(final int p) {
+        port = p;
+    }
+    
+    /**
+     * Sets the TLS port to listen on.
+     * 
+     * <p>Defaults to 8443.</p>
+     * 
+     * @param p port
+     */
+    public void setSecurePort(final int p) {
+        securePort = p;
+    }
+    
+    /**
+     * Starts embedded server to serve specified test content.
+     * 
+     * <p>The caller is expected to call {@link #stopServer} when finished.</p>
+     * 
+     * @param handler
+     * 
+     * @throws UnknownHostException
+     * @throws SocketException
+     */
+    public void startServer(final Handler handler) throws UnknownHostException, SocketException {
+        final Server server = new Server();
+
+        final var sslContextFactory = new SslContextFactory.Server();
+        sslContextFactory.setKeyStoreType("PKCS12");
+        sslContextFactory.setKeyStoreResource(ResourceFactory.of(server).newClassLoaderResource("/net/shibboleth/shared/testing/credentials/localhost.p12"));
+        sslContextFactory.setKeyStorePassword(getServerKeystorePassword());
+        
+        resolveListenAddresses();
+        ArrayList<ServerConnector> connectors = new ArrayList<>();
+        jettyListenAddrs.forEach(addr ->  {
+            
+            final ServerConnector connector = new ServerConnector(server);
+            connector.setHost(addr.getHostAddress());
+            connector.setPort(port);
+            connectors.add(connector);
+            
+            final ServerConnector tlsConnector = new ServerConnector(server, sslContextFactory);
+            tlsConnector.setHost(addr.getHostAddress());
+            tlsConnector.setPort(securePort);
+            connectors.add(tlsConnector);
+        });
+        server.setConnectors(connectors.toArray(new Connector[] {}));
+
+        server.setHandler(handler);
+        try {
+            server.start();
+        } catch (final Exception e) {
+            try {
+                server.stop();
+            } catch (final Exception e2) {}
+            throw new RuntimeException("Jetty startup failed", e);
+        }
+        final Thread serverRunner = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    server.join();
+                } catch (final InterruptedException e) {}
+            }
+        });
+        serverRunner.start();
+        jettyServer = server;
+    }
+    
+    /**
+     * Stop the server if started.
+     */
+    public void stopServer() {
+        if (jettyServer != null) {
+            try {
+                jettyServer.stop();
+            } catch (final Exception e) {
+                throw new RuntimeException("Jetty stop failed", e);
+            }
+        }
+    }
+    
+    /** {@inheritDoc} */
+    public void close() throws IOException {
+        stopServer();
+    }
+    
+    /**
+     * Returns the TLS certificate used by the server as a resource in PEM format
+     * 
+     * @return TLS server certificate resource
+     */
+    @Nonnull public static Resource getServerCertficateResource() {
+        return ResourceHelper.of(new ClassPathResource("/net/shibboleth/shared/testing/credentials/localhost.pem"));
+    }    
+
+    /**
+     * Returns the TLS keystore used by the server as a resource in PKCS12 format
+     * 
+     * @return TLS server keystore resource
+     */
+    @Nonnull public static Resource getServerKeystoreResource() {
+        return ResourceHelper.of(new ClassPathResource("/net/shibboleth/shared/testing/credentials/localhost.p12"));
+    }
+    
+    /**
+     * Returns the TLS server keystore password.
+     * 
+     * @return keystore password
+     */
+    @Nonnull public static String getServerKeystorePassword() {
+        return "changeit";
+    }
+    
+    /**
+     * Jetty handler to server content.
+     */
+    public static class ResourceHandler extends Handler.Abstract {
+
+        @Nonnull final NonnullSupplier<Integer> statusSupplier;
+        
+        @Nonnull final NonnullSupplier<Resource> resourceSupplier;
+        
+        @Nullable String contentType;
+
+        /**
+         * Constructor.
+         *
+         * @param s status
+         * @param r resource to serve
+         */
+        public ResourceHandler(final int s, @Nonnull final Resource r) {
+            statusSupplier = NonnullSupplier.of(s);
+            resourceSupplier = NonnullSupplier.of(Constraint.isNotNull(r, "Resource cannot be null"));
+        }
+        
+        /**
+         * Constructor.
+         * 
+         * <p>Uses 200 as the status.</p>
+         *
+         * @param r resource to serve
+         */
+        public ResourceHandler(@Nonnull final Resource r) {
+            this(200, r);
+        }
+        
+        /**
+         * Constructor.
+         *
+         * @param s status supplier
+         * @param r resource supplier
+         */
+        public ResourceHandler(@Nonnull final NonnullSupplier<Integer> s, @Nonnull final NonnullSupplier<Resource> r) {
+            statusSupplier = Constraint.isNotNull(s, "Status supplier cannot be null");
+            resourceSupplier = Constraint.isNotNull(r, "Resource supplier cannot be null");
+        }
+
+        /**
+         * Constructor.
+         * 
+         * <p>Uses 200 as the status.</p>
+         * 
+         * @param r resource supplier
+         */
+        public ResourceHandler(@Nonnull final NonnullSupplier<Resource> r) {
+            this(NonnullSupplier.of(200), r);
+        }
+        
+        /**
+         * Set value of content type header.
+         * 
+         * @param type content type value
+         */
+        public void setContentType(@Nullable final String type) {
+            contentType = type;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public boolean handle(Request request, Response response, Callback callback) throws Exception {
+            if (contentType != null) {
+                response.getHeaders().add("Content-Type", contentType);
+            }
+            response.setStatus(statusSupplier.get());
+            response.write(true, ByteBuffer.wrap(resourceSupplier.get().getInputStream().readAllBytes()), callback);
+            return true;
+        }
+    }
+
+    /**
+     * Resolve all applicable localhost interfaces.
+     * 
+     * @throws UnknownHostException 
+     * @throws SocketException 
+     */
+    private void resolveListenAddresses() throws UnknownHostException, SocketException {
+        // As of HttpClient 5.x, we need Jetty to listen on all localhost IPv4 and IPv6 addresses,
+        // b/c on connection failure (e.g. TLS handshake failure) HC will try them all,
+        // so they all have to respond similarly for the tests that expect failure via a specified exception type.
+        // This is an attempt to get them portably depending on whether IPv4 and/or IPv6 is enabled.
+
+        // Resolve the 'localhost' addrs that will be resolved and used by HttpClient
+        final List<InetAddress> localhostAddrs = CollectionSupport.listOf(SystemDefaultDnsResolver.INSTANCE.resolve("localhost"));
+
+        // Resolve available loopback and link-local interfaces
+        // Using ByteBuffer just to get hashcode() and equals() for byte[] for filtering using the Set.
+       final Set<ByteBuffer> interfaceAddrs = Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
+               .map(NetworkInterface::getInterfaceAddresses)
+               .flatMap(Collection::stream)
+               .map(InterfaceAddress::getAddress)
+               .filter(addr -> addr.isLoopbackAddress() || addr.isLinkLocalAddress() )
+               .map(InetAddress::getAddress)
+               .map(ByteBuffer::wrap)
+               .collect(Collectors.toSet());
+       
+       // Retain for listening those 'localhost' addrs which correspond to enabled interfaces
+       jettyListenAddrs = localhostAddrs.stream()
+               .filter(addr -> interfaceAddrs.contains(ByteBuffer.wrap(addr.getAddress())))
+               .collect(Collectors.toList());
+    }
+   
+}
\ No newline at end of file
diff --git a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/FileBackedHTTPResourceTest.java b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/FileBackedHTTPResourceTest.java
index e8d378fa..011c082b 100644
--- a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/FileBackedHTTPResourceTest.java
+++ b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/FileBackedHTTPResourceTest.java
@@ -17,8 +17,12 @@ package net.shibboleth.shared.spring.httpclient.resource;
 import java.io.File;
 import java.io.IOException;
 
+import javax.annotation.Nonnull;
+
 import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.httpclient.HttpClientBuilder;
+import net.shibboleth.shared.primitive.NonnullSupplier;
+import net.shibboleth.shared.spring.resource.ResourceHelper;
 import net.shibboleth.shared.spring.util.ApplicationContextBuilder;
 
 import org.apache.hc.client5.http.classic.HttpClient;
@@ -29,6 +33,7 @@ import org.springframework.mock.env.MockPropertySource;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 /**
@@ -37,52 +42,77 @@ import org.testng.annotations.Test;
 @SuppressWarnings("javadoc")
 public class FileBackedHTTPResourceTest {
 
-    private final String documentPath = "/net/shibboleth/shared/spring/httpclient/resource/document.xml";
+    private static final String TEST_URL = "http://localhost:8080/document.xml";
 
-    private final String existsURL =
-            RepositorySupport.buildHTTPResourceURL("java-shib-shared", "shib-networking-spring/src/test/resources/net/shibboleth/shared/spring/httpclient/resource/document.xml",false);
+    private static final String TEST_PATH = "net/shibboleth/shared/spring/httpclient/resource/document.xml";
 
-    private final String nonExistsURL = RepositorySupport.buildHTTPResourceURL("java-shib-shared", "trunk/src/test/resources/data/document.xml",false);
+    private EmbeddedJetty jetty;
+    private int jettyStatus;
+    private HttpClient client;
 
     private String existsFile;
 
-    private HttpClient client;
-
-    @BeforeClass public void setupClient() throws Exception {
+    @BeforeClass
+    public void startJetty() throws Exception {
         client = (new HttpClientBuilder()).buildClient();
         final File file = File.createTempFile("FileBackedHTTPResourceTest1", ".xml");
         existsFile = file.getAbsolutePath();
+
+        jetty = new EmbeddedJetty();
+        
+        final EmbeddedJetty.ResourceHandler handler = new EmbeddedJetty.ResourceHandler(
+                new NonnullSupplier<Integer>() {
+                    @Nonnull public Integer get() {
+                        return jettyStatus;
+                    }
+                },
+                NonnullSupplier.of(ResourceHelper.of(new ClassPathResource(TEST_PATH))));
+        handler.setContentType("application/json");
+        jetty.startServer(handler);
     }
 
-    @AfterClass public void deleteFile() {
+    @AfterClass public void stopJetty() {
+        if (jetty != null) {
+            jetty.stopServer();
+            jetty = null;
+        }
+
         final File f = new File(existsFile);
         if (f.exists()) {
             f.delete();
         }
     }
 
+    @BeforeMethod
+    public void resetStatus() {
+        jettyStatus = 200;        
+    }
+    
     @Test public void existsTest() throws IOException {
-        final Resource existsResource = new FileBackedHTTPResource(existsFile, client, existsURL);
-        final Resource notExistsResource =
-                new FileBackedHTTPResource(existsFile + "ZZZ", client, nonExistsURL);
-
+        final Resource existsResource = new FileBackedHTTPResource(existsFile, client, TEST_URL);
         Assert.assertTrue(existsResource.exists());
+
+        jettyStatus = 404;
+        final Resource notExistsResource =
+                new FileBackedHTTPResource(existsFile + "ZZZ", client, TEST_URL);
         Assert.assertFalse(notExistsResource.exists());
     }
 
     @Test public void testCompare() throws IOException {
-        Assert.assertTrue(ResourceTestHelper.compare(new FileBackedHTTPResource(existsFile, client, existsURL),
-                new ClassPathResource(documentPath)));
+        Assert.assertTrue(ResourceTestHelper.compare(new FileBackedHTTPResource(existsFile, client, TEST_URL),
+                new ClassPathResource(TEST_PATH)));
+        
         // With that done compare via the backup
-        Assert.assertTrue(ResourceTestHelper.compare(new FileBackedHTTPResource(existsFile, client, nonExistsURL),
-                new ClassPathResource(documentPath)));
+        jettyStatus = 404;
+        Assert.assertTrue(ResourceTestHelper.compare(new FileBackedHTTPResource(existsFile, client, TEST_URL),
+                new ClassPathResource(TEST_PATH)));
     }
 
     public GenericApplicationContext getContext(final String location) {
 
         final MockPropertySource mockEnvVars = new MockPropertySource();
         mockEnvVars.setProperty("file.name", existsFile);
-        mockEnvVars.setProperty("the.url", existsURL);
+        mockEnvVars.setProperty("the.url", TEST_URL);
 
         final ApplicationContextBuilder builder = new ApplicationContextBuilder();
         builder.setUnresolvedServiceConfigurations(CollectionSupport.singletonList(location));
@@ -96,15 +126,15 @@ public class FileBackedHTTPResourceTest {
         try (final GenericApplicationContext context = getContext("net/shibboleth/shared/spring/httpclient/resource/newStyle.xml")) {
 
             Assert.assertTrue(ResourceTestHelper.compare(context.getBean("namedString", FileBackedHTTPResource.class),
-                    new ClassPathResource(documentPath)));
+                    new ClassPathResource(TEST_PATH)));
             Assert.assertTrue(ResourceTestHelper.compare(context.getBean("namedURL", FileBackedHTTPResource.class),
-                    new ClassPathResource(documentPath)));
+                    new ClassPathResource(TEST_PATH)));
             Assert.assertTrue(ResourceTestHelper.compare(context
                     .getBean("numberedString", FileBackedHTTPResource.class),
-                    new ClassPathResource(documentPath)));
+                    new ClassPathResource(TEST_PATH)));
             Assert.assertTrue(ResourceTestHelper.compare(context.getBean("numberedURL", FileBackedHTTPResource.class),
-                    new ClassPathResource(documentPath)));
+                    new ClassPathResource(TEST_PATH)));
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/HTTPResourceTest.java b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/HTTPResourceTest.java
index e020a8ec..881b0e7f 100644
--- a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/HTTPResourceTest.java
+++ b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/HTTPResourceTest.java
@@ -21,6 +21,8 @@ import java.nio.file.Path;
 import java.time.Instant;
 import java.util.Collection;
 
+import javax.annotation.Nonnull;
+
 import org.apache.hc.client5.http.cache.CacheResponseStatus;
 import org.apache.hc.client5.http.classic.HttpClient;
 import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
@@ -31,13 +33,17 @@ import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.GenericApplicationContext;
 import org.springframework.core.io.ClassPathResource;
 import org.testng.Assert;
+import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import net.shibboleth.shared.httpclient.HttpClientBuilder;
 import net.shibboleth.shared.httpclient.HttpClientContextHandler;
 import net.shibboleth.shared.httpclient.InMemoryCachingHttpClientBuilder;
+import net.shibboleth.shared.primitive.NonnullSupplier;
 import net.shibboleth.shared.spring.custom.SchemaTypeAwareXMLBeanDefinitionReader;
+import net.shibboleth.shared.spring.resource.ResourceHelper;
 
 /**
  * Test for HTTPResource.
@@ -45,31 +51,55 @@ import net.shibboleth.shared.spring.custom.SchemaTypeAwareXMLBeanDefinitionReade
 @SuppressWarnings("javadoc")
 public class HTTPResourceTest {
 
-    private final String documentPath = "/net/shibboleth/shared/spring/httpclient/resource/document.xml";
-    
-//    private final String existsURL =
-//            "http://git.shibboleth.net/view/?p=java-shib-shared.git;a=blob_plain;f=shib-networking-spring/src/test/resources/net/shibboleth/shared/spring/httpclient/resource/document.xml;h=e8ec7c0d20c7a6b8193e1868398cda0c28df45ed;hb=HEAD";
-    private final String existsURL =
-            RepositorySupport.buildHTTPResourceURL("java-shib-shared", "shib-networking-spring/src/test/resources/net/shibboleth/shared/spring/httpclient/resource/document.xml",false);
+    private static final String TEST_URL = "http://localhost:8080/document.xml";
 
-    private final String nonExistsURL = RepositorySupport.buildHTTPResourceURL("java-shib-shared", "trunk/src/test/resources/data/document.xml",false);
+    private static final String TEST_PATH = "net/shibboleth/shared/spring/httpclient/resource/document.xml";
 
+    private EmbeddedJetty jetty;
+    private int jettyStatus;
     private HttpClient client;
-
-    @BeforeClass public void setupClient() throws Exception {
+    
+    @BeforeClass
+    public void startJetty() throws Exception {
         client = (new HttpClientBuilder()).buildClient();
+        
+        jetty = new EmbeddedJetty();
+        
+        final EmbeddedJetty.ResourceHandler handler = new EmbeddedJetty.ResourceHandler(
+                new NonnullSupplier<Integer>() {
+                    @Nonnull public Integer get() {
+                        return jettyStatus;
+                    }
+                },
+                NonnullSupplier.of(ResourceHelper.of(new ClassPathResource(TEST_PATH))));
+        handler.setContentType("application/json");
+        jetty.startServer(handler);
+    }
+    
+    @AfterClass
+    public void stopJetty() throws IOException {
+        if (jetty != null) {
+            jetty.stopServer();
+            jetty = null;
+        }
+    }
+    
+    @BeforeMethod
+    public void resetStatus() {
+        jettyStatus = 200;        
     }
 
     @Test public void existsTest() throws IOException {
-        final HTTPResource existsResource = new HTTPResource(client, existsURL);
-        final HTTPResource notExistsResource = new HTTPResource(client, nonExistsURL);
-
+        final HTTPResource existsResource = new HTTPResource(client, TEST_URL);
         Assert.assertTrue(existsResource.exists());
+        
+        jettyStatus = 404;
+        final HTTPResource notExistsResource = new HTTPResource(client, TEST_URL);
         Assert.assertFalse(notExistsResource.exists());
     }
     
     @Test public void contextHandlerNoopTest() throws IOException {
-        final HTTPResource existsResource = new HTTPResource(client, existsURL);
+        final HTTPResource existsResource = new HTTPResource(client, TEST_URL);
         existsResource.setHttpClientContextHandler(new HttpClientContextHandler() {
             public void invokeBefore(HttpClientContext context, ClassicHttpRequest request) throws IOException {
             }
@@ -81,7 +111,7 @@ public class HTTPResourceTest {
     }
     
     @Test public void contextHandlerFailBeforeTest() throws IOException {
-        final HTTPResource existsResource = new HTTPResource(client, existsURL);
+        final HTTPResource existsResource = new HTTPResource(client, TEST_URL);
         existsResource.setHttpClientContextHandler(new HttpClientContextHandler() {
             public void invokeBefore(HttpClientContext context, ClassicHttpRequest request) throws IOException {
                 throw new IOException("Fail");
@@ -94,7 +124,7 @@ public class HTTPResourceTest {
     }
     
     @Test public void contextHandlerFailAfterTest() throws IOException {
-        final HTTPResource existsResource = new HTTPResource(client, existsURL);
+        final HTTPResource existsResource = new HTTPResource(client, TEST_URL);
         existsResource.setHttpClientContextHandler(new HttpClientContextHandler() {
             public void invokeBefore(HttpClientContext context, ClassicHttpRequest request) throws IOException {
             }
@@ -108,15 +138,15 @@ public class HTTPResourceTest {
 
     @Test public void testCompare() throws IOException {
 
-        Assert.assertTrue(ResourceTestHelper.compare(new HTTPResource(client, existsURL), new ClassPathResource(documentPath)));
+        Assert.assertTrue(ResourceTestHelper.compare(new HTTPResource(client, TEST_URL), new ClassPathResource(TEST_PATH)));
     }
 
     @Test public void testRelated() throws IOException {
 
-        // Chose a file unlikely to change. Do not use the svn thing because the date will not be there
+        // Chose a file unlikely to change. Do not use the embedded thing because the date will not be there.
 
         final HTTPResource parent =
-                new HTTPResource(client, "http://test.shibboleth.net/downloads/identity-provider/archive/2.0.0/");
+                new HTTPResource(client, "http://shibboleth.net/downloads/identity-provider/archive/2.0.0/");
         final HTTPResource child = parent.createRelative("shibboleth-idp-2.0.0-bin.zip");
 
         final long when = child.lastModified();
@@ -129,10 +159,10 @@ public class HTTPResourceTest {
 
     @Test public void testCachedNoCache() throws IOException, InterruptedException {
 
-        final TestHTTPResource what = new TestHTTPResource(client, existsURL);
+        final TestHTTPResource what = new TestHTTPResource(client, TEST_URL);
         Assert.assertTrue(what.exists());
         Assert.assertNull(what.getLastCacheResponseStatus());
-        Assert.assertTrue(ResourceTestHelper.compare(what, new ClassPathResource(documentPath)));
+        Assert.assertTrue(ResourceTestHelper.compare(what, new ClassPathResource(TEST_PATH)));
         Assert.assertNull(what.getLastCacheResponseStatus());
     }
 
@@ -141,10 +171,10 @@ public class HTTPResourceTest {
 
         final InMemoryCachingHttpClientBuilder builder = new InMemoryCachingHttpClientBuilder();
         builder.setMaxCacheEntries(3);
-        final TestHTTPResource what = new TestHTTPResource(builder.buildClient(), existsURL);
+        final TestHTTPResource what = new TestHTTPResource(builder.buildClient(), TEST_URL);
         Assert.assertTrue(what.exists());
         Assert.assertNotNull(what.getLastCacheResponseStatus());
-        Assert.assertTrue(ResourceTestHelper.compare(what, new ClassPathResource(documentPath)));
+        Assert.assertTrue(ResourceTestHelper.compare(what, new ClassPathResource(TEST_PATH)));
 
         Assert.assertEquals(what.getLastCacheResponseStatus(), CacheResponseStatus.CACHE_HIT);
     }
@@ -179,7 +209,7 @@ public class HTTPResourceTest {
 
             Assert.assertTrue(what.exists());
             Assert.assertNotNull(what.getLastCacheResponseStatus());
-            Assert.assertTrue(ResourceTestHelper.compare(what, new ClassPathResource(documentPath)));
+            Assert.assertTrue(ResourceTestHelper.compare(what, new ClassPathResource(TEST_PATH)));
 
             Assert.assertEquals(what.getLastCacheResponseStatus(), CacheResponseStatus.CACHE_HIT);
         } finally {
@@ -216,7 +246,7 @@ public class HTTPResourceTest {
 
             Assert.assertTrue(what.exists());
             Assert.assertNotNull(what.getLastCacheResponseStatus());
-            Assert.assertTrue(ResourceTestHelper.compare(what, new ClassPathResource(documentPath)));
+            Assert.assertTrue(ResourceTestHelper.compare(what, new ClassPathResource(TEST_PATH)));
 
             Assert.assertEquals(what.getLastCacheResponseStatus(), CacheResponseStatus.CACHE_HIT);
         } finally {
@@ -233,9 +263,11 @@ public class HTTPResourceTest {
     }
 
     @Test(timeOut = 5000) public void testCloseResponse() {
+        jettyStatus = 404;
+        
         // See IDP-969. This test will timeout if the response is not closed.
         try (final PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager()) {
-            final HTTPResource notExistsResource = new HTTPResource(client, nonExistsURL);
+            final HTTPResource notExistsResource = new HTTPResource(client, TEST_URL);
             int count = 0;
             while (count <= connMgr.getDefaultMaxPerRoute()) {
                 count++;
@@ -249,4 +281,5 @@ public class HTTPResourceTest {
             Assert.fail("Bad URL", e);
         }
     }
-}
+    
+}
\ No newline at end of file
diff --git a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/RepositorySupport.java b/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/RepositorySupport.java
deleted file mode 100644
index 5896c204..00000000
--- a/shib-networking-spring/src/test/java/net/shibboleth/shared/spring/httpclient/resource/RepositorySupport.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.shared.spring.httpclient.resource;
-
-import javax.annotation.Nonnull;
-
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.StringSupport;
-
-/**
- * Support class for working with the project version control repository.
- * 
- * <p>NOTE: If this changes, change the "main" copy in shib-testing.</p>
- */
-public final class RepositorySupport {
-    
-    /** Constructor. */
-    private RepositorySupport() { } 
-
-    /**
-     * Build an HTTPS resource URL for the selected repository name and path on the main branch.
-     * 
-     * @param repoName the repository name.  If Git, do not include the ".git" suffix.
-     * @param resourcePath The relative resource path within the repository, e.g. "foo/bar/baz/file.txt"
-     * 
-     * @return the HTTPS resource URL
-     */
-    public static String buildHTTPSResourceURL(@Nonnull final String repoName, @Nonnull final String resourcePath) {
-        return buildHTTPResourceURL(repoName, resourcePath, true, "HEAD");
-    }
-    
-    /**
-     * Build an HTTP/HTTPS resource URL for the selected repository name and path on the main branch.
-     * 
-     * @param repoName the repository name.  If Git, do not include a trailing ".git" suffix for bare repos.
-     * @param resourcePath The relative resource path within the repository, e.g. "foo/bar/baz/file.txt"
-     * @param https if true, use https if possible, otherwise use http
-     * 
-     * @return the HTTP(S) resource URL
-     */
-    public static String buildHTTPResourceURL(@Nonnull final String repoName, @Nonnull final String resourcePath, 
-            final boolean https) {
-        return buildHTTPResourceURL(repoName, resourcePath, https, "HEAD");
-    }
-    
-    /**
-     * Build an HTTP/HTTPS resource URL for the selected repository name and path.
-     * 
-     * @param repoName the repository name.  If Git, do not include a trailing ".git" suffix for bare repos.
-     * @param resourcePath The relative resource path within the repository, e.g. "foo/bar/baz/file.txt"
-     * @param https if true, use https if possible, otherwise use http
-     * @param branch code branch
-     * 
-     * @return the HTTP(S) resource URL
-     * 
-     * @since 8.2.0
-     */
-    public static String buildHTTPResourceURL(@Nonnull final String repoName, @Nonnull final String resourcePath, 
-            final boolean https, @Nonnull @NotEmpty final String branch) {
-        
-        final String repo = Constraint.isNotNull(StringSupport.trimOrNull(repoName), 
-                "Repository name was null or empty");
-        String path = Constraint.isNotNull(StringSupport.trimOrNull(resourcePath), 
-                "Resource path was null or empty");
-        
-        if (path.startsWith("/")) {
-            path = path.substring(1);
-        }
-        
-        if (https) {
-            return String.format("https://git.shibboleth.net/unittests/%s/%s/%s", repo, branch, path);
-        }
-        return String.format("http://git.shibboleth.net/unittests/%s/%s/%s", repo, branch, path);
-    }
-
-}
\ No newline at end of file
diff --git a/shib-testing/pom.xml b/shib-testing/pom.xml
index 70e19cce..2895edfb 100644
--- a/shib-testing/pom.xml
+++ b/shib-testing/pom.xml
@@ -17,7 +17,6 @@
     <properties>
         <automatic.module.name>net.shibboleth.shared.testing</automatic.module.name>
         <checkstyle.configLocation>${project.basedir}/../resources/checkstyle/checkstyle.xml</checkstyle.configLocation>
-        <jetty.version>12.1.5</jetty.version>
     </properties>
 
     <dependencies>

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list