/** * Send the request message asynchronously to the given EPR * * @param epr the destination EPR for the message * @param msgContext the message being sent * @throws AxisFault on error */ private void sendAsyncRequest(EndpointReference epr, MessageContext msgContext) throws AxisFault { try { URL url = new URL(epr.getAddress()); String scheme = url.getProtocol() != null ? url.getProtocol() : "http"; String hostname = url.getHost(); int port = url.getPort(); if (port == -1) { // use default if ("http".equals(scheme)) { port = 80; } else if ("https".equals(scheme)) { port = 443; } } HttpHost target = new HttpHost(hostname, port, scheme); boolean secure = "https".equalsIgnoreCase(target.getSchemeName()); HttpHost proxy = proxyConfig.selectProxy(target); HttpRoute route; if (proxy != null) { route = new HttpRoute(target, null, proxy, secure); } else { route = new HttpRoute(target, null, secure); } Axis2HttpRequest axis2Req = new Axis2HttpRequest(epr, route, msgContext); Object timeout = msgContext.getProperty(NhttpConstants.SEND_TIMEOUT); if (timeout != null && timeout instanceof Long) { axis2Req.setTimeout((int) ((Long) timeout).longValue()); } NHttpClientConnection conn = connpool.getConnection(route); // Ensure MessageContext has a ClientConnectionDebug attached before we start streaming ServerConnectionDebug scd = (ServerConnectionDebug) msgContext.getProperty(ServerHandler.SERVER_CONNECTION_DEBUG); ClientConnectionDebug ccd; if (scd != null) { ccd = scd.getClientConnectionDebug(); if (ccd == null) { ccd = new ClientConnectionDebug(scd); scd.setClientConnectionDebug(ccd); } ccd.recordRequestStartTime(conn, axis2Req); msgContext.setProperty(ClientHandler.CLIENT_CONNECTION_DEBUG, ccd); } if (conn == null) { HttpHost host = route.getProxyHost() != null ? route.getProxyHost() : route.getTargetHost(); ioReactor.connect( new InetSocketAddress(host.getHostName(), host.getPort()), null, axis2Req, sessionRequestCallback); if (log.isDebugEnabled()) { log.debug("A new connection established to : " + route); } } else { conn.setSocketTimeout(socketTimeout); // reinitialize timeouts for the pooled connection try { handler.submitRequest(conn, axis2Req); if (log.isDebugEnabled()) { log.debug("An existing connection reused to : " + hostname + ":" + port); } } catch (ConnectionClosedException e) { ioReactor.connect( new InetSocketAddress(hostname, port), null, axis2Req, sessionRequestCallback); if (log.isDebugEnabled()) { log.debug("A new connection established to : " + hostname + ":" + port); } } } try { axis2Req.streamMessageContents(); } catch (AxisFault af) { throw af; } } catch (MalformedURLException e) { handleException("Malformed destination EPR : " + epr.getAddress(), e); } }
/** * Initialize the transport sender, and execute reactor in new separate thread * * @param cfgCtx the Axis2 configuration context * @param transportOut the description of the http/s transport from Axis2 configuration * @throws AxisFault thrown on an error */ public void init(ConfigurationContext cfgCtx, TransportOutDescription transportOut) throws AxisFault { this.configurationContext = cfgCtx; cfg = NHttpConfiguration.getInstance(); params = new BasicHttpParams(); params .setIntParameter( CoreConnectionPNames.SO_TIMEOUT, cfg.getProperty(NhttpConstants.SO_TIMEOUT_SENDER, 60000)) .setIntParameter( CoreConnectionPNames.CONNECTION_TIMEOUT, cfg.getProperty(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000)) .setIntParameter( CoreConnectionPNames.SOCKET_BUFFER_SIZE, cfg.getProperty(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)) .setParameter(CoreProtocolPNames.USER_AGENT, "Synapse-HttpComponents-NIO"); // .setParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET, // // cfg.getStringValue(CoreProtocolPNames.HTTP_ELEMENT_CHARSET,HTTP.DEFAULT_PROTOCOL_CHARSET)); // //TODO:This does not works with HTTPCore 4.3 name = transportOut.getName().toUpperCase(Locale.US) + " Sender"; ClientConnFactoryBuilder contextBuilder = initConnFactoryBuilder(transportOut); connFactory = contextBuilder.createConnFactory(params); connpool = new ConnectionPool(); proxyConfig = new ProxyConfigBuilder().build(transportOut); log.info(proxyConfig.logProxyConfig()); Parameter param = transportOut.getParameter("warnOnHTTP500"); if (param != null) { String[] warnOnHttp500 = ((String) param.getValue()).split("\\|"); cfgCtx.setNonReplicableProperty("warnOnHTTP500", warnOnHttp500); } IOReactorConfig ioReactorConfig = new IOReactorConfig(); ioReactorConfig.setIoThreadCount(NHttpConfiguration.getInstance().getClientIOWorkers()); ioReactorConfig.setSoTimeout(cfg.getProperty(NhttpConstants.SO_TIMEOUT_RECEIVER, 60000)); ioReactorConfig.setConnectTimeout( cfg.getProperty(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000)); ioReactorConfig.setTcpNoDelay(cfg.getProperty(CoreConnectionPNames.TCP_NODELAY, 1) == 1); if (cfg.getBooleanValue("http.nio.interest-ops-queueing", false)) { ioReactorConfig.setInterestOpQueued(true); } try { String prefix = name + " I/O dispatcher"; ioReactor = new DefaultConnectingIOReactor( ioReactorConfig, new NativeThreadFactory(new ThreadGroup(prefix + " thread group"), prefix)); ioReactor.setExceptionHandler( new IOReactorExceptionHandler() { public boolean handle(IOException ioException) { log.warn( "System may be unstable: IOReactor encountered a checked exception : " + ioException.getMessage(), ioException); return true; } public boolean handle(RuntimeException runtimeException) { log.warn( "System may be unstable: IOReactor encountered a runtime exception : " + runtimeException.getMessage(), runtimeException); return true; } }); } catch (IOException e) { log.error("Error starting the IOReactor", e); throw new AxisFault(e.getMessage(), e); } metrics = new NhttpMetricsCollector(false, transportOut.getName()); handler = new ClientHandler(connpool, connFactory, proxyConfig, cfgCtx, params, metrics); iodispatch = new ClientIODispatch(handler, connFactory); final IOEventDispatch ioEventDispatch = iodispatch; // start the Sender in a new seperate thread Thread t = new Thread( new Runnable() { public void run() { try { ioReactor.execute(ioEventDispatch); } catch (InterruptedIOException ex) { log.fatal("Reactor Interrupted"); } catch (IOException e) { log.fatal("Encountered an I/O error: " + e.getMessage(), e); } log.info(name + " Shutdown"); } }, "HttpCoreNIOSender"); t.start(); log.info(name + " starting"); // register with JMX mbeanSupport = new TransportMBeanSupport(this, "nio-" + transportOut.getName()); mbeanSupport.register(); state = BaseConstants.STARTED; }