Skip to content

Commit

Permalink
Various fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas-sexenian committed Nov 1, 2023
1 parent 2248d84 commit ff70d63
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import org.apache.http.pool.PoolStats;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
Expand All @@ -16,6 +17,7 @@ public class CustomPoolingHttpClientConnectionManager extends PoolingHttpClientC
private final List<IConnectionObserver> observers = new ArrayList<>();

private Set<IdentifiableHttpRoute> storedRoutes = this.getRoutes().stream().map(r -> new IdentifiableHttpRoute(r)).collect(Collectors.toSet());
PoolStats storedStats = this.getTotalStats();

public CustomPoolingHttpClientConnectionManager(Registry<ConnectionSocketFactory> socketFactoryRegistry) {
super(socketFactoryRegistry);
Expand All @@ -27,40 +29,60 @@ public void addObserver(IConnectionObserver observer) {

@Override
public ConnectionRequest requestConnection(HttpRoute route, Object state) {
ConnectionRequest originalRequest;
originalRequest = super.requestConnection(route, state);
if (originalRequest != null){
PoolStats statsBefore = storedStats;
ConnectionRequest connectionRequest = super.requestConnection(route, state);
PoolStats statsAfter = this.getTotalStats();
if (statsBefore.getAvailable() < statsAfter.getAvailable() || statsBefore.getLeased() < statsAfter.getLeased()) {
IdentifiableHttpRoute identifiableHttpRoute = new IdentifiableHttpRoute(route);
storedRoutes.add(identifiableHttpRoute);
notifyConnectionCreated(identifiableHttpRoute);
storedStats = statsAfter;
}
return originalRequest;
return connectionRequest;
}

@Override
public void closeExpiredConnections() {
Set<IdentifiableHttpRoute> beforeClosing = storedRoutes;
Set<IdentifiableHttpRoute> commonRoutes = new HashSet<>();
super.closeExpiredConnections();
Set<HttpRoute> afterClosing = this.getRoutes();

for (IdentifiableHttpRoute route : beforeClosing)
if (!afterClosing.contains(route.getHttpRoute()))
notifyConnectionDestroyed(route);
for (IdentifiableHttpRoute identifiableHttpRoute : beforeClosing){
Boolean found = false;
for (HttpRoute httpRoute : afterClosing){
if (identifiableHttpRoute.equals(httpRoute)){
found = true;
commonRoutes.add(identifiableHttpRoute);
break;
}
}
if (!found) notifyConnectionDestroyed(identifiableHttpRoute);
}

storedRoutes = afterClosing.stream().map(r -> new IdentifiableHttpRoute(r)).collect(Collectors.toSet());
storedRoutes = commonRoutes;
}

@Override
public void closeIdleConnections(long idletime, TimeUnit tunit) {
Set<IdentifiableHttpRoute> beforeClosing = storedRoutes;
Set<IdentifiableHttpRoute> commonRoutes = new HashSet<>();
super.closeIdleConnections(idletime, tunit);
Set<HttpRoute> afterClosing = this.getRoutes();

for (IdentifiableHttpRoute route : beforeClosing)
if (!afterClosing.contains(route.getHttpRoute()))
notifyConnectionDestroyed(route);
for (IdentifiableHttpRoute identifiableHttpRoute : beforeClosing){
Boolean found = false;
for (HttpRoute httpRoute : afterClosing){
if (identifiableHttpRoute.equals(httpRoute)){
found = true;
commonRoutes.add(identifiableHttpRoute);
break;
}
}
if (!found) notifyConnectionDestroyed(identifiableHttpRoute);
}

storedRoutes = afterClosing.stream().map(r -> new IdentifiableHttpRoute(r)).collect(Collectors.toSet());
storedRoutes = commonRoutes;
}

private void notifyConnectionCreated(IdentifiableHttpRoute route) {
Expand Down
13 changes: 7 additions & 6 deletions java/src/main/java/com/genexus/internet/HttpClientJavaLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
import org.apache.http.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.auth.AuthSchemeProvider;
import org.apache.http.auth.AuthScope;
Expand Down Expand Up @@ -68,7 +68,8 @@ public HttpClientJavaLib() {
cookies = new BasicCookieStore();
logger.info("Using apache http client implementation");
streamsToClose = new Vector<>();
connManager.addObserver(this);
if (Application.isJMXEnabled())
((CustomPoolingHttpClientConnectionManager) connManager).addObserver(this);
}

private static void getPoolInstance() {
Expand All @@ -77,12 +78,12 @@ private static void getPoolInstance() {
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE).register("https", getSSLSecureInstance())
.build();
connManager = new CustomPoolingHttpClientConnectionManager(socketFactoryRegistry);
connManager = Application.isJMXEnabled() ? new CustomPoolingHttpClientConnectionManager(socketFactoryRegistry) : new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connManager.setMaxTotal((int) CommonUtil.val(clientCfg.getProperty("Client", "HTTPCLIENT_MAX_SIZE", "1000")));
connManager.setDefaultMaxPerRoute((int) CommonUtil.val(clientCfg.getProperty("Client", "HTTPCLIENT_MAX_PER_ROUTE", "1000")));

if (Application.isJMXEnabled())
HTTPPoolJMX.CreateHTTPPoolJMX(connManager);
HTTPPoolJMX.CreateHTTPPoolJMX((CustomPoolingHttpClientConnectionManager) connManager);
}
else {
connManager.closeExpiredConnections();
Expand All @@ -105,7 +106,7 @@ public void onConnectionDestroyed(IdentifiableHttpRoute route) {
protected void finalize() {
this.closeOpenedStreams();
if (Application.isJMXEnabled())
HTTPPoolJMX.DestroyHTTPPoolJMX(connManager);
HTTPPoolJMX.DestroyHTTPPoolJMX((CustomPoolingHttpClientConnectionManager) connManager);
}

private ConnectionKeepAliveStrategy generateKeepAliveStrategy() {
Expand Down Expand Up @@ -137,7 +138,7 @@ public void setTimeout(int timeout)
}

private static Logger logger = org.apache.logging.log4j.LogManager.getLogger(HttpClientJavaLib.class);
private static CustomPoolingHttpClientConnectionManager connManager = null;
private static PoolingHttpClientConnectionManager connManager = null;
private Integer statusCode = 0;
private String reasonLine = "";
private HttpClientBuilder httpClientBuilder;
Expand Down
16 changes: 14 additions & 2 deletions java/src/main/java/com/genexus/internet/IdentifiableHttpRoute.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
public class IdentifiableHttpRoute {
private HttpRoute httpRoute;
private static int instanceCount = 0;
private int id;
private long id;

public IdentifiableHttpRoute(HttpRoute httpRoute) {
this.httpRoute = httpRoute;
this.id = instanceCount++;;
}

public int getId() {
public long getId() {
return id;
}

Expand All @@ -27,6 +27,18 @@ public String toString() {
", instance id='" + id + '\'' +
'}';
}

@Override
public final boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof HttpRoute))
return false;
HttpRoute that = (HttpRoute) o;
Boolean sameHost = this.getHttpRoute().getTargetHost().getHostName().equals(that.getTargetHost().getHostName());
Boolean samePort = this.getHttpRoute().getTargetHost().getPort() == that.getTargetHost().getPort();
return sameHost && samePort;
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ public class HTTPConnectionJMX implements HTTPConnectionJMXBean{

private static Logger log = org.apache.logging.log4j.LogManager.getLogger(HTTPConnectionJMX.class);

IdentifiableHttpRoute idableHttpRoute;
IdentifiableHttpRoute identifiableHttpRoute;

public HTTPConnectionJMX(IdentifiableHttpRoute httpRoute) {
this.idableHttpRoute = httpRoute;
this.identifiableHttpRoute = httpRoute;
}

static public void CreateHTTPConnectionJMX(IdentifiableHttpRoute connection) {
Expand All @@ -32,10 +32,10 @@ static public void DestroyHTTPConnectionJMX(IdentifiableHttpRoute connection) {
}

public int getPort() {
return idableHttpRoute.getHttpRoute().getTargetHost().getPort();
return identifiableHttpRoute.getHttpRoute().getTargetHost().getPort();
}

public String getHost() {
return idableHttpRoute.getHttpRoute().getTargetHost().getHostName();
return identifiableHttpRoute.getHttpRoute().getTargetHost().getHostName();
}
}
3 changes: 1 addition & 2 deletions java/src/main/java/com/genexus/management/MBeanUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,13 @@ public static void destroyMBean(IdentifiableHttpRoute idableHttpRoute) {
try {
ObjectName name = new ObjectName("com.genexus.management:type=GeneXusApplicationServer.HTTPPool.HTTPConnection,ApplicationName=" + idableHttpRoute.getHttpRoute().getTargetHost().getHostName() + ",Port=" + idableHttpRoute.getHttpRoute().getTargetHost().getPort() + ",Http connection id=" + idableHttpRoute.getId());
registeredObjects.removeElement(name);

mbs.unregisterMBean(name);
}
catch(javax.management.MalformedObjectNameException e) {
System.out.println(e);
}
catch(javax.management.InstanceNotFoundException e) {
System.out.println(e);
// Intentionally left empty because PoolingHttpClientConnectionManager does not provide a concise way of knowing exactly which connections are being destroyed
}
catch(javax.management.MBeanRegistrationException e) {
System.out.println(e);
Expand Down

0 comments on commit ff70d63

Please sign in to comment.