Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public RoutingTargetResponse resolveRouting(HttpServletRequest request)
return new RoutingTargetResponse(
new RoutingDestination(routingGroup, cluster, buildUriWithNewCluster(cluster, request), externalUrl),
request);
}).orElse(getRoutingTargetResponse(request));
}).orElseGet(() -> getRoutingTargetResponse(request));

logRewrite(routingTargetResponse.routingDestination().clusterHost(), request);
return routingTargetResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import jakarta.ws.rs.HttpMethod;
import jakarta.ws.rs.WebApplicationException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -108,7 +109,6 @@ void setUp()
config = provideGatewayConfiguration();
httpClient = Mockito.mock(HttpClient.class);
routingManager = Mockito.mock(RoutingManager.class);
when(routingManager.provideBackendConfiguration(any(), any())).thenReturn(new ProxyBackendConfiguration());
request = prepareMockRequest();

// Initialize the handler with the configuration
Expand All @@ -117,6 +117,14 @@ void setUp()
RoutingGroupSelector.byRoutingExternal(httpClient, config.getRoutingRules().getRulesExternalConfiguration(), config.getRequestAnalyzerConfig()), config);
}

@BeforeEach
void resetMocks()
{
Mockito.reset(routingManager);
when(routingManager.provideBackendConfiguration(any(), any())).thenReturn(new ProxyBackendConfiguration());
config.getRoutingRules().getRulesExternalConfiguration().setPropagateErrors(false);
}

@Test
void testBasicHeaderModification()
throws Exception
Expand Down Expand Up @@ -300,6 +308,38 @@ void testPropagateErrorsTrueResponseGroupAndErrorsSet()
.isInstanceOf(WebApplicationException.class);
}

@Test
void testResolveRoutingWithKnownQueryIdAndFailingFallback()
{
// Simulate a request to /ui/query.html?queryId where the query ID is known
// but the fallback routing (getRoutingTargetResponse) would fail because
// there are no backends for the resolved routing group.
// This tests that the eagerly-evaluated fallback does not throw when
// previousCluster is present.
String queryId = "20240101_000000_00001_aaaaa";
String backendUrl = "https://trino-backend.example.com";

HttpServletRequest uiRequest = Mockito.mock(HttpServletRequest.class);
when(uiRequest.getMethod()).thenReturn(HttpMethod.GET);
when(uiRequest.getRequestURI()).thenReturn("/ui/query.html");
when(uiRequest.getQueryString()).thenReturn(queryId);

// Query ID is known — cache returns the backend
when(routingManager.findBackendForQueryId(queryId)).thenReturn(backendUrl);
when(routingManager.findRoutingGroupForQueryId(queryId)).thenReturn("test-group");
when(routingManager.findExternalUrlForQueryId(queryId)).thenReturn(backendUrl);

// Fallback routing would throw (no backends for the routing group)
when(routingManager.provideBackendConfiguration(any(), any()))
.thenThrow(new IllegalStateException("Number of active backends found zero"));

// With orElse(), this throws. With orElseGet(), this succeeds.
// ref: https://github.com/trinodb/trino-gateway/issues/920
RoutingTargetResponse response = handler.resolveRouting(uiRequest);

assertThat(response.routingDestination().clusterHost()).isEqualTo(backendUrl);
}

private RoutingTargetHandler createHandlerWithPropagateErrorsTrue()
{
config.getRoutingRules().getRulesExternalConfiguration().setPropagateErrors(true);
Expand Down