Apply to both simple-http and netty-http modules.master
@@ -19,7 +19,8 @@ import com.alibaba.csp.sentinel.config.SentinelConfig; | |||||
import com.alibaba.csp.sentinel.log.RecordLog; | import com.alibaba.csp.sentinel.log.RecordLog; | ||||
import com.alibaba.csp.sentinel.util.HostNameUtil; | import com.alibaba.csp.sentinel.util.HostNameUtil; | ||||
import com.alibaba.csp.sentinel.util.StringUtil; | import com.alibaba.csp.sentinel.util.StringUtil; | ||||
import com.alibaba.csp.sentinel.util.function.Tuple2; | |||||
import com.alibaba.csp.sentinel.transport.endpoint.Endpoint; | |||||
import com.alibaba.csp.sentinel.transport.endpoint.Protocol; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -27,6 +28,7 @@ import java.util.List; | |||||
/** | /** | ||||
* @author Carpenter Lee | * @author Carpenter Lee | ||||
* @author Jason Joo | * @author Jason Joo | ||||
* @author Leo Li | |||||
*/ | */ | ||||
public class TransportConfig { | public class TransportConfig { | ||||
@@ -56,20 +58,20 @@ public class TransportConfig { | |||||
} | } | ||||
/** | /** | ||||
* Get a list of (ip/domain, port) indicating Sentinel Dashboard's address.<br> | |||||
* NOTE: only support <b>HTTP</b> protocol | |||||
* Get a list of Endpoint(protocol, ip/domain, port) indicating Sentinel Dashboard's address.<br> | |||||
* NOTE: only support <b>HTTP</b> and <b>HTTPS</b> protocol | |||||
* | * | ||||
* @return list of (ip/domain, port) pair. <br> | |||||
* @return list of Endpoint(protocol, ip/domain, port). <br> | |||||
* <b>May not be null</b>. <br> | * <b>May not be null</b>. <br> | ||||
* An empty list returned when not configured. | * An empty list returned when not configured. | ||||
*/ | */ | ||||
public static List<Tuple2<String, Integer>> getConsoleServerList() { | |||||
public static List<Endpoint> getConsoleServerList() { | |||||
String config = SentinelConfig.getConfig(CONSOLE_SERVER); | String config = SentinelConfig.getConfig(CONSOLE_SERVER); | ||||
List<Tuple2<String, Integer>> list = new ArrayList<Tuple2<String, Integer>>(); | |||||
List<Endpoint> list = new ArrayList<Endpoint>(); | |||||
if (StringUtil.isBlank(config)) { | if (StringUtil.isBlank(config)) { | ||||
return list; | return list; | ||||
} | } | ||||
int pos = -1; | int pos = -1; | ||||
int cur = 0; | int cur = 0; | ||||
while (true) { | while (true) { | ||||
@@ -92,11 +94,16 @@ public class TransportConfig { | |||||
continue; | continue; | ||||
} | } | ||||
ipPortStr = ipPortStr.trim(); | ipPortStr = ipPortStr.trim(); | ||||
int port = 80; | |||||
Protocol protocol = Protocol.HTTP; | |||||
if (ipPortStr.startsWith("http://")) { | if (ipPortStr.startsWith("http://")) { | ||||
ipPortStr = ipPortStr.substring(7); | ipPortStr = ipPortStr.substring(7); | ||||
} else if (ipPortStr.startsWith("https://")) { | |||||
ipPortStr = ipPortStr.substring(8); | |||||
port = 443; | |||||
protocol = Protocol.HTTPS; | |||||
} | } | ||||
int index = ipPortStr.indexOf(":"); | int index = ipPortStr.indexOf(":"); | ||||
int port = 80; | |||||
if (index == 0) { | if (index == 0) { | ||||
// skip | // skip | ||||
continue; | continue; | ||||
@@ -115,7 +122,7 @@ public class TransportConfig { | |||||
} | } | ||||
host = ipPortStr.substring(0, index); | host = ipPortStr.substring(0, index); | ||||
} | } | ||||
list.add(Tuple2.of(host, port)); | |||||
list.add(new Endpoint(protocol, host, port)); | |||||
} | } | ||||
return list; | return list; | ||||
} | } | ||||
@@ -0,0 +1,49 @@ | |||||
package com.alibaba.csp.sentinel.transport.endpoint; | |||||
import java.net.InetSocketAddress; | |||||
/** | |||||
* @author Leo Li | |||||
*/ | |||||
public class Endpoint { | |||||
private Protocol protocol; | |||||
private String host; | |||||
private int port; | |||||
public Endpoint(Protocol protocol, String host, int port) { | |||||
this.protocol = protocol; | |||||
this.host = host; | |||||
this.port = port; | |||||
} | |||||
public Protocol getProtocol() { | |||||
return protocol; | |||||
} | |||||
public void setProtocol(Protocol protocol) { | |||||
this.protocol = protocol; | |||||
} | |||||
public String getHost() { | |||||
return host; | |||||
} | |||||
public void setHost(String host) { | |||||
this.host = host; | |||||
} | |||||
public int getPort() { | |||||
return port; | |||||
} | |||||
public void setPort(int port) { | |||||
this.port = port; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "Endpoint{" + "protocol=" + protocol + ", host='" + host + ", port=" + port + '}'; | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
package com.alibaba.csp.sentinel.transport.endpoint; | |||||
/** | |||||
* @author Leo Li | |||||
*/ | |||||
public enum Protocol { | |||||
HTTP("http"), | |||||
HTTPS("https"); | |||||
private String protocol; | |||||
Protocol(String protocol) { | |||||
this.protocol = protocol; | |||||
} | |||||
public String getProtocol() { | |||||
return protocol; | |||||
} | |||||
} |
@@ -0,0 +1,58 @@ | |||||
package com.alibaba.csp.sentinel.transport.ssl; | |||||
import java.security.cert.CertificateException; | |||||
import java.security.cert.X509Certificate; | |||||
import javax.net.ssl.SSLContext; | |||||
import javax.net.ssl.TrustManager; | |||||
import javax.net.ssl.X509TrustManager; | |||||
import com.alibaba.csp.sentinel.log.RecordLog; | |||||
/** | |||||
* @author Leo Li | |||||
*/ | |||||
public class SslFactory { | |||||
private static class SslContextInstance { | |||||
private static final SSLContext SSL_CONTEXT = initSslContext(); | |||||
} | |||||
private static SSLContext initSslContext() { | |||||
SSLContext sslContext = null; | |||||
try { | |||||
sslContext = SSLContext.getInstance("TLS"); | |||||
X509TrustManager x509TrustManager = new X509TrustManager() { | |||||
public boolean isServerTrusted(X509Certificate[] certs) { | |||||
return true; | |||||
} | |||||
public boolean isClientTrusted(X509Certificate[] certs) { | |||||
return true; | |||||
} | |||||
@Override | |||||
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { | |||||
} | |||||
@Override | |||||
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { | |||||
} | |||||
@Override | |||||
public X509Certificate[] getAcceptedIssuers() { | |||||
return null; | |||||
} | |||||
}; | |||||
sslContext.init(null, new TrustManager[] { x509TrustManager }, null); | |||||
} catch (Exception e) { | |||||
RecordLog.error("get ssl socket factory error", e); | |||||
} | |||||
return sslContext; | |||||
} | |||||
public static SSLContext getSslConnectionSocketFactory() { | |||||
return SslContextInstance.SSL_CONTEXT; | |||||
} | |||||
} |
@@ -17,7 +17,8 @@ package com.alibaba.csp.sentinel.transport.config; | |||||
import com.alibaba.csp.sentinel.config.SentinelConfig; | import com.alibaba.csp.sentinel.config.SentinelConfig; | ||||
import com.alibaba.csp.sentinel.util.StringUtil; | import com.alibaba.csp.sentinel.util.StringUtil; | ||||
import com.alibaba.csp.sentinel.util.function.Tuple2; | |||||
import com.alibaba.csp.sentinel.transport.endpoint.Endpoint; | |||||
import com.alibaba.csp.sentinel.transport.endpoint.Protocol; | |||||
import org.junit.After; | import org.junit.After; | ||||
import org.junit.Before; | import org.junit.Before; | ||||
@@ -90,7 +91,7 @@ public class TransportConfigTest { | |||||
public void testGetConsoleServerList() { | public void testGetConsoleServerList() { | ||||
// empty | // empty | ||||
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, ""); | SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, ""); | ||||
List<Tuple2<String, Integer>> list = TransportConfig.getConsoleServerList(); | |||||
List<Endpoint> list = TransportConfig.getConsoleServerList(); | |||||
assertNotNull(list); | assertNotNull(list); | ||||
assertEquals(0, list.size()); | assertEquals(0, list.size()); | ||||
@@ -99,38 +100,38 @@ public class TransportConfigTest { | |||||
list = TransportConfig.getConsoleServerList(); | list = TransportConfig.getConsoleServerList(); | ||||
assertNotNull(list); | assertNotNull(list); | ||||
assertEquals(1, list.size()); | assertEquals(1, list.size()); | ||||
assertEquals("112.13.223.3", list.get(0).r1); | |||||
assertEquals(new Integer(80), list.get(0).r2); | |||||
assertEquals("112.13.223.3", list.get(0).getHost()); | |||||
assertEquals(80, list.get(0).getPort()); | |||||
// single domain | // single domain | ||||
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org"); | SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org"); | ||||
list = TransportConfig.getConsoleServerList(); | list = TransportConfig.getConsoleServerList(); | ||||
assertNotNull(list); | assertNotNull(list); | ||||
assertEquals(1, list.size()); | assertEquals(1, list.size()); | ||||
assertEquals("www.dashboard.org", list.get(0).r1); | |||||
assertEquals(new Integer(80), list.get(0).r2); | |||||
assertEquals("www.dashboard.org", list.get(0).getHost()); | |||||
assertEquals(80, list.get(0).getPort()); | |||||
// single ip including port | // single ip including port | ||||
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:81"); | SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:81"); | ||||
list = TransportConfig.getConsoleServerList(); | list = TransportConfig.getConsoleServerList(); | ||||
assertNotNull(list); | assertNotNull(list); | ||||
assertEquals(1, list.size()); | assertEquals(1, list.size()); | ||||
assertEquals("www.dashboard.org", list.get(0).r1); | |||||
assertEquals(new Integer(81), list.get(0).r2); | |||||
assertEquals("www.dashboard.org", list.get(0).getHost()); | |||||
assertEquals(81, list.get(0).getPort()); | |||||
// mixed | // mixed | ||||
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:81,112.13.223.3,112.13.223.4:8080,www.dashboard.org"); | SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:81,112.13.223.3,112.13.223.4:8080,www.dashboard.org"); | ||||
list = TransportConfig.getConsoleServerList(); | list = TransportConfig.getConsoleServerList(); | ||||
assertNotNull(list); | assertNotNull(list); | ||||
assertEquals(4, list.size()); | assertEquals(4, list.size()); | ||||
assertEquals("www.dashboard.org", list.get(0).r1); | |||||
assertEquals(new Integer(81), list.get(0).r2); | |||||
assertEquals("112.13.223.3", list.get(1).r1); | |||||
assertEquals(new Integer(80), list.get(1).r2); | |||||
assertEquals("112.13.223.4", list.get(2).r1); | |||||
assertEquals(new Integer(8080), list.get(2).r2); | |||||
assertEquals("www.dashboard.org", list.get(3).r1); | |||||
assertEquals(new Integer(80), list.get(3).r2); | |||||
assertEquals("www.dashboard.org", list.get(0).getHost()); | |||||
assertEquals(81, list.get(0).getPort()); | |||||
assertEquals("112.13.223.3", list.get(1).getHost()); | |||||
assertEquals(80, list.get(1).getPort()); | |||||
assertEquals("112.13.223.4", list.get(2).getHost()); | |||||
assertEquals(8080, list.get(2).getPort()); | |||||
assertEquals("www.dashboard.org", list.get(3).getHost()); | |||||
assertEquals(80, list.get(3).getPort()); | |||||
// malformed | // malformed | ||||
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:0"); | SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "www.dashboard.org:0"); | ||||
@@ -162,7 +163,18 @@ public class TransportConfigTest { | |||||
list = TransportConfig.getConsoleServerList(); | list = TransportConfig.getConsoleServerList(); | ||||
assertNotNull(list); | assertNotNull(list); | ||||
assertEquals(1, list.size()); | assertEquals(1, list.size()); | ||||
assertEquals("www.dashboard.org", list.get(0).r1); | |||||
assertEquals(new Integer(81), list.get(0).r2); | |||||
assertEquals("www.dashboard.org", list.get(0).getHost()); | |||||
assertEquals(81, list.get(0).getPort()); | |||||
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "https://www.dashboard.org,http://www.dashboard.org:8080,www.dashboard.org,www.dashboard.org:8080"); | |||||
list = TransportConfig.getConsoleServerList(); | |||||
assertNotNull(list); | |||||
assertEquals(4, list.size()); | |||||
assertEquals(Protocol.HTTPS, list.get(0).getProtocol()); | |||||
assertEquals(Protocol.HTTP, list.get(1).getProtocol()); | |||||
assertEquals(Protocol.HTTP, list.get(2).getProtocol()); | |||||
assertEquals(Protocol.HTTP, list.get(3).getProtocol()); | |||||
assertEquals(443, list.get(0).getPort()); | |||||
assertEquals(80, list.get(2).getPort()); | |||||
} | } | ||||
} | } |
@@ -21,24 +21,26 @@ import com.alibaba.csp.sentinel.log.RecordLog; | |||||
import com.alibaba.csp.sentinel.spi.SpiOrder; | import com.alibaba.csp.sentinel.spi.SpiOrder; | ||||
import com.alibaba.csp.sentinel.transport.HeartbeatSender; | import com.alibaba.csp.sentinel.transport.HeartbeatSender; | ||||
import com.alibaba.csp.sentinel.transport.config.TransportConfig; | import com.alibaba.csp.sentinel.transport.config.TransportConfig; | ||||
import com.alibaba.csp.sentinel.transport.endpoint.Protocol; | |||||
import com.alibaba.csp.sentinel.transport.heartbeat.client.HttpClientsFactory; | |||||
import com.alibaba.csp.sentinel.util.AppNameUtil; | import com.alibaba.csp.sentinel.util.AppNameUtil; | ||||
import com.alibaba.csp.sentinel.util.HostNameUtil; | import com.alibaba.csp.sentinel.util.HostNameUtil; | ||||
import com.alibaba.csp.sentinel.util.PidUtil; | import com.alibaba.csp.sentinel.util.PidUtil; | ||||
import com.alibaba.csp.sentinel.util.StringUtil; | import com.alibaba.csp.sentinel.util.StringUtil; | ||||
import com.alibaba.csp.sentinel.util.function.Tuple2; | |||||
import com.alibaba.csp.sentinel.transport.endpoint.Endpoint; | |||||
import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
import org.apache.http.client.methods.HttpGet; | import org.apache.http.client.methods.HttpGet; | ||||
import org.apache.http.client.utils.URIBuilder; | import org.apache.http.client.utils.URIBuilder; | ||||
import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
import org.apache.http.impl.client.HttpClients; | |||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
* @author Eric Zhao | * @author Eric Zhao | ||||
* @author Carpenter Lee | * @author Carpenter Lee | ||||
* @author Leo Li | |||||
*/ | */ | ||||
@SpiOrder(SpiOrder.LOWEST_PRECEDENCE - 100) | @SpiOrder(SpiOrder.LOWEST_PRECEDENCE - 100) | ||||
public class HttpHeartbeatSender implements HeartbeatSender { | public class HttpHeartbeatSender implements HeartbeatSender { | ||||
@@ -54,21 +56,24 @@ public class HttpHeartbeatSender implements HeartbeatSender { | |||||
.setSocketTimeout(timeoutMs) | .setSocketTimeout(timeoutMs) | ||||
.build(); | .build(); | ||||
private final Protocol consoleProtocol; | |||||
private final String consoleHost; | private final String consoleHost; | ||||
private final int consolePort; | private final int consolePort; | ||||
public HttpHeartbeatSender() { | public HttpHeartbeatSender() { | ||||
this.client = HttpClients.createDefault(); | |||||
List<Tuple2<String, Integer>> dashboardList = TransportConfig.getConsoleServerList(); | |||||
List<Endpoint> dashboardList = TransportConfig.getConsoleServerList(); | |||||
if (dashboardList == null || dashboardList.isEmpty()) { | if (dashboardList == null || dashboardList.isEmpty()) { | ||||
RecordLog.info("[NettyHttpHeartbeatSender] No dashboard server available"); | RecordLog.info("[NettyHttpHeartbeatSender] No dashboard server available"); | ||||
consoleProtocol = Protocol.HTTP; | |||||
consoleHost = null; | consoleHost = null; | ||||
consolePort = -1; | consolePort = -1; | ||||
} else { | } else { | ||||
consoleHost = dashboardList.get(0).r1; | |||||
consolePort = dashboardList.get(0).r2; | |||||
consoleProtocol = dashboardList.get(0).getProtocol(); | |||||
consoleHost = dashboardList.get(0).getHost(); | |||||
consolePort = dashboardList.get(0).getPort(); | |||||
RecordLog.info("[NettyHttpHeartbeatSender] Dashboard address parsed: <{}:{}>", consoleHost, consolePort); | RecordLog.info("[NettyHttpHeartbeatSender] Dashboard address parsed: <{}:{}>", consoleHost, consolePort); | ||||
} | } | ||||
this.client = HttpClientsFactory.getHttpClientsByProtocol(consoleProtocol); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -77,7 +82,7 @@ public class HttpHeartbeatSender implements HeartbeatSender { | |||||
return false; | return false; | ||||
} | } | ||||
URIBuilder uriBuilder = new URIBuilder(); | URIBuilder uriBuilder = new URIBuilder(); | ||||
uriBuilder.setScheme("http").setHost(consoleHost).setPort(consolePort) | |||||
uriBuilder.setScheme(consoleProtocol.getProtocol()).setHost(consoleHost).setPort(consolePort) | |||||
.setPath(TransportConfig.getHeartbeatApiPath()) | .setPath(TransportConfig.getHeartbeatApiPath()) | ||||
.setParameter("app", AppNameUtil.getAppName()) | .setParameter("app", AppNameUtil.getAppName()) | ||||
.setParameter("app_type", String.valueOf(SentinelConfig.getAppType())) | .setParameter("app_type", String.valueOf(SentinelConfig.getAppType())) | ||||
@@ -0,0 +1,23 @@ | |||||
package com.alibaba.csp.sentinel.transport.heartbeat.client; | |||||
import com.alibaba.csp.sentinel.transport.endpoint.Protocol; | |||||
import com.alibaba.csp.sentinel.transport.ssl.SslFactory; | |||||
import org.apache.http.conn.ssl.NoopHostnameVerifier; | |||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||||
import org.apache.http.impl.client.CloseableHttpClient; | |||||
import org.apache.http.impl.client.HttpClients; | |||||
/** | |||||
* @author Leo Li | |||||
*/ | |||||
public class HttpClientsFactory { | |||||
private static class SslConnectionSocketFactoryInstance { | |||||
private static final SSLConnectionSocketFactory SSL_CONNECTION_SOCKET_FACTORY = new SSLConnectionSocketFactory(SslFactory.getSslConnectionSocketFactory(), NoopHostnameVerifier.INSTANCE); | |||||
} | |||||
public static CloseableHttpClient getHttpClientsByProtocol(Protocol protocol) { | |||||
return protocol == Protocol.HTTP ? HttpClients.createDefault() : HttpClients.custom(). | |||||
setSSLSocketFactory(SslConnectionSocketFactoryInstance.SSL_CONNECTION_SOCKET_FACTORY).build(); | |||||
} | |||||
} |
@@ -21,9 +21,8 @@ import com.alibaba.csp.sentinel.transport.config.TransportConfig; | |||||
import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpClient; | import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpClient; | ||||
import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpRequest; | import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpRequest; | ||||
import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpResponse; | import com.alibaba.csp.sentinel.transport.heartbeat.client.SimpleHttpResponse; | ||||
import com.alibaba.csp.sentinel.util.function.Tuple2; | |||||
import com.alibaba.csp.sentinel.transport.endpoint.Endpoint; | |||||
import java.net.InetSocketAddress; | |||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
@@ -32,6 +31,7 @@ import java.util.List; | |||||
* | * | ||||
* @author Eric Zhao | * @author Eric Zhao | ||||
* @author Carpenter Lee | * @author Carpenter Lee | ||||
* @author Leo Li | |||||
*/ | */ | ||||
public class SimpleHttpHeartbeatSender implements HeartbeatSender { | public class SimpleHttpHeartbeatSender implements HeartbeatSender { | ||||
@@ -42,13 +42,13 @@ public class SimpleHttpHeartbeatSender implements HeartbeatSender { | |||||
private final HeartbeatMessage heartBeat = new HeartbeatMessage(); | private final HeartbeatMessage heartBeat = new HeartbeatMessage(); | ||||
private final SimpleHttpClient httpClient = new SimpleHttpClient(); | private final SimpleHttpClient httpClient = new SimpleHttpClient(); | ||||
private final List<Tuple2<String, Integer>> addressList; | |||||
private final List<Endpoint> addressList; | |||||
private int currentAddressIdx = 0; | private int currentAddressIdx = 0; | ||||
public SimpleHttpHeartbeatSender() { | public SimpleHttpHeartbeatSender() { | ||||
// Retrieve the list of default addresses. | // Retrieve the list of default addresses. | ||||
List<Tuple2<String, Integer>> newAddrs = TransportConfig.getConsoleServerList(); | |||||
List<Endpoint> newAddrs = TransportConfig.getConsoleServerList(); | |||||
if (newAddrs.isEmpty()) { | if (newAddrs.isEmpty()) { | ||||
RecordLog.warn("[SimpleHttpHeartbeatSender] Dashboard server address not configured or not available"); | RecordLog.warn("[SimpleHttpHeartbeatSender] Dashboard server address not configured or not available"); | ||||
} else { | } else { | ||||
@@ -63,24 +63,23 @@ public class SimpleHttpHeartbeatSender implements HeartbeatSender { | |||||
RecordLog.info("[SimpleHttpHeartbeatSender] Command server port not initialized, won't send heartbeat"); | RecordLog.info("[SimpleHttpHeartbeatSender] Command server port not initialized, won't send heartbeat"); | ||||
return false; | return false; | ||||
} | } | ||||
Tuple2<String, Integer> addrInfo = getAvailableAddress(); | |||||
Endpoint addrInfo = getAvailableAddress(); | |||||
if (addrInfo == null) { | if (addrInfo == null) { | ||||
return false; | return false; | ||||
} | } | ||||
InetSocketAddress addr = new InetSocketAddress(addrInfo.r1, addrInfo.r2); | |||||
SimpleHttpRequest request = new SimpleHttpRequest(addr, TransportConfig.getHeartbeatApiPath()); | |||||
SimpleHttpRequest request = new SimpleHttpRequest(addrInfo, TransportConfig.getHeartbeatApiPath()); | |||||
request.setParams(heartBeat.generateCurrentMessage()); | request.setParams(heartBeat.generateCurrentMessage()); | ||||
try { | try { | ||||
SimpleHttpResponse response = httpClient.post(request); | SimpleHttpResponse response = httpClient.post(request); | ||||
if (response.getStatusCode() == OK_STATUS) { | if (response.getStatusCode() == OK_STATUS) { | ||||
return true; | return true; | ||||
} else if (clientErrorCode(response.getStatusCode()) || serverErrorCode(response.getStatusCode())) { | } else if (clientErrorCode(response.getStatusCode()) || serverErrorCode(response.getStatusCode())) { | ||||
RecordLog.warn("[SimpleHttpHeartbeatSender] Failed to send heartbeat to " + addr | |||||
RecordLog.warn("[SimpleHttpHeartbeatSender] Failed to send heartbeat to " + addrInfo | |||||
+ ", http status code: " + response.getStatusCode()); | + ", http status code: " + response.getStatusCode()); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
RecordLog.warn("[SimpleHttpHeartbeatSender] Failed to send heartbeat to " + addr, e); | |||||
RecordLog.warn("[SimpleHttpHeartbeatSender] Failed to send heartbeat to " + addrInfo, e); | |||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
@@ -90,7 +89,7 @@ public class SimpleHttpHeartbeatSender implements HeartbeatSender { | |||||
return DEFAULT_INTERVAL; | return DEFAULT_INTERVAL; | ||||
} | } | ||||
private Tuple2<String, Integer> getAvailableAddress() { | |||||
private Endpoint getAvailableAddress() { | |||||
if (addressList == null || addressList.isEmpty()) { | if (addressList == null || addressList.isEmpty()) { | ||||
return null; | return null; | ||||
} | } | ||||
@@ -26,6 +26,7 @@ import java.util.Map; | |||||
import java.util.Map.Entry; | import java.util.Map.Entry; | ||||
import com.alibaba.csp.sentinel.log.RecordLog; | import com.alibaba.csp.sentinel.log.RecordLog; | ||||
import com.alibaba.csp.sentinel.transport.endpoint.Endpoint; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
@@ -47,6 +48,7 @@ import com.alibaba.csp.sentinel.log.RecordLog; | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author leyou | * @author leyou | ||||
* @author Leo Li | |||||
*/ | */ | ||||
public class SimpleHttpClient { | public class SimpleHttpClient { | ||||
@@ -61,7 +63,7 @@ public class SimpleHttpClient { | |||||
if (request == null) { | if (request == null) { | ||||
return null; | return null; | ||||
} | } | ||||
return request(request.getSocketAddress(), | |||||
return request(request.getEndpoint(), | |||||
RequestMethod.GET, request.getRequestPath(), request.getParams(), | RequestMethod.GET, request.getRequestPath(), request.getParams(), | ||||
request.getCharset(), request.getSoTimeout()); | request.getCharset(), request.getSoTimeout()); | ||||
} | } | ||||
@@ -77,20 +79,21 @@ public class SimpleHttpClient { | |||||
if (request == null) { | if (request == null) { | ||||
return null; | return null; | ||||
} | } | ||||
return request(request.getSocketAddress(), | |||||
return request(request.getEndpoint(), | |||||
RequestMethod.POST, request.getRequestPath(), | RequestMethod.POST, request.getRequestPath(), | ||||
request.getParams(), request.getCharset(), | request.getParams(), request.getCharset(), | ||||
request.getSoTimeout()); | request.getSoTimeout()); | ||||
} | } | ||||
private SimpleHttpResponse request(InetSocketAddress socketAddress, | |||||
private SimpleHttpResponse request(Endpoint endpoint, | |||||
RequestMethod type, String requestPath, | RequestMethod type, String requestPath, | ||||
Map<String, String> paramsMap, Charset charset, int soTimeout) | Map<String, String> paramsMap, Charset charset, int soTimeout) | ||||
throws IOException { | throws IOException { | ||||
Socket socket = null; | Socket socket = null; | ||||
BufferedWriter writer; | BufferedWriter writer; | ||||
InetSocketAddress socketAddress = new InetSocketAddress(endpoint.getHost(), endpoint.getPort()); | |||||
try { | try { | ||||
socket = new Socket(); | |||||
socket = SocketFactory.getSocket(endpoint.getProtocol()); | |||||
socket.setSoTimeout(soTimeout); | socket.setSoTimeout(soTimeout); | ||||
socket.connect(socketAddress, soTimeout); | socket.connect(socketAddress, soTimeout); | ||||
@@ -15,38 +15,39 @@ | |||||
*/ | */ | ||||
package com.alibaba.csp.sentinel.transport.heartbeat.client; | package com.alibaba.csp.sentinel.transport.heartbeat.client; | ||||
import java.net.InetSocketAddress; | |||||
import java.nio.charset.Charset; | import java.nio.charset.Charset; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import com.alibaba.csp.sentinel.config.SentinelConfig; | import com.alibaba.csp.sentinel.config.SentinelConfig; | ||||
import com.alibaba.csp.sentinel.util.StringUtil; | import com.alibaba.csp.sentinel.util.StringUtil; | ||||
import com.alibaba.csp.sentinel.transport.endpoint.Endpoint; | |||||
/** | /** | ||||
* Simple HTTP request representation. | * Simple HTTP request representation. | ||||
* | * | ||||
* @author leyou | * @author leyou | ||||
* @author Leo Li | |||||
*/ | */ | ||||
public class SimpleHttpRequest { | public class SimpleHttpRequest { | ||||
private InetSocketAddress socketAddress; | |||||
private Endpoint endpoint; | |||||
private String requestPath = ""; | private String requestPath = ""; | ||||
private int soTimeout = 3000; | private int soTimeout = 3000; | ||||
private Map<String, String> params; | private Map<String, String> params; | ||||
private Charset charset = Charset.forName(SentinelConfig.charset()); | private Charset charset = Charset.forName(SentinelConfig.charset()); | ||||
public SimpleHttpRequest(InetSocketAddress socketAddress, String requestPath) { | |||||
this.socketAddress = socketAddress; | |||||
public SimpleHttpRequest(Endpoint endpoint, String requestPath) { | |||||
this.endpoint = endpoint; | |||||
this.requestPath = requestPath; | this.requestPath = requestPath; | ||||
} | } | ||||
public InetSocketAddress getSocketAddress() { | |||||
return socketAddress; | |||||
public Endpoint getEndpoint() { | |||||
return endpoint; | |||||
} | } | ||||
public SimpleHttpRequest setSocketAddress(InetSocketAddress socketAddress) { | |||||
this.socketAddress = socketAddress; | |||||
public SimpleHttpRequest setEndpoint(Endpoint endpoint) { | |||||
this.endpoint = endpoint; | |||||
return this; | return this; | ||||
} | } | ||||
@@ -0,0 +1,23 @@ | |||||
package com.alibaba.csp.sentinel.transport.heartbeat.client; | |||||
import java.io.IOException; | |||||
import java.net.Socket; | |||||
import javax.net.ssl.SSLSocketFactory; | |||||
import com.alibaba.csp.sentinel.transport.endpoint.Protocol; | |||||
import com.alibaba.csp.sentinel.transport.ssl.SslFactory; | |||||
/** | |||||
* @author Leo Li | |||||
*/ | |||||
public class SocketFactory { | |||||
private static class SSLSocketFactoryInstance { | |||||
private static final SSLSocketFactory SSL_SOCKET_FACTORY = SslFactory.getSslConnectionSocketFactory().getSocketFactory(); | |||||
} | |||||
public static Socket getSocket(Protocol protocol) throws IOException { | |||||
return protocol == Protocol.HTTP ? new Socket() : SSLSocketFactoryInstance.SSL_SOCKET_FACTORY.createSocket(); | |||||
} | |||||
} |