Search in sources :

Example 1 with CONNECTION

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION in project flink by apache.

the class HistoryServerStaticFileServerHandler method respondWithFile.

/**
 * Response when running with leading JobManager.
 */
private void respondWithFile(ChannelHandlerContext ctx, HttpRequest request, String requestPath) throws IOException, ParseException, RestHandlerException {
    // make sure we request the "index.html" in case there is a directory request
    if (requestPath.endsWith("/")) {
        requestPath = requestPath + "index.html";
    }
    if (!requestPath.contains(".")) {
        // we assume that the path ends in either .html or .js
        requestPath = requestPath + ".json";
    }
    // convert to absolute path
    final File file = new File(rootPath, requestPath);
    if (!file.exists()) {
        // file does not exist. Try to load it with the classloader
        ClassLoader cl = HistoryServerStaticFileServerHandler.class.getClassLoader();
        try (InputStream resourceStream = cl.getResourceAsStream("web" + requestPath)) {
            boolean success = false;
            try {
                if (resourceStream != null) {
                    URL root = cl.getResource("web");
                    URL requested = cl.getResource("web" + requestPath);
                    if (root != null && requested != null) {
                        URI rootURI = new URI(root.getPath()).normalize();
                        URI requestedURI = new URI(requested.getPath()).normalize();
                        // expected scope.
                        if (!rootURI.relativize(requestedURI).equals(requestedURI)) {
                            LOG.debug("Loading missing file from classloader: {}", requestPath);
                            // ensure that directory to file exists.
                            file.getParentFile().mkdirs();
                            Files.copy(resourceStream, file.toPath());
                            success = true;
                        }
                    }
                }
            } catch (Throwable t) {
                LOG.error("error while responding", t);
            } finally {
                if (!success) {
                    LOG.debug("Unable to load requested file {} from classloader", requestPath);
                    throw new NotFoundException("File not found.");
                }
            }
        }
    }
    StaticFileServerHandler.checkFileValidity(file, rootPath, LOG);
    // cache validation
    final String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE);
    if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
        SimpleDateFormat dateFormatter = new SimpleDateFormat(StaticFileServerHandler.HTTP_DATE_FORMAT, Locale.US);
        Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);
        // Only compare up to the second because the datetime format we send to the client
        // does not have milliseconds
        long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
        long fileLastModifiedSeconds = file.lastModified() / 1000;
        if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Responding 'NOT MODIFIED' for file '" + file.getAbsolutePath() + '\'');
            }
            StaticFileServerHandler.sendNotModified(ctx);
            return;
        }
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Responding with file '" + file.getAbsolutePath() + '\'');
    }
    // Don't need to close this manually. Netty's DefaultFileRegion will take care of it.
    final RandomAccessFile raf;
    try {
        raf = new RandomAccessFile(file, "r");
    } catch (FileNotFoundException e) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Could not find file {}.", file.getAbsolutePath());
        }
        HandlerUtils.sendErrorResponse(ctx, request, new ErrorResponseBody("File not found."), NOT_FOUND, Collections.emptyMap());
        return;
    }
    try {
        long fileLength = raf.length();
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        StaticFileServerHandler.setContentTypeHeader(response, file);
        // the job overview should be updated as soon as possible
        if (!requestPath.equals("/joboverview.json")) {
            StaticFileServerHandler.setDateAndCacheHeaders(response, file);
        }
        if (HttpHeaders.isKeepAlive(request)) {
            response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
        }
        HttpHeaders.setContentLength(response, fileLength);
        // write the initial line and the header.
        ctx.write(response);
        // write the content.
        ChannelFuture lastContentFuture;
        if (ctx.pipeline().get(SslHandler.class) == null) {
            ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
            lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
        } else {
            lastContentFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)), ctx.newProgressivePromise());
        // HttpChunkedInput will write the end marker (LastHttpContent) for us.
        }
        // close the connection, if no keep-alive is needed
        if (!HttpHeaders.isKeepAlive(request)) {
            lastContentFuture.addListener(ChannelFutureListener.CLOSE);
        }
    } catch (Exception e) {
        raf.close();
        LOG.error("Failed to serve file.", e);
        throw new RestHandlerException("Internal server error.", INTERNAL_SERVER_ERROR);
    }
}
Also used : ChannelFuture(org.apache.flink.shaded.netty4.io.netty.channel.ChannelFuture) InputStream(java.io.InputStream) ChunkedFile(org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile) FileNotFoundException(java.io.FileNotFoundException) NotFoundException(org.apache.flink.runtime.rest.NotFoundException) FileNotFoundException(java.io.FileNotFoundException) ErrorResponseBody(org.apache.flink.runtime.rest.messages.ErrorResponseBody) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponse) DefaultFileRegion(org.apache.flink.shaded.netty4.io.netty.channel.DefaultFileRegion) URI(java.net.URI) URL(java.net.URL) Date(java.util.Date) SslHandler(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslHandler) NotFoundException(org.apache.flink.runtime.rest.NotFoundException) ParseException(java.text.ParseException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) RestHandlerException(org.apache.flink.runtime.rest.handler.RestHandlerException) RestHandlerException(org.apache.flink.runtime.rest.handler.RestHandlerException) HttpChunkedInput(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpChunkedInput) RandomAccessFile(java.io.RandomAccessFile) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) ChunkedFile(org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile) SimpleDateFormat(java.text.SimpleDateFormat)

Example 2 with CONNECTION

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION in project flink by apache.

the class NettyClient method connect.

// ------------------------------------------------------------------------
// Client connections
// ------------------------------------------------------------------------
ChannelFuture connect(final InetSocketAddress serverSocketAddress) {
    checkState(bootstrap != null, "Client has not been initialized yet.");
    // --------------------------------------------------------------------
    // Child channel pipeline for accepted connections
    // --------------------------------------------------------------------
    bootstrap.handler(new ChannelInitializer<SocketChannel>() {

        @Override
        public void initChannel(SocketChannel channel) throws Exception {
            // SSL handler should be added first in the pipeline
            if (clientSSLFactory != null) {
                SslHandler sslHandler = clientSSLFactory.createNettySSLHandler(channel.alloc(), serverSocketAddress.getAddress().getCanonicalHostName(), serverSocketAddress.getPort());
                channel.pipeline().addLast("ssl", sslHandler);
            }
            channel.pipeline().addLast(protocol.getClientChannelHandlers());
        }
    });
    try {
        return bootstrap.connect(serverSocketAddress);
    } catch (ChannelException e) {
        if ((e.getCause() instanceof java.net.SocketException && e.getCause().getMessage().equals("Too many open files")) || (e.getCause() instanceof ChannelException && e.getCause().getCause() instanceof java.net.SocketException && e.getCause().getCause().getMessage().equals("Too many open files"))) {
            throw new ChannelException("The operating system does not offer enough file handles to open the network connection. " + "Please increase the number of available file handles.", e.getCause());
        } else {
            throw e;
        }
    }
}
Also used : EpollSocketChannel(org.apache.flink.shaded.netty4.io.netty.channel.epoll.EpollSocketChannel) NioSocketChannel(org.apache.flink.shaded.netty4.io.netty.channel.socket.nio.NioSocketChannel) SocketChannel(org.apache.flink.shaded.netty4.io.netty.channel.socket.SocketChannel) IOException(java.io.IOException) ChannelException(org.apache.flink.shaded.netty4.io.netty.channel.ChannelException) SslHandler(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslHandler) ChannelException(org.apache.flink.shaded.netty4.io.netty.channel.ChannelException)

Example 3 with CONNECTION

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION in project flink by apache.

the class ClientTest method testServerClosesChannel.

/**
 * Tests that a server channel close, closes the connection and removes it from the established
 * connections.
 */
@Test
public void testServerClosesChannel() throws Exception {
    AtomicKvStateRequestStats stats = new AtomicKvStateRequestStats();
    final MessageSerializer<KvStateInternalRequest, KvStateResponse> serializer = new MessageSerializer<>(new KvStateInternalRequest.KvStateInternalRequestDeserializer(), new KvStateResponse.KvStateResponseDeserializer());
    Client<KvStateInternalRequest, KvStateResponse> client = null;
    Channel serverChannel = null;
    try {
        client = new Client<>("Test Client", 1, serializer, stats);
        final LinkedBlockingQueue<ByteBuf> received = new LinkedBlockingQueue<>();
        final AtomicReference<Channel> channel = new AtomicReference<>();
        serverChannel = createServerChannel(new ChannelDataCollectingHandler(channel, received));
        InetSocketAddress serverAddress = getKvStateServerAddress(serverChannel);
        // Requests
        KvStateInternalRequest request = new KvStateInternalRequest(new KvStateID(), new byte[0]);
        Future<KvStateResponse> future = client.sendRequest(serverAddress, request);
        received.take();
        assertEquals(1, stats.getNumConnections());
        channel.get().close().await();
        try {
            future.get();
            fail("Did not throw expected server failure");
        } catch (ExecutionException e) {
            if (!(e.getCause() instanceof ClosedChannelException)) {
                fail("Did not throw expected Exception");
            }
        // Expected
        }
        assertEquals(0L, stats.getNumConnections());
        // Counts can take some time to propagate
        while (stats.getNumSuccessful() != 0L || stats.getNumFailed() != 1L) {
            Thread.sleep(100L);
        }
        assertEquals(1L, stats.getNumRequests());
        assertEquals(0L, stats.getNumSuccessful());
        assertEquals(1L, stats.getNumFailed());
    } finally {
        if (client != null) {
            try {
                client.shutdown().get();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Assert.assertTrue(client.isEventGroupShutdown());
        }
        if (serverChannel != null) {
            serverChannel.close();
        }
        assertEquals("Channel leak", 0L, stats.getNumConnections());
    }
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) MessageSerializer(org.apache.flink.queryablestate.network.messages.MessageSerializer) InetSocketAddress(java.net.InetSocketAddress) SocketChannel(org.apache.flink.shaded.netty4.io.netty.channel.socket.SocketChannel) NioServerSocketChannel(org.apache.flink.shaded.netty4.io.netty.channel.socket.nio.NioServerSocketChannel) Channel(org.apache.flink.shaded.netty4.io.netty.channel.Channel) AtomicReference(java.util.concurrent.atomic.AtomicReference) ByteBuf(org.apache.flink.shaded.netty4.io.netty.buffer.ByteBuf) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) ConnectException(java.net.ConnectException) ClosedChannelException(java.nio.channels.ClosedChannelException) UnknownHostException(java.net.UnknownHostException) ExecutionException(java.util.concurrent.ExecutionException) KvStateInternalRequest(org.apache.flink.queryablestate.messages.KvStateInternalRequest) KvStateResponse(org.apache.flink.queryablestate.messages.KvStateResponse) KvStateID(org.apache.flink.queryablestate.KvStateID) ExecutionException(java.util.concurrent.ExecutionException) AtomicKvStateRequestStats(org.apache.flink.queryablestate.network.stats.AtomicKvStateRequestStats) Test(org.junit.Test)

Example 4 with CONNECTION

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION in project flink by apache.

the class ClientTest method testFailureClosesChannel.

/**
 * Tests that a server failure closes the connection and removes it from the established
 * connections.
 */
@Test
public void testFailureClosesChannel() throws Exception {
    AtomicKvStateRequestStats stats = new AtomicKvStateRequestStats();
    final MessageSerializer<KvStateInternalRequest, KvStateResponse> serializer = new MessageSerializer<>(new KvStateInternalRequest.KvStateInternalRequestDeserializer(), new KvStateResponse.KvStateResponseDeserializer());
    Client<KvStateInternalRequest, KvStateResponse> client = null;
    Channel serverChannel = null;
    try {
        client = new Client<>("Test Client", 1, serializer, stats);
        final LinkedBlockingQueue<ByteBuf> received = new LinkedBlockingQueue<>();
        final AtomicReference<Channel> channel = new AtomicReference<>();
        serverChannel = createServerChannel(new ChannelDataCollectingHandler(channel, received));
        InetSocketAddress serverAddress = getKvStateServerAddress(serverChannel);
        // Requests
        List<Future<KvStateResponse>> futures = new ArrayList<>();
        KvStateInternalRequest request = new KvStateInternalRequest(new KvStateID(), new byte[0]);
        futures.add(client.sendRequest(serverAddress, request));
        futures.add(client.sendRequest(serverAddress, request));
        ByteBuf buf = received.take();
        assertNotNull("Receive timed out", buf);
        buf.release();
        buf = received.take();
        assertNotNull("Receive timed out", buf);
        buf.release();
        assertEquals(1L, stats.getNumConnections());
        Channel ch = channel.get();
        assertNotNull("Channel not active", ch);
        // Respond with failure
        ch.writeAndFlush(MessageSerializer.serializeServerFailure(serverChannel.alloc(), new RuntimeException("Expected test server failure")));
        try {
            futures.remove(0).get();
            fail("Did not throw expected server failure");
        } catch (ExecutionException e) {
            if (!(e.getCause() instanceof RuntimeException)) {
                fail("Did not throw expected Exception");
            }
        // Expected
        }
        try {
            futures.remove(0).get();
            fail("Did not throw expected server failure");
        } catch (ExecutionException e) {
            if (!(e.getCause() instanceof RuntimeException)) {
                fail("Did not throw expected Exception");
            }
        // Expected
        }
        assertEquals(0L, stats.getNumConnections());
        // Counts can take some time to propagate
        while (stats.getNumSuccessful() != 0L || stats.getNumFailed() != 2L) {
            Thread.sleep(100L);
        }
        assertEquals(2L, stats.getNumRequests());
        assertEquals(0L, stats.getNumSuccessful());
        assertEquals(2L, stats.getNumFailed());
    } finally {
        if (client != null) {
            try {
                client.shutdown().get();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Assert.assertTrue(client.isEventGroupShutdown());
        }
        if (serverChannel != null) {
            serverChannel.close();
        }
        assertEquals("Channel leak", 0L, stats.getNumConnections());
    }
}
Also used : MessageSerializer(org.apache.flink.queryablestate.network.messages.MessageSerializer) InetSocketAddress(java.net.InetSocketAddress) SocketChannel(org.apache.flink.shaded.netty4.io.netty.channel.socket.SocketChannel) NioServerSocketChannel(org.apache.flink.shaded.netty4.io.netty.channel.socket.nio.NioServerSocketChannel) Channel(org.apache.flink.shaded.netty4.io.netty.channel.Channel) ArrayList(java.util.ArrayList) AtomicReference(java.util.concurrent.atomic.AtomicReference) ByteBuf(org.apache.flink.shaded.netty4.io.netty.buffer.ByteBuf) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) ConnectException(java.net.ConnectException) ClosedChannelException(java.nio.channels.ClosedChannelException) UnknownHostException(java.net.UnknownHostException) ExecutionException(java.util.concurrent.ExecutionException) KvStateInternalRequest(org.apache.flink.queryablestate.messages.KvStateInternalRequest) Future(java.util.concurrent.Future) CompletableFuture(java.util.concurrent.CompletableFuture) KvStateResponse(org.apache.flink.queryablestate.messages.KvStateResponse) KvStateID(org.apache.flink.queryablestate.KvStateID) ExecutionException(java.util.concurrent.ExecutionException) AtomicKvStateRequestStats(org.apache.flink.queryablestate.network.stats.AtomicKvStateRequestStats) Test(org.junit.Test)

Example 5 with CONNECTION

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION in project flink by apache.

the class RestClientTest method testConnectionClosedHandling.

/**
 * Tests that we fail the operation if the remote connection closes.
 */
@Test
public void testConnectionClosedHandling() throws Exception {
    final Configuration config = new Configuration();
    config.setLong(RestOptions.IDLENESS_TIMEOUT, 5000L);
    try (final ServerSocket serverSocket = new ServerSocket(0);
        final RestClient restClient = new RestClient(config, TestingUtils.defaultExecutor())) {
        final String targetAddress = "localhost";
        final int targetPort = serverSocket.getLocalPort();
        // start server
        final CompletableFuture<Socket> socketCompletableFuture = CompletableFuture.supplyAsync(CheckedSupplier.unchecked(() -> NetUtils.acceptWithoutTimeout(serverSocket)));
        final CompletableFuture<EmptyResponseBody> responseFuture = restClient.sendRequest(targetAddress, targetPort, new TestMessageHeaders(), EmptyMessageParameters.getInstance(), EmptyRequestBody.getInstance(), Collections.emptyList());
        Socket connectionSocket = null;
        try {
            connectionSocket = socketCompletableFuture.get(TIMEOUT, TimeUnit.SECONDS);
        } catch (TimeoutException ignored) {
            // could not establish a server connection --> see that the response failed
            socketCompletableFuture.cancel(true);
        }
        if (connectionSocket != null) {
            // close connection
            connectionSocket.close();
        }
        try {
            responseFuture.get();
        } catch (ExecutionException ee) {
            if (!ExceptionUtils.findThrowable(ee, IOException.class).isPresent()) {
                throw ee;
            }
        }
    }
}
Also used : Configuration(org.apache.flink.configuration.Configuration) ServerSocket(java.net.ServerSocket) Matchers.containsString(org.hamcrest.Matchers.containsString) IOException(java.io.IOException) EmptyResponseBody(org.apache.flink.runtime.rest.messages.EmptyResponseBody) ExecutionException(java.util.concurrent.ExecutionException) Socket(java.net.Socket) ServerSocket(java.net.ServerSocket) TimeoutException(java.util.concurrent.TimeoutException) ConnectTimeoutException(org.apache.flink.shaded.netty4.io.netty.channel.ConnectTimeoutException) Test(org.junit.Test)

Aggregations

IOException (java.io.IOException)8 Test (org.junit.Test)7 ExecutionException (java.util.concurrent.ExecutionException)4 ByteBuf (org.apache.flink.shaded.netty4.io.netty.buffer.ByteBuf)4 Channel (org.apache.flink.shaded.netty4.io.netty.channel.Channel)4 ChannelFuture (org.apache.flink.shaded.netty4.io.netty.channel.ChannelFuture)4 SslHandler (org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslHandler)4 File (java.io.File)3 FileNotFoundException (java.io.FileNotFoundException)3 RandomAccessFile (java.io.RandomAccessFile)3 TimeoutException (java.util.concurrent.TimeoutException)3 RemoteTransportException (org.apache.flink.runtime.io.network.netty.exception.RemoteTransportException)3 SocketChannel (org.apache.flink.shaded.netty4.io.netty.channel.socket.SocketChannel)3 DefaultHttpResponse (org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse)3 HttpResponse (org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponse)3 InputStream (java.io.InputStream)2 ConnectException (java.net.ConnectException)2 InetSocketAddress (java.net.InetSocketAddress)2 ServerSocket (java.net.ServerSocket)2 Socket (java.net.Socket)2