Skip to content

Commit fac7da3

Browse files
chore: misc non-functional cleanup (#9750)
1 parent 3fcc669 commit fac7da3

11 files changed

Lines changed: 195 additions & 103 deletions

File tree

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/channelpool/ChannelPool.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
* A {@link ManagedChannel} that will send requests round-robin via a set of channels.
4848
*
4949
* <p>In addition to spreading requests over a set of child connections, the pool will also actively
50-
* manage the lifecycle of the channels. Currently lifecycle management is limited to pre-emptively
50+
* manage the lifecycle of the channels. Currently, lifecycle management is limited to pre-emptively
5151
* replacing channels every hour. In the future it will dynamically size the pool based on number of
5252
* outstanding requests.
5353
*

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/channelpool/DataChannel.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@
4949
import org.slf4j.Logger;
5050
import org.slf4j.LoggerFactory;
5151

52+
/**
53+
* Decorator for a Bigtable data plane connection to add channel warming via PingAndWarm. Channel
54+
* warming will happen on creation and then every 3 minutes.
55+
*/
5256
public class DataChannel extends ManagedChannel {
5357
private static final Logger LOGGER = LoggerFactory.getLogger(DataChannel.class);
5458

@@ -111,6 +115,8 @@ private void warm() {
111115
return;
112116
}
113117

118+
LOGGER.debug("Warming channel {} with: {}", inner, primingKeys);
119+
114120
List<ListenableFuture<PingAndWarmResponse>> futures =
115121
primingKeys.stream().map(this::sendPingAndWarm).collect(Collectors.toList());
116122

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/channelpool/ResourceCollector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void collect(CallLabels labels) {
3737
try {
3838
PrimingKey.from(labels).ifPresent(k -> primingKeys.put(k, true));
3939
} catch (ParsingException e) {
40-
LOG.atWarn().log("Failed to collect priming request for {}", labels, e);
40+
LOG.warn("Failed to collect priming request for {}", labels, e);
4141
}
4242
}
4343

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/commands/Verify.java

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import com.google.cloud.opentelemetry.metric.GoogleCloudMetricExporter;
3434
import com.google.cloud.opentelemetry.metric.MetricConfiguration;
3535
import com.google.common.collect.ImmutableList;
36-
import com.google.common.net.PercentEscaper;
3736
import com.google.protobuf.ByteString;
3837
import io.grpc.CallCredentials;
3938
import io.grpc.CallOptions;
@@ -49,18 +48,13 @@
4948
import io.grpc.MethodDescriptor;
5049
import io.grpc.StatusRuntimeException;
5150
import io.grpc.auth.MoreCallCredentials;
52-
import io.opentelemetry.api.common.Attributes;
5351
import io.opentelemetry.contrib.gcp.resource.GCPResourceProvider;
5452
import io.opentelemetry.sdk.common.CompletableResultCode;
5553
import io.opentelemetry.sdk.metrics.data.MetricData;
5654
import io.opentelemetry.sdk.metrics.export.MetricExporter;
57-
import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData;
58-
import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData;
59-
import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData;
6055
import io.opentelemetry.sdk.resources.Resource;
61-
import java.time.Duration;
62-
import java.time.Instant;
63-
import java.time.temporal.ChronoUnit;
56+
import java.net.URLEncoder;
57+
import java.nio.charset.StandardCharsets;
6458
import java.util.Iterator;
6559
import java.util.concurrent.Callable;
6660
import java.util.concurrent.TimeUnit;
@@ -123,10 +117,12 @@ private void checkBigtable(CallCredentials callCredentials, String tableName) {
123117

124118
try {
125119
Metadata md = new Metadata();
126-
PercentEscaper escaper = new PercentEscaper("", true);
120+
127121
md.put(
128122
Key.of("x-goog-request-params", Metadata.ASCII_STRING_MARSHALLER),
129-
String.format("table_name=%s&app_profile_id=%s", escaper.escape(tableName), ""));
123+
String.format(
124+
"table_name=%s&app_profile_id=%s",
125+
URLEncoder.encode(tableName, StandardCharsets.UTF_8), ""));
130126

131127
BigtableBlockingStub stub =
132128
BigtableGrpc.newBlockingStub(channel)
@@ -186,43 +182,28 @@ private void checkBigtable(CallCredentials callCredentials, String tableName) {
186182
}
187183

188184
void checkMetrics(Credentials creds) {
189-
Instant end = Instant.now().truncatedTo(ChronoUnit.MINUTES);
190-
Instant start = end.minus(Duration.ofMinutes(1));
185+
MetricConfiguration config =
186+
MetricConfiguration.builder()
187+
.setCredentials(creds)
188+
.setProjectId(metricsProjectId)
189+
.setInstrumentationLibraryLabelsEnabled(false)
190+
.build();
191191

192192
GCPResourceProvider resourceProvider = new GCPResourceProvider();
193193
Resource resource = Resource.create(resourceProvider.getAttributes());
194+
ImmutableList<MetricData> metricData =
195+
ImmutableList.of(MetricsImpl.generateTestPresenceMeasurement(resource));
194196

195-
MetricExporter exporter =
196-
GoogleCloudMetricExporter.createWithConfiguration(
197-
MetricConfiguration.builder()
198-
.setCredentials(creds)
199-
.setProjectId(metricsProjectId)
200-
.setInstrumentationLibraryLabelsEnabled(false)
201-
.build());
197+
try (MetricExporter exporter = GoogleCloudMetricExporter.createWithConfiguration(config)) {
198+
CompletableResultCode result = exporter.export(metricData);
199+
result.join(1, TimeUnit.MINUTES);
202200

203-
ImmutableList<MetricData> metricData =
204-
ImmutableList.of(
205-
ImmutableMetricData.createLongGauge(
206-
resource,
207-
MetricsImpl.INSTRUMENTATION_SCOPE_INFO,
208-
MetricsImpl.METRIC_PRESENCE_NAME,
209-
MetricsImpl.METRIC_PRESENCE_DESC,
210-
MetricsImpl.METRIC_PRESENCE_UNIT,
211-
ImmutableGaugeData.create(
212-
ImmutableList.of(
213-
ImmutableLongPointData.create(
214-
TimeUnit.MILLISECONDS.toNanos(start.toEpochMilli()),
215-
TimeUnit.MILLISECONDS.toNanos(end.toEpochMilli()),
216-
Attributes.empty(),
217-
1L)))));
218-
CompletableResultCode result = exporter.export(metricData);
219-
result.join(1, TimeUnit.MINUTES);
220-
221-
System.out.println("Metrics resource: " + resource);
222-
if (result.isSuccess()) {
223-
System.out.println("Metrics write: OK");
224-
} else {
225-
System.out.println("Metrics write: FAILED: " + result.getFailureThrowable().getMessage());
201+
System.out.println("Metrics resource: " + resource);
202+
if (result.isSuccess()) {
203+
System.out.println("Metrics write: OK");
204+
} else {
205+
System.out.println("Metrics write: FAILED: " + result.getFailureThrowable().getMessage());
206+
}
226207
}
227208
}
228209

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/core/CallLabels.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
*
4242
* <ul>
4343
* <li>{@code x-goog-request-params} - contains the resource and app profile id
44+
* <li>{@code google-cloud-resource-prefix} - the previous version of {@code
45+
* x-goog-request-params}, used as a fallback
46+
* <li>{@code x-goog-cbt-cookie-routing} - an opaque blob used to routing RPCs on the serverside
47+
* <li>{@code bigtable-features} - the client's available features
4448
* <li>{@code x-goog-api-client} - contains the client info of the downstream client
4549
* </ul>
4650
*/
@@ -111,6 +115,7 @@ public static CallLabels create(MethodDescriptor<?, ?> method, Metadata headers)
111115
method, requestParams, legacyResourcePrefix, routingCookie, encodedFeatures, apiClient);
112116
}
113117

118+
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
114119
@VisibleForTesting
115120
public static CallLabels create(
116121
MethodDescriptor<?, ?> method,
@@ -129,6 +134,12 @@ public static CallLabels create(
129134
apiClient);
130135
}
131136

137+
/**
138+
* Extracts the resource name, will use {@link #getRequestParams()} if present, otherwise falls
139+
* back on {@link #getLegacyResourcePrefix()}. If neither is present, {@link Optional#empty()} is
140+
* returned. If there was an issue extracting, a {@link ParsingException} is thrown. In the
141+
* primary case, the value will be url decoded.
142+
*/
132143
public Optional<String> extractResourceName() throws ParsingException {
133144
if (getRequestParams().isEmpty()) {
134145
return getLegacyResourcePrefix();
@@ -167,17 +178,19 @@ public Optional<String> extractResourceName() throws ParsingException {
167178
return resourceName.map(ResourceName::getValue);
168179
}
169180

170-
private static Optional<ResourceNameType> findType(String encodedKey) throws ParsingException {
171-
String decodedKey = percentDecode(encodedKey);
172-
181+
private static Optional<ResourceNameType> findType(String key) {
173182
for (ResourceNameType type : ResourceNameType.values()) {
174-
if (type.name.equals(decodedKey)) {
183+
if (type.name.equals(key)) {
175184
return Optional.of(type);
176185
}
177186
}
178187
return Optional.empty();
179188
}
180189

190+
/**
191+
* Extracts the app profile id from {@link #getRequestParams()}. Returns {@link Optional#empty()}
192+
* if the key is missing. The value will be url decoded.
193+
*/
181194
public Optional<String> extractAppProfileId() throws ParsingException {
182195
String requestParams = getRequestParams().orElse("");
183196

@@ -200,13 +213,17 @@ private static String percentDecode(String s) throws ParsingException {
200213
}
201214
}
202215

216+
/**
217+
* Can be derived from {@link CallLabels} to create a priming request to keep the channel active
218+
* for future RPCs.
219+
*/
203220
@AutoValue
204221
public abstract static class PrimingKey {
205-
abstract Map<String, String> getMetadata();
222+
protected abstract Map<String, String> getMetadata();
206223

207-
abstract String getName();
224+
protected abstract String getName();
208225

209-
abstract Optional<String> getAppProfileId();
226+
protected abstract Optional<String> getAppProfileId();
210227

211228
public static Optional<PrimingKey> from(CallLabels labels) throws ParsingException {
212229
final ImmutableMap.Builder<String, String> md = ImmutableMap.builder();

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/metrics/InstrumentedCallCredentials.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,40 @@
1616

1717
package com.google.cloud.bigtable.examples.proxy.metrics;
1818

19+
import com.google.cloud.bigtable.examples.proxy.channelpool.DataChannel;
20+
import com.google.cloud.bigtable.examples.proxy.core.CallLabels.PrimingKey;
21+
import com.google.cloud.bigtable.examples.proxy.core.ProxyHandler;
1922
import com.google.common.base.Stopwatch;
2023
import io.grpc.CallCredentials;
24+
import io.grpc.CallOptions;
2125
import io.grpc.InternalMayRequireSpecificExecutor;
2226
import io.grpc.Metadata;
27+
import io.grpc.ServerCall;
2328
import io.grpc.Status;
2429
import java.time.Duration;
2530
import java.util.concurrent.Executor;
2631
import java.util.concurrent.TimeUnit;
2732
import javax.annotation.Nullable;
33+
import org.slf4j.Logger;
34+
import org.slf4j.LoggerFactory;
2835

36+
/**
37+
* {@link CallCredentials} decorator that tracks latency for fetching credentials.
38+
*
39+
* <p>This expects that all RPCs that use these credentials embed a {@link Tracer} in the {@link
40+
* io.grpc.CallOptions} using {@link Tracer#injectIntoCallOptions(CallOptions)}.
41+
*
42+
* <p>Known callers:
43+
*
44+
* <ul>
45+
* <li>{@link DataChannel#sendPingAndWarm(PrimingKey)}
46+
* <li>{@link ProxyHandler#startCall(ServerCall, Metadata)}
47+
* </ul>
48+
*/
2949
public class InstrumentedCallCredentials extends CallCredentials
3050
implements InternalMayRequireSpecificExecutor {
51+
private static final Logger LOG = LoggerFactory.getLogger(InstrumentedCallCredentials.class);
52+
3153
private final CallCredentials inner;
3254
private final boolean specificExecutorRequired;
3355

@@ -56,15 +78,21 @@ public void applyRequestMetadata(
5678
new MetadataApplier() {
5779
@Override
5880
public void apply(Metadata headers) {
59-
tracer.onCredentialsFetch(
60-
Status.OK, Duration.ofMillis(stopwatch.elapsed(TimeUnit.MILLISECONDS)));
81+
Duration latency = Duration.ofMillis(stopwatch.elapsed(TimeUnit.MILLISECONDS));
82+
// Most credentials fetches should very fast because they are cached
83+
if (latency.compareTo(Duration.ofMillis(1)) >= 1) {
84+
LOG.debug("Fetching Credentials took {}", latency);
85+
}
86+
tracer.onCredentialsFetch(Status.OK, latency);
6187
applier.apply(headers);
6288
}
6389

6490
@Override
6591
public void fail(Status status) {
66-
tracer.onCredentialsFetch(
67-
status, Duration.ofMillis(stopwatch.elapsed(TimeUnit.MILLISECONDS)));
92+
Duration latency = Duration.ofMillis(stopwatch.elapsed(TimeUnit.MILLISECONDS));
93+
94+
LOG.warn("Failed to fetch Credentials after {}: {}", latency, status);
95+
tracer.onCredentialsFetch(status, latency);
6896
applier.fail(status);
6997
}
7098
});

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/metrics/Metrics.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.grpc.Status;
2222
import java.time.Duration;
2323

24+
/** Interface for tracking measurements across the application. */
2425
public interface Metrics {
2526
MetricsAttributes createAttributes(CallLabels callLabels);
2627

0 commit comments

Comments
 (0)