Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
@@ -0,0 +1,63 @@
package org.opentripplanner.apis;

import io.micrometer.core.instrument.Tag;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MultivaluedMap;
import java.util.Collection;

public final class TracingUtils {

private static final String UNKNOWN_VALUE = "__UNKNOWN__";

/**
* This method tries to find a tracing tag from a request's headers.
* If no value is found for a tag, the value is set to "__UNKNOWN__".
*
* @param tracingHeaderTags a collection of tag names to match against headers
* @param headers headers from a request
* @return a list of tracing tags with computed values
*/
public static Iterable<Tag> findTagsInHeaders(
Collection<String> tracingHeaderTags,
HttpHeaders headers
) {
return tracingHeaderTags
.stream()
.map(header -> {
String value = headers.getHeaderString(header);
return Tag.of(header, value == null ? UNKNOWN_VALUE : value);
})
.toList();
}

/**
* This method tries to find a tracing tag from either a request's headers or query parameters.
* The value from headers is favored if a value is present in both.
* If no value is found for a tag, the value is set to "__UNKNOWN__".
*
* @param tracingTags a collection of tag names to match against headers or query parameters
* @param headers headers from a request
* @param queryParameters query parameters from a request
* @return a list of tracing tags with computed values
*/
public static Iterable<Tag> findTagsInHeadersOrQueryParameters(
Collection<String> tracingTags,
HttpHeaders headers,
MultivaluedMap<String, String> queryParameters
) {
return tracingTags
.stream()
.map(header -> {
String headerValue = headers.getHeaderString(header);
String queryParameterValue = queryParameters.getFirst(header);
if (headerValue != null) {
return Tag.of(header, headerValue);
} else if (queryParameterValue != null) {
return Tag.of(header, queryParameterValue);
} else {
return Tag.of(header, UNKNOWN_VALUE);
}
})
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.opentripplanner.apis.gtfs;

import java.util.Collection;
import org.opentripplanner.ext.actuator.MicrometerGraphQLInstrumentation;

/**
* GTFS API parameters. These parameters configure the behaviour of some aspects of the
* GTFS GraphQL API.
*/
public interface GtfsApiParameters {
/**
* Which HTTP headers or query parameters should be used as tags for performance metering in the
* Actuator API.
*
* @see MicrometerGraphQLInstrumentation
*/
Collection<String> tracingTags();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.opentripplanner.apis.TracingUtils;
import org.opentripplanner.standalone.api.OtpServerRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -50,12 +54,13 @@ public GtfsGraphQLAPIOldPath(
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response getGraphQL(
HashMap<String, Object> queryParameters,
HashMap<String, Object> jsonParameters,
@HeaderParam("OTPTimeout") @DefaultValue("30000") int timeout,
@HeaderParam("OTPMaxResolves") @DefaultValue("1000000") int maxResolves,
@Context HttpHeaders headers
@Context HttpHeaders headers,
@Context UriInfo uriInfo
) {
if (queryParameters == null || !queryParameters.containsKey("query")) {
if (jsonParameters == null || !jsonParameters.containsKey("query")) {
LOG.debug("No query found in body");
return Response.status(Response.Status.BAD_REQUEST)
.type(MediaType.TEXT_PLAIN_TYPE)
Expand All @@ -67,9 +72,9 @@ public Response getGraphQL(
? headers.getAcceptableLanguages().get(0)
: serverContext.defaultRouteRequest().preferences().locale();

String query = (String) queryParameters.get("query");
Object queryVariables = queryParameters.getOrDefault("variables", null);
String operationName = (String) queryParameters.getOrDefault("operationName", null);
String query = (String) jsonParameters.get("query");
Object queryVariables = jsonParameters.getOrDefault("variables", null);
String operationName = (String) jsonParameters.getOrDefault("operationName", null);
Map<String, Object> variables;

if (queryVariables instanceof Map) {
Expand All @@ -93,7 +98,12 @@ public Response getGraphQL(
maxResolves,
timeout,
locale,
GraphQLRequestContext.ofServerContext(serverContext)
GraphQLRequestContext.ofServerContext(serverContext),
TracingUtils.findTagsInHeadersOrQueryParameters(
serverContext.gtfsApiParameters().tracingTags(),
headers,
uriInfo.getQueryParameters()
)
);
}

Expand All @@ -103,7 +113,8 @@ public Response getGraphQL(
String query,
@HeaderParam("OTPTimeout") @DefaultValue("30000") int timeout,
@HeaderParam("OTPMaxResolves") @DefaultValue("1000000") int maxResolves,
@Context HttpHeaders headers
@Context HttpHeaders headers,
@Context UriInfo uriInfo
) {
Locale locale = headers.getAcceptableLanguages().size() > 0
? headers.getAcceptableLanguages().get(0)
Expand All @@ -115,7 +126,12 @@ public Response getGraphQL(
maxResolves,
timeout,
locale,
GraphQLRequestContext.ofServerContext(serverContext)
GraphQLRequestContext.ofServerContext(serverContext),
TracingUtils.findTagsInHeadersOrQueryParameters(
serverContext.gtfsApiParameters().tracingTags(),
headers,
uriInfo.getQueryParameters()
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import graphql.execution.instrumentation.ChainedInstrumentation;
import graphql.execution.instrumentation.Instrumentation;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import jakarta.ws.rs.core.Response;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ExecutionException;
Expand All @@ -30,13 +30,14 @@ static ExecutionResult getGraphQLExecutionResult(
int maxResolves,
int timeoutMs,
Locale locale,
GraphQLRequestContext requestContext
GraphQLRequestContext requestContext,
Iterable<Tag> tracingTags
) {
Instrumentation instrumentation = new MaxQueryComplexityInstrumentation(maxResolves);

if (OTPFeature.ActuatorAPI.isOn()) {
instrumentation = new ChainedInstrumentation(
new MicrometerGraphQLInstrumentation(Metrics.globalRegistry, List.of()),
new MicrometerGraphQLInstrumentation(Metrics.globalRegistry, tracingTags),
instrumentation
);
}
Expand Down Expand Up @@ -71,7 +72,8 @@ static Response getGraphQLResponse(
int maxResolves,
int timeoutMs,
Locale locale,
GraphQLRequestContext requestContext
GraphQLRequestContext requestContext,
Iterable<Tag> tracingTags
) {
ExecutionResult executionResult = getGraphQLExecutionResult(
query,
Expand All @@ -80,7 +82,8 @@ static Response getGraphQLResponse(
maxResolves,
timeoutMs,
locale,
requestContext
requestContext,
tracingTags
);

return Response.status(Response.Status.OK)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import org.opentripplanner.apis.TracingUtils;
import org.opentripplanner.apis.support.graphql.injectdoc.ApiDocumentationProfile;
import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper;
import org.opentripplanner.routing.api.request.RouteRequest;
Expand Down Expand Up @@ -134,7 +135,7 @@ public Response getGraphQL(
variables,
operationName,
maxNumberOfResultFields,
getTagsFromHeaders(headers)
TracingUtils.findTagsInHeaders(tracingHeaderTags, headers)
);
}

Expand All @@ -147,7 +148,7 @@ public Response getGraphQL(String query, @Context HttpHeaders headers) {
null,
null,
maxNumberOfResultFields,
getTagsFromHeaders(headers)
TracingUtils.findTagsInHeaders(tracingHeaderTags, headers)
);
}

Expand All @@ -157,14 +158,4 @@ public Response getGraphQLSchema() {
var text = SCHEMA_DOC_HEADER + new SchemaPrinter().print(schema);
return Response.ok().encoding("UTF-8").entity(text).build();
}

private static Iterable<Tag> getTagsFromHeaders(HttpHeaders headers) {
return tracingHeaderTags
.stream()
.map(header -> {
String value = headers.getHeaderString(header);
return Tag.of(header, value == null ? "__UNKNOWN__" : value);
})
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.micrometer.core.instrument.MeterRegistry;
import java.util.List;
import javax.annotation.Nullable;
import org.opentripplanner.apis.gtfs.GtfsApiParameters;
import org.opentripplanner.astar.spi.TraverseVisitor;
import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext;
import org.opentripplanner.ext.flex.FlexParameters;
Expand Down Expand Up @@ -128,6 +129,8 @@ default GraphFinder graphFinder() {

TriasApiParameters triasApiParameters();

GtfsApiParameters gtfsApiParameters();

/* Sandbox modules */

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.fasterxml.jackson.databind.node.MissingNode;
import java.io.Serializable;
import java.util.List;
import org.opentripplanner.apis.gtfs.GtfsApiParameters;
import org.opentripplanner.ext.flex.FlexParameters;
import org.opentripplanner.ext.ridehailing.RideHailingServiceParameters;
import org.opentripplanner.ext.trias.config.TriasApiConfig;
Expand All @@ -20,6 +21,7 @@
import org.opentripplanner.standalone.config.routerconfig.UpdatersConfig;
import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig;
import org.opentripplanner.standalone.config.sandbox.FlexConfig;
import org.opentripplanner.standalone.config.sandbox.GtfsApiConfig;
import org.opentripplanner.standalone.config.sandbox.TransmodelAPIConfig;
import org.opentripplanner.updater.UpdatersParameters;
import org.slf4j.Logger;
Expand Down Expand Up @@ -50,6 +52,7 @@ public class RouterConfig implements Serializable {
private final RideHailingServicesConfig rideHailingConfig;
private final FlexConfig flexConfig;
private final TransmodelAPIConfig transmodelApi;
private final GtfsApiConfig gtfsApi;
private final VectorTileConfig vectorTileConfig;
private final TriasApiParameters triasApiParameters;

Expand All @@ -69,6 +72,7 @@ public RouterConfig(JsonNode node, String source, boolean logUnusedParams) {

this.server = new ServerConfig("server", root);
this.transmodelApi = new TransmodelAPIConfig("transmodelApi", root);
this.gtfsApi = new GtfsApiConfig("gtfsApi", root);
var request = mapDefaultRouteRequest("routingDefaults", root);
this.transitConfig = new TransitRoutingConfig("transit", root, request);
this.routingRequestDefaults = request
Expand Down Expand Up @@ -142,6 +146,10 @@ public TriasApiParameters triasApiParameters() {
return triasApiParameters;
}

public GtfsApiParameters gtfsApiParameters() {
return gtfsApi;
}

public NodeAdapter asNodeAdapter() {
return root;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.opentripplanner.standalone.config.sandbox;

import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_8;

import java.util.Collection;
import java.util.Set;
import org.opentripplanner.apis.gtfs.GtfsApiParameters;
import org.opentripplanner.standalone.config.framework.json.NodeAdapter;

/**
* @see GtfsApiParameters for documentation of parameters
*/
public class GtfsApiConfig implements GtfsApiParameters {

private final Collection<String> tracingTags;

public GtfsApiConfig(String parameterName, NodeAdapter root) {
var c = root
.of(parameterName)
.since(V2_8)
.summary("Configuration for the GTFS GraphQL API.")
.asObject();

tracingTags = c
.of("tracingTags")
.summary("Used to group requests when monitoring OTP.")
.asStringList(Set.of());
}

@Override
public Collection<String> tracingTags() {
return tracingTags;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ OtpServerRequestContext providesServerContext(

var transitRoutingConfig = routerConfig.transitTuningConfig();
var triasApiParameters = routerConfig.triasApiParameters();
var gtfsApiConfig = routerConfig.gtfsApiParameters();
var vectorTileConfig = routerConfig.vectorTileConfig();
var flexParameters = routerConfig.flexParameters();

Expand All @@ -80,6 +81,7 @@ OtpServerRequestContext providesServerContext(
transitRoutingConfig,
transitService,
triasApiParameters,
gtfsApiConfig,
vectorTileConfig,
vehicleParkingService,
vehicleRentalService,
Expand Down
Loading
Loading