/* * Copyright 2010 Proofpoint, Inc. * * 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 io.airlift.event.client; import com.google.common.io.CharStreams; import io.airlift.discovery.client.HttpServiceSelector; import io.airlift.discovery.client.testing.StaticHttpServiceSelector; import io.airlift.http.client.HttpClient; import io.airlift.http.client.HttpClientConfig; import io.airlift.http.client.jetty.JettyHttpClient; import io.airlift.node.NodeInfo; import io.airlift.units.Duration; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.joda.time.DateTime; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static com.google.common.base.Throwables.throwIfUnchecked; import static io.airlift.event.client.EventTypeMetadata.getValidEventTypeMetaDataSet; import static io.airlift.event.client.TestingUtils.getNormalizedJson; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.asList; import static java.util.concurrent.TimeUnit.SECONDS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; @Test(singleThreaded = true) public class TestHttpEventClient { private DummyServlet servlet; private HttpEventClient client; private Server server; private URI baseUri; private HttpClient httpClient; @Test(expectedExceptions = ServiceUnavailableException.class, expectedExceptionsMessageRegExp = ".*is not available.*") public void testFutureFailsWhenServiceUnavailable() throws ExecutionException, InterruptedException { client = newEventClient(Collections.<URI>emptyList()); try { client.post(new FixedDummyEventClass("host", new DateTime(), UUID.randomUUID(), 1, "foo")).get(); } catch (ExecutionException e) { throwIfUnchecked(e.getCause()); throw new RuntimeException(e.getCause()); } } @Test public void testCallSucceedsWhenServiceUnavailable() throws ExecutionException, InterruptedException { client = newEventClient(Collections.<URI>emptyList()); client.post(new FixedDummyEventClass("host", new DateTime(), UUID.randomUUID(), 1, "foo")); assertNull(servlet.lastPath); assertNull(servlet.lastBody); } @Test public void testReceivesEvent() throws ExecutionException, InterruptedException, IOException { client = newEventClient(asList(baseUri)); client.post(TestingUtils.getEvents()).get(); assertEquals(servlet.lastPath, "/v2/event"); assertEquals(servlet.lastBody, getNormalizedJson("events.json")); } @Test public void loadTest() throws ExecutionException, InterruptedException, IOException { client = newEventClient(asList(baseUri)); List<Future<Void>> futures = new ArrayList<>(); for (int i = 0; i < 100; i++) { futures.add(client.post(TestingUtils.getEvents())); } for (Future<Void> future : futures) { future.get(); System.out.println("future " + future); } assertEquals(servlet.lastPath, "/v2/event"); assertEquals(servlet.lastBody, getNormalizedJson("events.json")); } @BeforeMethod public void setup() throws Exception { httpClient = new JettyHttpClient(new HttpClientConfig().setConnectTimeout(new Duration(10, SECONDS))); servlet = new DummyServlet(); server = createServer(servlet); server.start(); } @AfterMethod(alwaysRun = true) public void tearDown() throws Exception { if (server != null) { server.stop(); } httpClient.close(); } private HttpEventClient newEventClient(List<URI> uris) { HttpServiceSelector selector = new StaticHttpServiceSelector("collector", "general", uris); Set<EventTypeMetadata<?>> eventTypes = getValidEventTypeMetaDataSet(FixedDummyEventClass.class); JsonEventWriter eventWriter = new JsonEventWriter(eventTypes); return new HttpEventClient( selector, eventWriter, new NodeInfo("test"), httpClient); } private Server createServer(final DummyServlet servlet) throws Exception { int port; try (ServerSocket socket = new ServerSocket()) { socket.bind(new InetSocketAddress(0)); port = socket.getLocalPort(); } baseUri = new URI("http", null, "127.0.0.1", port, null, null, null); HttpConfiguration httpConfiguration = new HttpConfiguration(); httpConfiguration.setSendServerVersion(false); httpConfiguration.setSendXPoweredBy(false); server = new Server(); ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration)); httpConnector.setPort(port); httpConnector.setName("http"); server.addConnector(httpConnector); ServletHolder servletHolder = new ServletHolder(servlet); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS); context.addServlet(servletHolder, "/*"); HandlerCollection handlers = new HandlerCollection(); handlers.addHandler(context); server.setHandler(handlers); return server; } private static class DummyServlet extends HttpServlet { private volatile String lastPath; private volatile String lastBody; private DummyServlet() { } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { lastPath = request.getPathInfo(); lastBody = CharStreams.toString(new InputStreamReader(request.getInputStream(), UTF_8)); } } }