// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http.server.jetty; import com.yahoo.jdisc.Metric; import com.yahoo.jdisc.http.ConnectorConfig; import com.yahoo.jdisc.http.SecretStore; import com.yahoo.jdisc.http.SslContextFactory; import com.yahoo.jdisc.http.ssl.ReaderForPath; import com.yahoo.jdisc.http.ssl.SslKeyStore; import com.yahoo.jdisc.http.ssl.pem.PemKeyStore; import com.yahoo.jdisc.http.ssl.pem.PemSslKeyStore; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; import org.testng.annotations.Test; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.ServerSocketChannel; import java.util.Map; import static com.yahoo.jdisc.http.ConnectorConfig.Ssl; import static com.yahoo.jdisc.http.ConnectorConfig.Ssl.KeyStoreType.Enum.JKS; import static com.yahoo.jdisc.http.ConnectorConfig.Ssl.KeyStoreType.Enum.PEM; import static org.hamcrest.CoreMatchers.equalTo; /** * @author Einar M R Rosenvinge */ public class ConnectorFactoryTest { @Test(expectedExceptions = IllegalArgumentException.class) public void ssl_jks_config_is_validated() { ConnectorConfig config = new ConnectorConfig( new ConnectorConfig.Builder() .ssl(new Ssl.Builder() .enabled(true) .keyStoreType(JKS) .pemKeyStore( new Ssl.PemKeyStore.Builder() .keyPath("nonEmpty")))); ConnectorFactory willThrowException = new ConnectorFactory(config, new ThrowingSecretStore()); } @Test(expectedExceptions = IllegalArgumentException.class) public void ssl_pem_config_is_validated() { ConnectorConfig config = new ConnectorConfig( new ConnectorConfig.Builder() .ssl(new Ssl.Builder() .enabled(true) .keyStoreType(PEM) .keyStorePath("nonEmpty"))); ConnectorFactory willThrowException = new ConnectorFactory(config, new ThrowingSecretStore()); } @Test public void requireThatNoPreBoundChannelWorks() throws Exception { Server server = new Server(); try { ConnectorFactory factory = new ConnectorFactory(new ConnectorConfig(new ConnectorConfig.Builder()), new ThrowingSecretStore()); ConnectorFactory.JDiscServerConnector connector = (ConnectorFactory.JDiscServerConnector)factory.createConnector(new DummyMetric(), server, null); server.addConnector(connector); server.setHandler(new HelloWorldHandler()); server.start(); SimpleHttpClient client = new SimpleHttpClient(null, connector.getLocalPort(), false); SimpleHttpClient.RequestExecutor ex = client.newGet("/blaasdfnb"); SimpleHttpClient.ResponseValidator val = ex.execute(); val.expectContent(equalTo("Hello world")); } finally { try { server.stop(); } catch (Exception e) { //ignore } } } @Test public void requireThatPreBoundChannelWorks() throws Exception { Server server = new Server(); try { ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.socket().bind(new InetSocketAddress(0)); ConnectorFactory factory = new ConnectorFactory(new ConnectorConfig(new ConnectorConfig.Builder()), new ThrowingSecretStore()); ConnectorFactory.JDiscServerConnector connector = (ConnectorFactory.JDiscServerConnector) factory.createConnector(new DummyMetric(), server, serverChannel); server.addConnector(connector); server.setHandler(new HelloWorldHandler()); server.start(); SimpleHttpClient client = new SimpleHttpClient(null, connector.getLocalPort(), false); SimpleHttpClient.RequestExecutor ex = client.newGet("/blaasdfnb"); SimpleHttpClient.ResponseValidator val = ex.execute(); val.expectContent(equalTo("Hello world")); } finally { try { server.stop(); } catch (Exception e) { //ignore } } } private static class HelloWorldHandler extends AbstractHandler { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.getWriter().write("Hello world"); response.getWriter().flush(); response.getWriter().close(); baseRequest.setHandled(true); } } private static class DummyMetric implements Metric { @Override public void set(String key, Number val, Context ctx) { } @Override public void add(String key, Number val, Context ctx) { } @Override public Context createContext(Map properties) { return new DummyContext(); } } private static class DummyContext implements Metric.Context { } private static final class ThrowingSecretStore implements SecretStore { @Override public String getSecret(String key) { throw new UnsupportedOperationException("A secret store is not available"); } } }