HttpServerCustomizerTest.java

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you 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 org.apache.calcite.avatica.server;

import org.apache.calcite.avatica.Meta;
import org.apache.calcite.avatica.remote.Driver;
import org.apache.calcite.avatica.remote.LocalService;
import org.apache.calcite.avatica.remote.Service;

import org.eclipse.jetty.server.Server;
import org.junit.Test;

import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

/**
 * HTTP server customizer tests
 */
public class HttpServerCustomizerTest {

  private static Meta mockMeta = mock(Meta.class);

  @SuppressWarnings("unchecked") // needed for the mocked customizers, not the builder
  @Test public void serverCustomizersInvoked() {
    ServerCustomizer<Server> mockCustomizer1 =
        (ServerCustomizer<Server>) mock(ServerCustomizer.class);
    ServerCustomizer<Server> mockCustomizer2 =
        (ServerCustomizer<Server>) mock(ServerCustomizer.class);
    Service service = new LocalService(mockMeta);
    HttpServer server =
        HttpServer.Builder.<Server>newBuilder().withHandler(service, Driver.Serialization.PROTOBUF)
            .withServerCustomizers(Arrays.asList(mockCustomizer1, mockCustomizer2), Server.class)
            .withPort(0).build();
    try {
      server.start();
      verify(mockCustomizer2).customize(any(Server.class));
      verify(mockCustomizer1).customize(any(Server.class));
    } finally {
      server.stop();
    }
  }

  @Test public void onlyJettyCustomizersAllowed() {
    List<ServerCustomizer<UnsupportedServer>> unsupportedCustomizers = new ArrayList<>();
    unsupportedCustomizers.add(new ServerCustomizer<UnsupportedServer>() {
      @Override public void customize(UnsupportedServer server) {
      }
    });

    HttpServer.Builder<UnsupportedServer> builder = HttpServer.Builder.newBuilder();
    IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
        () -> builder.withServerCustomizers(unsupportedCustomizers, UnsupportedServer.class));
    assertThat(thrown.getMessage(), containsString("Only Jetty Server customizers are supported"));
  }

  /**
   * A server type that cannot be customized
   */
  private static class UnsupportedServer {
  }

  @Test
  public void testServerVersionNotReturnedForUnauthorisedAccess() throws Exception {
    ServerCustomizer<Server> mockCustomizer1 =
            (ServerCustomizer<Server>) mock(ServerCustomizer.class);
    ServerCustomizer<Server> mockCustomizer2 =
            (ServerCustomizer<Server>) mock(ServerCustomizer.class);
    Service service = new LocalService(mockMeta);
    HttpServer server =
            HttpServer.Builder.<Server>newBuilder().withHandler(service,
                            Driver.Serialization.PROTOBUF)
                    .withServerCustomizers(
                            Arrays.asList(mockCustomizer1, mockCustomizer2), Server.class)
                    .withPort(0).build();
    try {
      server.start();
      URL httpServerUrl = new URI("http://localhost:" + server.getPort()).toURL();
      HttpURLConnection conn = (HttpURLConnection) httpServerUrl.openConnection();
      conn.setRequestMethod("GET");
      assertNull("Server information was not expected", conn.getHeaderField("server"));
    } finally {
      server.stop();
    }
  }
}

// End HttpServerCustomizerTest.java