Skip to content

Commit 6a06471

Browse files
committed
Implement configuration option for Quota Project ID
1 parent 43f12dd commit 6a06471

File tree

2 files changed

+36
-24
lines changed

2 files changed

+36
-24
lines changed

gcp-auth-extension/src/main/java/io/opentelemetry/contrib/gcp/auth/GcpAuthAutoConfigurationCustomizerProvider.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,16 @@ public class GcpAuthAutoConfigurationCustomizerProvider
5959
*/
6060
@Override
6161
public void customize(AutoConfigurationCustomizer autoConfiguration) {
62+
GoogleCredentials credentials;
6263
try {
63-
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
64-
autoConfiguration
65-
.addSpanExporterCustomizer(
66-
(exporter, configProperties) -> addAuthorizationHeaders(exporter, credentials))
67-
.addResourceCustomizer(GcpAuthAutoConfigurationCustomizerProvider::customizeResource);
64+
credentials = GoogleCredentials.getApplicationDefault();
6865
} catch (IOException e) {
6966
throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
7067
}
68+
autoConfiguration
69+
.addSpanExporterCustomizer(
70+
(exporter, configProperties) -> addAuthorizationHeaders(exporter, credentials))
71+
.addResourceCustomizer(GcpAuthAutoConfigurationCustomizerProvider::customizeResource);
7172
}
7273

7374
@Override
@@ -100,24 +101,19 @@ private static Map<String, String> getRequiredHeaderMap(GoogleCredentials creden
100101
} catch (IOException e) {
101102
throw new GoogleAuthException(Reason.FAILED_ADC_REFRESH, e);
102103
}
103-
gcpHeaders.put(QUOTA_USER_PROJECT_HEADER, credentials.getQuotaProjectId());
104104
gcpHeaders.put("Authorization", "Bearer " + credentials.getAccessToken().getTokenValue());
105+
String configuredQuotaProjectId =
106+
ConfigurableOption.GOOGLE_CLOUD_QUOTA_PROJECT.getConfiguredValueWithFallback(
107+
credentials::getQuotaProjectId);
108+
if (configuredQuotaProjectId != null && !configuredQuotaProjectId.isEmpty()) {
109+
gcpHeaders.put(QUOTA_USER_PROJECT_HEADER, configuredQuotaProjectId);
110+
}
105111
return gcpHeaders;
106112
}
107113

108114
// Updates the current resource with the attributes required for ingesting OTLP data on GCP.
109115
private static Resource customizeResource(Resource resource, ConfigProperties configProperties) {
110-
String gcpProjectId =
111-
ConfigurableOption.GOOGLE_CLOUD_PROJECT.getConfiguredValueWithFallback(
112-
() -> {
113-
try {
114-
GoogleCredentials googleCredentials = GoogleCredentials.getApplicationDefault();
115-
return googleCredentials.getQuotaProjectId();
116-
} catch (IOException e) {
117-
throw new GoogleAuthException(Reason.FAILED_ADC_RETRIEVAL, e);
118-
}
119-
});
120-
116+
String gcpProjectId = ConfigurableOption.GOOGLE_CLOUD_PROJECT.getConfiguredValue();
121117
Resource res =
122118
Resource.create(
123119
Attributes.of(AttributeKey.stringKey(GCP_USER_PROJECT_ID_KEY), gcpProjectId));

gcp-auth-extension/src/test/java/io/opentelemetry/contrib/gcp/auth/GcpAuthAutoConfigurationCustomizerProviderTest.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
@ExtendWith(MockitoExtension.class)
5959
class GcpAuthAutoConfigurationCustomizerProviderTest {
6060

61+
private static final String DUMMY_GCP_RESOURCE_PROJECT_ID = "my-gcp-resource-project-id";
62+
private static final String DUMMY_GCP_QUOTA_PROJECT_ID = "my-gcp-quota-project-id";
63+
6164
@Mock private GoogleCredentials mockedGoogleCredentials;
6265

6366
@Captor private ArgumentCaptor<Supplier<Map<String, String>>> headerSupplierCaptor;
@@ -77,13 +80,17 @@ class GcpAuthAutoConfigurationCustomizerProviderTest {
7780
@SuppressWarnings("CannotMockMethod")
7881
public void setup() {
7982
MockitoAnnotations.openMocks(this);
80-
Mockito.when(mockedGoogleCredentials.getQuotaProjectId()).thenReturn("test-project");
83+
Mockito.when(mockedGoogleCredentials.getQuotaProjectId())
84+
.thenReturn(DUMMY_GCP_QUOTA_PROJECT_ID);
8185
Mockito.when(mockedGoogleCredentials.getAccessToken())
8286
.thenReturn(new AccessToken("fake", Date.from(Instant.now())));
8387
}
8488

8589
@Test
8690
public void testCustomizerOtlpHttp() {
91+
// Set resource project system property
92+
System.setProperty("google.cloud.project", DUMMY_GCP_RESOURCE_PROJECT_ID);
93+
// Prepare mocks
8794
OtlpHttpSpanExporter mockOtlpHttpSpanExporter = Mockito.mock(OtlpHttpSpanExporter.class);
8895
OtlpHttpSpanExporterBuilder otlpSpanExporterBuilder = OtlpHttpSpanExporter.builder();
8996
OtlpHttpSpanExporterBuilder spyOtlpHttpSpanExporterBuilder =
@@ -116,7 +123,8 @@ public void testCustomizerOtlpHttp() {
116123
Mockito.verify(spyOtlpHttpSpanExporterBuilder, Mockito.times(1))
117124
.setHeaders(headerSupplierCaptor.capture());
118125
assertEquals(2, headerSupplierCaptor.getValue().get().size());
119-
assertThat(verifyAuthHeaders(headerSupplierCaptor.getValue().get())).isTrue();
126+
assertThat(verifyAuthHeadersQuotaProjectPresent(headerSupplierCaptor.getValue().get()))
127+
.isTrue();
120128

121129
Mockito.verify(mockOtlpHttpSpanExporter, Mockito.atLeast(1)).export(Mockito.anyCollection());
122130

@@ -125,7 +133,9 @@ public void testCustomizerOtlpHttp() {
125133
.allSatisfy(
126134
spanData -> {
127135
assertThat(spanData.getResource().getAttributes().asMap())
128-
.containsEntry(AttributeKey.stringKey(GCP_USER_PROJECT_ID_KEY), "test-project")
136+
.containsEntry(
137+
AttributeKey.stringKey(GCP_USER_PROJECT_ID_KEY),
138+
DUMMY_GCP_RESOURCE_PROJECT_ID)
129139
.containsEntry(AttributeKey.stringKey("foo"), "bar");
130140
assertThat(spanData.getAttributes().asMap())
131141
.containsKey(AttributeKey.longKey("work_loop"));
@@ -135,6 +145,9 @@ public void testCustomizerOtlpHttp() {
135145

136146
@Test
137147
public void testCustomizerOtlpGrpc() {
148+
// Set resource project system property
149+
System.setProperty("google.cloud.project", DUMMY_GCP_RESOURCE_PROJECT_ID);
150+
// Prepare mocks
138151
OtlpGrpcSpanExporter mockOtlpGrpcSpanExporter = Mockito.mock(OtlpGrpcSpanExporter.class);
139152
OtlpGrpcSpanExporterBuilder otlpSpanExporterBuilder = OtlpGrpcSpanExporter.builder();
140153
OtlpGrpcSpanExporterBuilder spyOtlpGrpcSpanExporterBuilder =
@@ -166,7 +179,7 @@ public void testCustomizerOtlpGrpc() {
166179
Mockito.verify(spyOtlpGrpcSpanExporterBuilder, Mockito.times(1))
167180
.setHeaders(headerSupplierCaptor.capture());
168181
assertEquals(2, headerSupplierCaptor.getValue().get().size());
169-
verifyAuthHeaders(headerSupplierCaptor.getValue().get());
182+
verifyAuthHeadersQuotaProjectPresent(headerSupplierCaptor.getValue().get());
170183

171184
Mockito.verify(mockOtlpGrpcSpanExporter, Mockito.atLeast(1)).export(Mockito.anyCollection());
172185

@@ -175,7 +188,9 @@ public void testCustomizerOtlpGrpc() {
175188
.allSatisfy(
176189
spanData -> {
177190
assertThat(spanData.getResource().getAttributes().asMap())
178-
.containsEntry(AttributeKey.stringKey(GCP_USER_PROJECT_ID_KEY), "test-project")
191+
.containsEntry(
192+
AttributeKey.stringKey(GCP_USER_PROJECT_ID_KEY),
193+
DUMMY_GCP_RESOURCE_PROJECT_ID)
179194
.containsEntry(AttributeKey.stringKey("foo"), "bar");
180195
assertThat(spanData.getAttributes().asMap())
181196
.containsKey(AttributeKey.longKey("work_loop"));
@@ -215,9 +230,10 @@ public String getName() {
215230
return builder.build().getOpenTelemetrySdk();
216231
}
217232

218-
private static boolean verifyAuthHeaders(Map<String, String> headers) {
233+
private static boolean verifyAuthHeadersQuotaProjectPresent(Map<String, String> headers) {
219234
Set<Entry<String, String>> headerEntrySet = headers.entrySet();
220-
return headerEntrySet.contains(new SimpleEntry<>(QUOTA_USER_PROJECT_HEADER, "test-project"))
235+
return headerEntrySet.contains(
236+
new SimpleEntry<>(QUOTA_USER_PROJECT_HEADER, DUMMY_GCP_QUOTA_PROJECT_ID))
221237
&& headerEntrySet.contains(new SimpleEntry<>("Authorization", "Bearer fake"));
222238
}
223239

0 commit comments

Comments
 (0)