All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.component.mllp.internal.TcpServerAcceptThread Maven / Gradle / Ivy

The newest version!
/*
 * 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.camel.component.mllp.internal;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;

import org.apache.camel.Route;
import org.apache.camel.component.mllp.MllpTcpServerConsumer;
import org.apache.camel.spi.UnitOfWork;
import org.apache.camel.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

/**
 * Thread to handle the ServerSocket.accept requests, and submit the sockets to the accept executor for validation.
 */
public class TcpServerAcceptThread extends Thread {
    Logger log = LoggerFactory.getLogger(this.getClass());

    MllpTcpServerConsumer consumer;
    ServerSocket serverSocket;
    boolean running;

    public TcpServerAcceptThread(MllpTcpServerConsumer consumer, ServerSocket serverSocket) {
        this.consumer = consumer;
        this.serverSocket = serverSocket;
    }

    /**
     * Derive a thread name from the class name, the component URI and the connection information.
     * 

* The String will in the format [endpoint key] - [local socket address] * * @return String for thread name */ String createThreadName(ServerSocket serverSocket) { // Get the classname without the package. This is a nested class, so we want the parent class name included String fullClassName = this.getClass().getName(); String className = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); // Get the URI without options String fullEndpointKey = consumer.getEndpoint().getEndpointKey(); String endpointKey = StringHelper.before(fullEndpointKey, "?", fullEndpointKey); // Now put it all together return String.format("%s[%s] - %s", className, endpointKey, serverSocket.getLocalSocketAddress()); } /** * The main ServerSocket.accept() loop *

* NOTE: When a connection is received, the Socket is checked after a brief delay in an attempt to determine if this * is a load-balancer probe. The test is done before the ConsumerClientSocketThread is created to avoid creating a * large number of short lived threads, which is what can occur if the load balancer polling interval is very short. */ @Override public void run() { running = true; String originalThreadName = Thread.currentThread().getName(); Thread.currentThread().setName(createThreadName(serverSocket)); MDC.put(UnitOfWork.MDC_CAMEL_CONTEXT_ID, consumer.getEndpoint().getCamelContext().getName()); Route route = consumer.getRoute(); if (route != null) { String routeId = route.getId(); if (routeId != null) { MDC.put(UnitOfWork.MDC_ROUTE_ID, route.getId()); } } log.info("Starting ServerSocket accept thread for {}", serverSocket); try { while (running && null != serverSocket && serverSocket.isBound() && !serverSocket.isClosed()) { Socket socket = null; try { socket = serverSocket.accept(); } catch (SocketTimeoutException timeoutEx) { // Didn't get a new connection - keep waiting for one log.debug("Timeout waiting for client connection - keep listening"); continue; } catch (SocketException socketEx) { // This should happen if the component is closed while the accept call is blocking if (serverSocket.isBound()) { try { serverSocket.close(); } catch (Exception ex) { log.debug("Exception encountered closing ServerSocket after SocketException on accept() - ignoring", ex); } } continue; } catch (IOException ioEx) { log.error("Exception encountered accepting connection - closing ServerSocket", ioEx); if (serverSocket.isBound()) { try { serverSocket.close(); } catch (Exception ex) { log.debug("Exception encountered closing ServerSocket after exception on accept() - ignoring", ex); } } continue; } if (MllpSocketBuffer.isConnectionValid(socket)) { // Try and avoid starting client threads for things like security scans and load balancer probes consumer.validateConsumer(socket); } } } finally { log.info("ServerSocket.accept loop finished - closing listener"); if (null != serverSocket && serverSocket.isBound() && !serverSocket.isClosed()) { try { serverSocket.close(); } catch (Exception ex) { log.debug("Exception encountered closing ServerSocket after accept loop had exited - ignoring", ex); } } Thread.currentThread().setName(originalThreadName); MDC.remove(UnitOfWork.MDC_ROUTE_ID); MDC.remove(UnitOfWork.MDC_CAMEL_CONTEXT_ID); } } @Override public void interrupt() { this.running = false; super.interrupt(); if (null != serverSocket) { if (serverSocket.isBound()) { try { serverSocket.close(); } catch (IOException ioEx) { log.warn("Exception encountered closing ServerSocket in interrupt() method - ignoring", ioEx); } } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy