Skip to content

Commit

Permalink
refactor: use EndpointKey in BackendHealthStatus
Browse files Browse the repository at this point in the history
  • Loading branch information
NiccoMlt committed Nov 20, 2024
1 parent 0a1306c commit ae4b887
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,24 @@ public ContentSender getCacheSender(ProxyRequest request) {
public static class CachedContent {

HttpClientResponse response;
final List<ByteBuf> chunks = new ArrayList<>();
final long creationTs = System.currentTimeMillis();
final List<ByteBuf> chunks;
final long creationTs;
long lastModified;
long expiresTs = -1;
long expiresTs;
long heapSize;
long directSize;
int hits;

public CachedContent(final long creationTs) {
this.creationTs = creationTs;
this.chunks = new ArrayList<>();
this.expiresTs = -1;
}

public CachedContent() {
this(System.currentTimeMillis());
}

public boolean modifiedSince(ProxyRequest request) {
final long ifModifiedSince = request.getRequestHeaders().getTimeMillis(IF_MODIFIED_SINCE, -1);
return ifModifiedSince == -1 || getLastModified() <= 0 || ifModifiedSince < getLastModified();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,29 +106,33 @@ public void testBackendUnreachableOnStuckRequest(boolean backendsUnreachableOnSt
String s = resp.toString();
System.out.println("s:" + s);
assertEquals("HTTP/1.1 500 Internal Server Error\r\n", resp.getStatusLine());
assertEquals("<html>\n"
+ " <body>\n"
+ " An internal error occurred\n"
+ " </body> \n"
+ "</html>\n", resp.getBodyString());
assertEquals("""
<html>
<body>
An internal error occurred
</body> \s
</html>
""", resp.getBodyString());
}

assertThat((int) ProxyRequestsManager.PENDING_REQUESTS_GAUGE.get(), is(0));
assertThat((int) ProxyRequestsManager.STUCK_REQUESTS_COUNTER.get() > 0, is(true));

assertEquals(backendsUnreachableOnStuckRequests, !server.getBackendHealthManager().isAvailable(key.toString()));
assertEquals(backendsUnreachableOnStuckRequests, !server.getBackendHealthManager().isAvailable(key));

try (RawHttpClient client = new RawHttpClient("localhost", port)) {
RawHttpClient.HttpResponse resp = client.executeRequest("GET /good-index.html HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n");
String s = resp.toString();
System.out.println("s:" + s);
if (backendsUnreachableOnStuckRequests) {
assertEquals("HTTP/1.1 503 Service Unavailable\r\n", resp.getStatusLine());
assertEquals("<html>\n"
+ " <body>\n"
+ " Service Unavailable\n"
+ " </body>\n"
+ "</html>\n", resp.getBodyString());
assertEquals("""
<html>
<body>
Service Unavailable
</body>
</html>
""", resp.getBodyString());
} else {
assertEquals("HTTP/1.1 200 OK\r\n", resp.getStatusLine());
assertEquals("it <b>works</b> !!", resp.getBodyString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*/
package org.carapaceproxy.backends;

import org.carapaceproxy.utils.TestEndpointMapper;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
Expand All @@ -28,18 +27,19 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.github.tomakehurst.wiremock.http.Fault;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import java.util.Arrays;
import java.util.Collection;
import java.util.Properties;
import org.carapaceproxy.configstore.PropertiesConfigurationStore;
import org.carapaceproxy.core.EndpointKey;
import org.carapaceproxy.core.HttpProxyServer;
import org.carapaceproxy.core.ProxyRequestsManager;
import org.carapaceproxy.server.config.NetworkListenerConfiguration;
import org.carapaceproxy.utils.RawHttpClient;
import static org.junit.Assert.assertTrue;
import java.util.Properties;
import org.carapaceproxy.configstore.PropertiesConfigurationStore;
import org.carapaceproxy.core.ProxyRequestsManager;
import org.carapaceproxy.utils.TestEndpointMapper;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
Expand Down Expand Up @@ -96,13 +96,15 @@ public void testWithUnreachableBackend() throws Exception {
String s = resp.toString();
System.out.println("s:" + s);
assertEquals("HTTP/1.1 503 Service Unavailable\r\n", resp.getStatusLine());
assertEquals("<html>\n"
+ " <body>\n"
+ " Service Unavailable\n"
+ " </body>\n"
+ "</html>\n", resp.getBodyString());
assertEquals("""
<html>
<body>
Service Unavailable
</body>
</html>
""", resp.getBodyString());
}
assertFalse(server.getBackendHealthManager().isAvailable(key.toString()));
assertFalse(server.getBackendHealthManager().isAvailable(key));
assertThat((int) ProxyRequestsManager.PENDING_REQUESTS_GAUGE.get(), is(0));
}
}
Expand Down Expand Up @@ -132,13 +134,15 @@ public void testEmptyResponse() throws Exception {
String s = resp.toString();
System.out.println("s:" + s);
assertEquals("HTTP/1.1 503 Service Unavailable\r\n", resp.getStatusLine());
assertEquals("<html>\n"
+ " <body>\n"
+ " Service Unavailable\n"
+ " </body>\n"
+ "</html>\n", resp.getBodyString());
assertEquals("""
<html>
<body>
Service Unavailable
</body>
</html>
""", resp.getBodyString());
}
assertTrue(server.getBackendHealthManager().isAvailable(key.toString())); // no troubles for new connections
assertTrue(server.getBackendHealthManager().isAvailable(key)); // no troubles for new connections
assertThat((int) ProxyRequestsManager.PENDING_REQUESTS_GAUGE.get(), is(0));
}
}
Expand All @@ -162,13 +166,15 @@ public void testConnectionResetByPeer() throws Exception {
String s = resp.toString();
System.out.println("s:" + s);
assertEquals("HTTP/1.1 503 Service Unavailable\r\n", resp.getStatusLine());
assertEquals("<html>\n"
+ " <body>\n"
+ " Service Unavailable\n"
+ " </body>\n"
+ "</html>\n", resp.getBodyString());
assertEquals("""
<html>
<body>
Service Unavailable
</body>
</html>
""", resp.getBodyString());
}
assertTrue(server.getBackendHealthManager().isAvailable(key.toString())); // no troubles for new connections
assertTrue(server.getBackendHealthManager().isAvailable(key)); // no troubles for new connections
assertThat((int) ProxyRequestsManager.PENDING_REQUESTS_GAUGE.get(), is(0));
}
}
Expand Down Expand Up @@ -196,13 +202,15 @@ public void testNonHttpResponseThenClose() throws Exception {
String s = resp.toString();
System.out.println("s:" + s);
assertEquals("HTTP/1.1 503 Service Unavailable\r\n", resp.getStatusLine());
assertEquals("<html>\n"
+ " <body>\n"
+ " Service Unavailable\n"
+ " </body>\n"
+ "</html>\n", resp.getBodyString());
assertEquals("""
<html>
<body>
Service Unavailable
</body>
</html>
""", resp.getBodyString());
}
assertTrue(server.getBackendHealthManager().isAvailable(key.toString()));
assertTrue(server.getBackendHealthManager().isAvailable(key));
assertThat((int) ProxyRequestsManager.PENDING_REQUESTS_GAUGE.get(), is(0));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@
*/
package org.carapaceproxy.server.cache;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
import com.github.benmanes.caffeine.cache.RemovalCause;

import io.netty.buffer.Unpooled;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -29,21 +34,10 @@
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.carapaceproxy.server.cache.ContentsCache.ContentKey;
import org.carapaceproxy.server.cache.ContentsCache.CachedContent;
import org.carapaceproxy.server.cache.ContentsCache.ContentKey;
import org.carapaceproxy.utils.TestUtils;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.After;

import static org.junit.Assert.assertTrue;

import io.netty.buffer.Unpooled;
import org.junit.Test;

/**
Expand Down Expand Up @@ -104,9 +98,8 @@ public CacheEntry(ContentKey key, CachedContent payload, boolean copy) {
this.payload = payload;
} else {
this.key = key;
this.payload = new CachedContent();
this.payload = new CachedContent(payload.creationTs);
this.payload.chunks.addAll(payload.chunks);
TestUtils.setFinalField(this.payload, "creationTs", payload.creationTs);
this.payload.directSize = payload.directSize;
this.payload.expiresTs = payload.expiresTs;
this.payload.heapSize = payload.heapSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
*
* @author enrico.olivelli
*/
@SuppressWarnings("deprecation")
public class XForwardedForFilterTest {

@Rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.carapaceproxy.configstore.PropertiesConfigurationStore;
import org.carapaceproxy.core.EndpointKey;
import org.carapaceproxy.core.HttpProxyServer;
import org.carapaceproxy.core.StaticContentsManager;
import org.carapaceproxy.server.backends.BackendHealthManager;
Expand Down Expand Up @@ -254,8 +255,8 @@ public void testRouteErrors() throws Exception {
PropertiesConfigurationStore config = new PropertiesConfigurationStore(configuration);

BackendHealthManager bhMan = mock(BackendHealthManager.class);
when(bhMan.isAvailable(eq("localhost:" + backend1.port()))).thenReturn(true);
when(bhMan.isAvailable(eq("localhost-down:" + backend1.port()))).thenReturn(false); // simulate unreachable backend -> expected 500 error
when(bhMan.isAvailable(eq(EndpointKey.make("localhost:" + backend1.port())))).thenReturn(true);
when(bhMan.isAvailable(eq(EndpointKey.make("localhost-down:" + backend1.port())))).thenReturn(false); // simulate unreachable backend -> expected 500 error
server.setBackendHealthManager(bhMan);
server.configureAtBoot(config);
server.start();
Expand Down Expand Up @@ -320,8 +321,8 @@ public void testDefaultRoute() throws Exception {
mapper.addRoute(new RouteConfiguration("route-default", "cache", true, new RegexpRequestMatcher(PROPERTY_URI, ".*html")));

BackendHealthManager bhMan = mock(BackendHealthManager.class);
when(bhMan.isAvailable(eq("localhost:" + backendPort))).thenReturn(true);
when(bhMan.isAvailable(eq("localhost-down:" + backendPort))).thenReturn(false); // simulate unreachable backend -> expected 500 error
when(bhMan.isAvailable(eq(EndpointKey.make("localhost:" + backendPort)))).thenReturn(true);
when(bhMan.isAvailable(eq(EndpointKey.make("localhost-down:" + backendPort)))).thenReturn(false); // simulate unreachable backend -> expected 500 error

try (HttpProxyServer server = HttpProxyServer.buildForTests("localhost", 0, mapper, tmpDir.newFolder())) {
server.setBackendHealthManager(bhMan);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package org.carapaceproxy.utils;

import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -29,12 +30,6 @@
import java.util.Arrays;
import java.util.concurrent.Callable;
import org.junit.Assert;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.misc.Unsafe;

/**
* Utility for tests
Expand Down Expand Up @@ -149,58 +144,4 @@ public static <T extends Throwable> T expectThrows(Class<T> expectedThrowable, T
expectedThrowable.getSimpleName());
throw new AssertionError(message);
}

public static void setFinalStaticField(Class clazz, String name, Object newValue) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
int fieldModifiersMask = field.getModifiers();
boolean isFinalModifierPresent = (fieldModifiersMask & Modifier.FINAL) == Modifier.FINAL;
if (isFinalModifierPresent) {
AccessController.doPrivileged((PrivilegedAction) (() -> {
try {
Field field1 = Unsafe.class.getDeclaredField("theUnsafe");
field1.setAccessible(true);
Unsafe unsafe = (Unsafe) field1.get(null);
long offset = unsafe.staticFieldOffset(field);
unsafe.putObject(unsafe.staticFieldBase(field), offset, newValue);
return null;
} catch (Throwable t) {
throw new RuntimeException("Cannot patch final static field " + name + " on " + clazz + " with value " + newValue + ": " + t, t);
}
}));
} else {
field.set(null, newValue);
}
} catch (NoSuchFieldException | SecurityException | IllegalAccessException | IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
}

public static void setFinalField(Object object, String name, Object newValue) {
try {
Field field = object.getClass().getDeclaredField(name);
field.setAccessible(true);
int fieldModifiersMask = field.getModifiers();
boolean isFinalModifierPresent = (fieldModifiersMask & Modifier.FINAL) == Modifier.FINAL;
if (isFinalModifierPresent) {
AccessController.doPrivileged((PrivilegedAction) (() -> {
try {
Field field1 = Unsafe.class.getDeclaredField("theUnsafe");
field1.setAccessible(true);
Unsafe unsafe = (Unsafe) field1.get(null);
long offset = unsafe.objectFieldOffset(field);
unsafe.putObject(object, offset, newValue);
return null;
} catch (Throwable t) {
throw new RuntimeException("Cannot patch final field " + name + " on " + object + " with value " + newValue + ": " + t, t);
}
}));
} else {
field.set(object, newValue);
}
} catch (NoSuchFieldException | SecurityException | IllegalAccessException | IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
}
}

0 comments on commit ae4b887

Please sign in to comment.