/*
* Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.synapse.transport.passthru.core;
import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
import org.apache.http.nio.NHttpServerEventHandler;
import org.apache.http.nio.reactor.IOReactorException;
import org.apache.http.nio.reactor.ListenerEndpoint;
import org.apache.http.nio.reactor.ListeningIOReactor;
import org.apache.log4j.Logger;
import org.apache.synapse.transport.http.conn.ServerConnFactory;
import org.apache.synapse.transport.passthru.ServerIODispatch;
import org.apache.synapse.transport.passthru.config.PassThroughConfiguration;
import org.apache.synapse.transport.passthru.config.SourceConfiguration;
import org.apache.synapse.transport.passthru.core.ssl.MultiListenerSSLServerIODispatch;
import org.apache.synapse.transport.passthru.core.ssl.SSLConfiguration;
import org.apache.synapse.transport.passthru.core.ssl.SSLConnectionUtils;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
public class PassThroughListeningIOReactorManager {
private static final Logger log = Logger.getLogger(PassThroughListeningIOReactorManager.class);
/**
* Singleton Object of class PassThroughListeningIOReactorManager
*/
private static PassThroughListeningIOReactorManager passThroughListeningIOReactorManager = new PassThroughListeningIOReactorManager();
/**
* Reference for shared ListeningIOReactor which can use by external endpoints
*/
private ListeningIOReactor sharedListeningIOReactor;
/**
* Reference for shared SSL ListeningIOReactor which can be used by external SSL configured endpoints
*/
private ListeningIOReactor sharedSSLListeningIOReactor;
/**
* Configuration used in shared IO Reactor
*/
private PassThroughSharedListenerConfiguration passThroughListenerConfiguration;
/**
* Configuration used in shared SSL IO Reactor
*/
private PassThroughSharedListenerConfiguration sslPassThroughListenerConfiguration;
/**
* Map keeps EventHandler and port mapping
*/
private Map<Integer, NHttpServerEventHandler> portServerHandlerMapper;
/**
* Map keeps ListeningEndpoint and external port mapping
*/
private Map<Integer, ListenerEndpoint> dynamicPTTListeningEndpointMapper;
/**
* Keep map between PTT Listeners and IOReactors.
*/
private Map<Integer, ListeningIOReactor> passThroughListenerIOReactorMapper;
/**
* Keep map between ServerIODispatch and PTT Listeners
*/
private Map<Integer, ServerIODispatch> passThroughListenerServerIODispatchMapper;
/**
* keep map between port , tenant and serverConnectionFactory used in Inbound Endpoints with SSL
*/
private Map<Integer, ServerConnFactory> serverConnectionFactoryMapper;
private AtomicBoolean isSharedIOReactorInitiated;
private IOReactorSharingMode ioReactorSharingMode;
private AtomicBoolean isSharedSSLIOReactorInitiated;
private PassThroughListeningIOReactorManager() {
portServerHandlerMapper = new ConcurrentHashMap<Integer, NHttpServerEventHandler>();
dynamicPTTListeningEndpointMapper = new ConcurrentHashMap<Integer, ListenerEndpoint>();
passThroughListenerIOReactorMapper = new ConcurrentHashMap<Integer, ListeningIOReactor>();
passThroughListenerServerIODispatchMapper = new ConcurrentHashMap<Integer, ServerIODispatch>();
serverConnectionFactoryMapper = new ConcurrentHashMap<Integer, ServerConnFactory>();
isSharedIOReactorInitiated = new AtomicBoolean(false);
isSharedSSLIOReactorInitiated = new AtomicBoolean(false);
ioReactorSharingMode = PassThroughConfiguration.getInstance().isListeningIOReactorShared() ?
IOReactorSharingMode.SHARED : IOReactorSharingMode.UNSHARED;
}
/**
* Provide manager object for internal services
*
* @return PassThroughIOReactorManager
*/
public static PassThroughListeningIOReactorManager getInstance() {
return passThroughListeningIOReactorManager;
}
/**
* Start PTT Endpoint which is given by axis2.xml
*
* @param inetSocketAddress Socket Address of starting endpoint
* @param defaultListeningIOReactor IO Reactor which starts Endpoint
* @param namePrefix name specified for endpoint
* @return Is started
*/
public boolean startPTTEndpoint(InetSocketAddress inetSocketAddress,
DefaultListeningIOReactor defaultListeningIOReactor, String namePrefix) {
try {
return startEndpoint(inetSocketAddress, defaultListeningIOReactor, namePrefix) != null;
} catch (Exception e) {
log.error("Cannot Start PassThroughListeningEndpoint for port " + inetSocketAddress.getPort(), e);
return false;
}
}
/**
* Start Endpoint in IOReactor which is external to PTT Axis2 Listeners started at server startup
*
* @param inetSocketAddress Socket Address of starting endpoint
* @param nHttpServerEventHandler ServerHandler responsible for handle events of port
* @param endpointName Endpoint Name
* @return Is Endpoint started
*/
public boolean startDynamicPTTEndpoint(InetSocketAddress inetSocketAddress,
NHttpServerEventHandler nHttpServerEventHandler, String endpointName) {
try {
// get Shared IO Reactor and Start Endpoint
ListenerEndpoint endpoint = startEndpoint(inetSocketAddress,
getSharedIOReactor(nHttpServerEventHandler, endpointName), endpointName);
if (endpoint != null) {
portServerHandlerMapper.put(inetSocketAddress.getPort(), nHttpServerEventHandler);
dynamicPTTListeningEndpointMapper.put(inetSocketAddress.getPort(), endpoint);
return true;
} else {
return false;
}
} catch (Exception e) {
log.error("Cannot Start Endpoint for " + endpointName, e);
return false;
}
}
/**
* Start SSL endpoint in IO reactor which is external to PTT Axis Listeners started at server startup
* @param inetSocketAddress InetSocketAddress
* @param nHttpServerEventHandler ServerHandler responsible for handle events of port
* @param endpointName Endpoint Name
* @param sslConfiguration SSL information for create secure connection
* @return
*/
public boolean startDynamicPTTSSLEndpoint(InetSocketAddress inetSocketAddress,
NHttpServerEventHandler nHttpServerEventHandler, String endpointName,
SSLConfiguration sslConfiguration) {
try {
// get Shared IO Reactor and Start Endpoint
ListenerEndpoint endpoint = startEndpoint(inetSocketAddress,
getSharedSSLIOReactor(nHttpServerEventHandler, endpointName,
inetSocketAddress.getPort(),
sslConfiguration), endpointName);
if (endpoint != null) {
portServerHandlerMapper.put(inetSocketAddress.getPort(), nHttpServerEventHandler);
dynamicPTTListeningEndpointMapper.put(inetSocketAddress.getPort(), endpoint);
return true;
} else {
return false;
}
} catch (Exception e) {
log.error("Cannot Start Endpoint for " + endpointName, e);
return false;
}
}
/**
* Create IOReactor with given configuration
*
* @param port Port of the Endpoint for axis2 Listener
* @param nHttpServerEventHandler Server Handler responsible for handle events of port
* @param passThroughSharedListenerConfiguration configuration related to create and start IOReactor
* @return IOReactor
*/
public ListeningIOReactor initIOReactor(int port, NHttpServerEventHandler nHttpServerEventHandler,
PassThroughSharedListenerConfiguration passThroughSharedListenerConfiguration)
throws IOReactorException {
ListeningIOReactor defaultListeningIOReactor;
try {
ServerIODispatch serverIODispatch;
// PassThroughListenerConfiguration to be used by Shared IO Reactor
synchronized (this) {
if (this.passThroughListenerConfiguration == null &&
!passThroughSharedListenerConfiguration.getSourceConfiguration().getScheme().isSSL()) {
this.passThroughListenerConfiguration = passThroughSharedListenerConfiguration;
}
if (this.sslPassThroughListenerConfiguration == null &&
passThroughSharedListenerConfiguration.getSourceConfiguration().getScheme().isSSL()) {
this.sslPassThroughListenerConfiguration = passThroughSharedListenerConfiguration;
}
}
//If IOReactor is in shared mode and if it is not initialized, initialize it for HTTP Protocol
if (ioReactorSharingMode == IOReactorSharingMode.SHARED && !isSharedIOReactorInitiated.get()
&& !passThroughSharedListenerConfiguration.getSourceConfiguration().getScheme().isSSL()) {
synchronized (this) {
portServerHandlerMapper.put(port, nHttpServerEventHandler);
serverIODispatch = new MultiListenerServerIODispatch
(portServerHandlerMapper, nHttpServerEventHandler,
passThroughSharedListenerConfiguration.getServerConnFactory());
// Create IOReactor for Listener make it shareable with Inbounds
defaultListeningIOReactor = createListeningIOReactor(passThroughSharedListenerConfiguration);
log.info("IO Reactor for port " + port + " initiated on shared mode which will be used by non axis2 " +
"Transport Listeners ");
sharedListeningIOReactor = defaultListeningIOReactor;
isSharedIOReactorInitiated.compareAndSet(false, true);
}
} else if(ioReactorSharingMode == IOReactorSharingMode.SHARED && !isSharedSSLIOReactorInitiated.get()
&& passThroughSharedListenerConfiguration.getSourceConfiguration().getScheme().isSSL()) {
synchronized (this) {
serverConnectionFactoryMapper.put(port,passThroughSharedListenerConfiguration.getServerConnFactory());
portServerHandlerMapper.put(port, nHttpServerEventHandler);
serverIODispatch = new MultiListenerSSLServerIODispatch(
portServerHandlerMapper , nHttpServerEventHandler, serverConnectionFactoryMapper);
// Create IOReactor for Listener make it shareable with Inbounds
defaultListeningIOReactor = createListeningIOReactor(passThroughSharedListenerConfiguration);
log.info("IO Reactor for port " + port + " initiated on shared mode which will be used by non axis2 " +
"Transport SSL Listeners ");
sharedSSLListeningIOReactor = defaultListeningIOReactor;
isSharedSSLIOReactorInitiated.compareAndSet(false, true);
}
}else {
// Create un shareable IOReactors for axis2 Listeners and assign IOReactor Config for later
// create IOReactor for Inbounds
serverIODispatch = new ServerIODispatch(nHttpServerEventHandler,
passThroughSharedListenerConfiguration.getServerConnFactory());
defaultListeningIOReactor = createListeningIOReactor(passThroughSharedListenerConfiguration);
}
passThroughListenerServerIODispatchMapper.put(port, serverIODispatch);
passThroughListenerIOReactorMapper.put(port, defaultListeningIOReactor);
} catch (IOReactorException e) {
throw new IOReactorException("Error occurred when trying to init IO Reactor", e);
}
return defaultListeningIOReactor;
}
/**
* Close external endpoints listen in shared IO Reactor
*
* @param port Port of the endpoint need to close
* @return Is endpoint closed
*/
public boolean closeDynamicPTTEndpoint(int port) {
try {
log.info("Closing Endpoint Listener for port "+port);
dynamicPTTListeningEndpointMapper.get(port).close();
log.info("Successfully closed Endpoint Listener for port "+port);
} catch (Exception e) {
log.error("Cannot close Endpoint relevant to port " + port, e);
return false;
} finally {
if(serverConnectionFactoryMapper.containsKey(port)){
serverConnectionFactoryMapper.remove(port);
}
dynamicPTTListeningEndpointMapper.remove(port);
}
return true;
}
/**
* Close all endpoints started by PTT Listeners.
*
* @param port Port of the Endpoint for PTT axis2 Listener
* @return is all Endpoints closed
*/
public boolean closeAllPTTListenerEndpoints(int port) {
try {
ListeningIOReactor listeningIOReactor = passThroughListenerIOReactorMapper.get(port);
if (listeningIOReactor != null) {
Set<ListenerEndpoint> endpoints = listeningIOReactor.getEndpoints();
// If it is shared IO Reactor then only close endpoints related to PTT Listener
if (passThroughListenerServerIODispatchMapper.get(port) instanceof MultiListenerServerIODispatch) {
for (ListenerEndpoint listenerEndpoint : endpoints) {
if (listenerEndpoint.getAddress() instanceof InetSocketAddress) {
int endPointPort = ((InetSocketAddress) listenerEndpoint.getAddress()).getPort();
if (dynamicPTTListeningEndpointMapper.containsKey(endPointPort)) {
continue;
}
log.info("Closing Endpoint Listener for port "+port);
listenerEndpoint.close();
log.info("Successfully closed Endpoint Listener for port "+port);
}
}
} else {
for (ListenerEndpoint listenerEndpoint : endpoints) {
log.info("Closing Endpoint Listener for port "+port);
listenerEndpoint.close();
log.info("Successfully closed Endpoint Listener for port "+port);
}
}
}
return true;
} catch (Exception e) {
log.error("Error occurred when closing Endpoint in PassThrough Transport Related to port " + port, e);
return false;
}
}
/**
* Close specific endpoints started by PTT Listeners using give set of bind addresses.
*
* @param port Port of the listener
* @param bindAddresses bind address list of endpoints to be closed
* @return true if successfully closed, false if any error
*/
public boolean closeSpecificPTTListenerEndpoints(int port,
Set<InetSocketAddress> bindAddresses) {
try {
ListeningIOReactor listeningIOReactor = passThroughListenerIOReactorMapper.get(port);
if (listeningIOReactor != null) {
Set<ListenerEndpoint> endpoints = listeningIOReactor.getEndpoints();
// If it is shared IO Reactor then only close endpoints related to PTT Listener
if (passThroughListenerServerIODispatchMapper.get(port) instanceof MultiListenerServerIODispatch) {
for (ListenerEndpoint listenerEndpoint : endpoints) {
if (listenerEndpoint.getAddress() instanceof InetSocketAddress) {
int endPointPort = ((InetSocketAddress) listenerEndpoint.getAddress()).getPort();
if (dynamicPTTListeningEndpointMapper.containsKey(endPointPort)) {
continue;
}
for (InetSocketAddress inetSocketAddress : bindAddresses) {
if (inetSocketAddress.getHostName().equalsIgnoreCase(((InetSocketAddress) listenerEndpoint.getAddress()).getHostName())) {
listenerEndpoint.close();
}
}
}
}
} else {
for (ListenerEndpoint listenerEndpoint : endpoints) {
for (InetSocketAddress inetSocketAddress : bindAddresses) {
if (inetSocketAddress.getHostName().equalsIgnoreCase(((InetSocketAddress) listenerEndpoint.getAddress()).getHostName())) {
listenerEndpoint.close();
}
}
}
}
}
return true;
} catch (Exception e) {
log.error("Error occurred when closing Endpoint in PassThrough Transport Related to port " + port, e);
return false;
}
}
/**
* Return ServerIODispatch registered under given port
*
* @param port Port of axis2 PTT Listener
* @return ServerIODispatch
*/
public ServerIODispatch getServerIODispatch(int port) {
return passThroughListenerServerIODispatchMapper.get(port);
}
/**
* @return source configuration used by shared IO Reactor
*/
public SourceConfiguration getSharedPassThroughSourceConfiguration() {
if (passThroughListenerConfiguration != null) {
return passThroughListenerConfiguration.getSourceConfiguration();
}
return null;
}
/**
* @return source configuration used by shared SSL IO Reactor
*/
public SourceConfiguration getSharedSSLPassThroughSourceConfiguration() {
if (sslPassThroughListenerConfiguration != null) {
return sslPassThroughListenerConfiguration.getSourceConfiguration();
}
return null;
}
/**
* ShutdownIOReactor which is registered by HTTPListener running on given port
*
* @param port Port of axis2 PTT Listener
* @throws IOException Exception throwing when Shutdown
*/
public void shutdownIOReactor(int port) throws IOException {
ListeningIOReactor ioReactor = shutdownReactor(port);
if (ioReactor != null) {
try {
ioReactor.shutdown();
} catch (IOException e) {
throw new IOException(
"IOException occurred when shutting down IOReactor for Listener started on port " + port, e);
}
passThroughListenerIOReactorMapper.remove(port);
passThroughListenerServerIODispatchMapper.remove(port);
}
}
/**
* ShutdownIOReactor which is registered by HTTPListener running on given port
*
* @param port Port of axis2 PTT Listener
* @param miliSeconds Waiting Time before close IO Reactor
* @throws IOException Exception throwing when Shutdown
*/
public void shutdownIOReactor(int port, long miliSeconds) throws IOException {
ListeningIOReactor ioReactor = shutdownReactor(port);
if (ioReactor != null) {
try {
ioReactor.shutdown(miliSeconds);
} catch (IOException e) {
throw new IOException(
"IOException occurred when shutting down IOReactor for Listener started on port " + port, e);
}
passThroughListenerIOReactorMapper.remove(port);
passThroughListenerServerIODispatchMapper.remove(port);
}
}
/**
* Pause IO Reactor which is registered by HTTPListener running on given port
*
* @param port Port of axis2 PTT Listener
* @throws IOException Exception throwing when pausing
*/
public void pauseIOReactor(int port) throws IOException {
ListeningIOReactor listeningIOReactor = passThroughListenerIOReactorMapper.get(port);
ServerIODispatch serverIODispatch = passThroughListenerServerIODispatchMapper.get(port);
if (listeningIOReactor != null) {
if (serverIODispatch instanceof MultiListenerServerIODispatch ||
serverIODispatch instanceof MultiListenerSSLServerIODispatch) {
log.info("Pausing shared IO Reactor bind for port " + port + " will be caused for pausing non " +
"axis2 Listeners ");
} else {
log.info("Pausing IO Reactor bind for port " + port);
}
listeningIOReactor.pause();
} else {
log.error("Cannot find Pass Through Listener for port " + port);
}
}
/**
* Resume IO Reactor which is registered by HTTPListener running on given port
*
* @param port Port of axis2 PTT Listener
* @throws IOException Exception throwing when pausing
*/
public void resumeIOReactor(int port) throws IOException {
ListeningIOReactor listeningIOReactor = passThroughListenerIOReactorMapper.get(port);
if (listeningIOReactor != null) {
listeningIOReactor.resume();
} else {
log.error("Cannot find Pass Through Listener for port " + port);
}
}
/**
* StartIOReactor with given ServerIODispatch
*
* @param listeningIOReactor Listening IO Reactor to be start
* @param serverIODispatch underlying Event Dispatcher for Reactor
* @param prefix HTTP/HTTPS
*/
public void startIOReactor(final ListeningIOReactor listeningIOReactor, final ServerIODispatch serverIODispatch,
final String prefix) {
Thread reactorThread = new Thread(new Runnable() {
public void run() {
try {
listeningIOReactor.execute(serverIODispatch);
} catch (Exception e) {
log.fatal("Exception encountered in the " + prefix + " Listener. " +
"No more connections will be accepted by this transport", e);
} finally {
log.info(prefix + " Listener shutdown.");
if (serverIODispatch instanceof MultiListenerServerIODispatch) {
log.info("Shutting down shared IO Reactor");
}
}
}
}, "PassThrough " + prefix + " Listener");
reactorThread.start();
}
private ListeningIOReactor getSharedIOReactor(NHttpServerEventHandler nHttpServerEventHandler,
String endpointName) throws Exception {
if (!isSharedIOReactorInitiated.get()) {
if (passThroughListenerConfiguration != null) {
//create separate IO Reactor for external non axis2 transports and share among them
try {
synchronized (this) {
sharedListeningIOReactor = createListeningIOReactor(passThroughListenerConfiguration);
ServerIODispatch serverIODispatch = new MultiListenerServerIODispatch(portServerHandlerMapper,
nHttpServerEventHandler,
passThroughListenerConfiguration.getServerConnFactory());
startIOReactor(sharedListeningIOReactor, serverIODispatch, "HTTP");
isSharedIOReactorInitiated.compareAndSet(false, true);
}
} catch (IOReactorException e) {
throw new IOReactorException("Error occurred when creating shared IO Reactor for non axis2 Listener "
+ endpointName, e);
}
} else {
throw new Exception("Cannot start Endpoint for" + endpointName +
"Axis2 Transport Listeners for PassThrough transport" + " not started correctly or not created the " +
"IOReactor Configuration");
}
}
return sharedListeningIOReactor;
}
private ListeningIOReactor getSharedSSLIOReactor(NHttpServerEventHandler nHttpServerEventHandler,
String endpointName, int port,
SSLConfiguration sslConfiguration) throws Exception {
if (!isSharedSSLIOReactorInitiated.get()) {
if (sslPassThroughListenerConfiguration != null) {
//create separate IO Reactor for external non axis2 transports and share among them
try {
synchronized (this) {
sharedSSLListeningIOReactor = createListeningIOReactor(sslPassThroughListenerConfiguration);
ServerIODispatch serverIODispatch = new MultiListenerSSLServerIODispatch(portServerHandlerMapper,
nHttpServerEventHandler,
serverConnectionFactoryMapper);
startIOReactor(sharedSSLListeningIOReactor, serverIODispatch, "HTTPS");
isSharedSSLIOReactorInitiated.compareAndSet(false, true);
}
} catch (IOReactorException e) {
throw new IOReactorException("Error occurred when creating shared IO Reactor for non axis2 Listener "
+ endpointName, e);
}
} else {
throw new Exception("Cannot start Endpoint for" + endpointName +
"Axis2 SSL Transport Listeners for PassThrough transport" + " not started correctly or not created the " +
"IOReactor Configuration");
}
}
ServerConnFactory serverConnFactory = SSLConnectionUtils.
getServerConnectionFactory(endpointName, sslPassThroughListenerConfiguration,
sslConfiguration);
if (serverConnectionFactoryMapper.get(port) != null) {
throw new Exception("Cannot create ServerConnectionFactory for " + endpointName + "in port " + port +
"already registered a server connection factory ");
} else {
serverConnectionFactoryMapper.put(port, serverConnFactory);
}
return sharedSSLListeningIOReactor;
}
private ListeningIOReactor createListeningIOReactor(
PassThroughSharedListenerConfiguration passThroughSharedListenerConfiguration) throws IOReactorException {
try {
return new DefaultListeningIOReactor(
passThroughSharedListenerConfiguration.getSourceConfiguration().getIOReactorConfig(),
passThroughSharedListenerConfiguration.getThreadFactory());
} catch (IOReactorException e) {
throw new IOReactorException
("Error creating DefaultListingIOReactor, ioReactorConfig or thread factory may have problems", e);
}
}
private ListenerEndpoint startEndpoint(InetSocketAddress inetSocketAddress,
ListeningIOReactor defaultListeningIOReactor, String endPointName)
throws Exception {
ListenerEndpoint endpoint = defaultListeningIOReactor.listen(inetSocketAddress);
try {
endpoint.waitFor();
InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
if (!address.isUnresolved()) {
log.info((endPointName != null ? "Pass-through " + endPointName : " Pass-through Http ") +
" Listener started on " + address.getHostName() + ":" + address.getPort());
} else {
log.info((endPointName != null ? "Pass-through " + endPointName : " Pass-through Http ") +
" Listener started on " + address);
}
} catch (Exception e) {
throw new Exception("Endpoint does not start for port " + inetSocketAddress.getPort() +
"May be IO Reactor not started or endpoint binding exception ", e);
}
return endpoint;
}
private ListeningIOReactor shutdownReactor(int port) {
ListeningIOReactor listeningIOReactor = passThroughListenerIOReactorMapper.get(port);
ServerIODispatch serverIODispatch = passThroughListenerServerIODispatchMapper.get(port);
if (listeningIOReactor != null) {
if (serverIODispatch instanceof MultiListenerServerIODispatch ||
serverIODispatch instanceof MultiListenerSSLServerIODispatch) {
log.info("Shutting down shared IO Reactor bind for port " + port + " will be caused for shutdown non " +
"axis2 Listeners ");
} else {
log.info("Shutting down IO Reactor bind for port " + port);
}
} else {
log.error("Cannot find Pass Through Listener for port " + port);
}
return listeningIOReactor;
}
/**
* Check whether dynamic endpoint is running for a particular port
*
* @param port port
* @return whether dynamic endpoint is running for a particular port
*/
public boolean isDynamicEndpointRunning(int port) {
return dynamicPTTListeningEndpointMapper.get(port) != null ;
}
}