-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new module for resource-detector support library (#276)
* Add new module for resource-detector support library * Rname GCPResource -> GCPResourceProvider * Extract GCPMetadataConfig into support library * Refactor platform detection from resource provider * Refactor platform detection to enhance testing * make EnvironmentVariables package-private * Add license headers to the newly added files * Fix spotless style findings * Remove CloudLocationUtil class * change attribute map to hold string instead of optional values * add tests to verify resource attributes mapping * add javadoc to public classes * add unit test for ServiceLoader discoverability * Remove no-args constructor for simplified testing * Update gradle files to support junit5 testing * Add missing attribute in GKE mapping * Add tests for resources-support library * Update copyright year in GoogleCloudRun.java * Add missing newline * Update resource-detector tests to JUnit5 * Remove non-GCP attributes from GKE detection * Add missing attributes in detected GCE environment * Update tests for GAE * Add CLOUD_ACCOUNT_ID to all supported platforms * Rename support package: detectors -> detection Support library was using the same package as the detectors library. This rename would avoid potential conflicts and import issues. * Undo breaking changes These breaking chnages can be directly introduced when we contribute the resource detector upstream. This commit adds classes back and marks them deprecated to indicate to the users not to depend on them.
- Loading branch information
Showing
26 changed files
with
1,851 additions
and
410 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
description = 'Support library for Google Cloud Resource Detector' | ||
|
||
dependencies { | ||
testImplementation(testLibraries.assertj) | ||
testImplementation(testLibraries.wiremock) | ||
testImplementation(testLibraries.mockito) | ||
testImplementation(testLibraries.junit5) | ||
testImplementation(testLibraries.junit5_params) | ||
testRuntimeOnly(testLibraries.junit5_runtime) | ||
} | ||
|
||
afterEvaluate { | ||
tasks.named("compileJava"){ | ||
options.release = 8 | ||
} | ||
} | ||
|
||
test { | ||
// required for discovering JUnit 5 tests | ||
useJUnitPlatform() | ||
} |
60 changes: 60 additions & 0 deletions
60
...sources-support/src/main/java/com/google/cloud/opentelemetry/detection/AttributeKeys.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.google.cloud.opentelemetry.detection; | ||
|
||
/** | ||
* Contains constants that act as keys for the known attributes for {@link | ||
* GCPPlatformDetector.SupportedPlatform}s. | ||
*/ | ||
public final class AttributeKeys { | ||
// GCE Attributes | ||
public static final String GCE_AVAILABILITY_ZONE = AttributeKeys.AVAILABILITY_ZONE; | ||
public static final String GCE_CLOUD_REGION = AttributeKeys.CLOUD_REGION; | ||
public static final String GCE_INSTANCE_ID = AttributeKeys.INSTANCE_ID; | ||
public static final String GCE_INSTANCE_NAME = AttributeKeys.INSTANCE_NAME; | ||
public static final String GCE_MACHINE_TYPE = AttributeKeys.MACHINE_TYPE; | ||
public static final String GCE_INSTANCE_HOSTNAME = "instance_hostname"; | ||
|
||
// GKE Attributes | ||
public static final String GKE_CLUSTER_NAME = "gke_cluster_name"; | ||
public static final String GKE_CLUSTER_LOCATION_TYPE = "gke_cluster_location_type"; | ||
public static final String GKE_CLUSTER_LOCATION = "gke_cluster_location"; | ||
public static final String GKE_HOST_ID = AttributeKeys.INSTANCE_ID; | ||
|
||
// GKE Location Constants | ||
public static final String GKE_LOCATION_TYPE_ZONE = "ZONE"; | ||
public static final String GKE_LOCATION_TYPE_REGION = "REGION"; | ||
|
||
// GAE Attributes | ||
public static final String GAE_MODULE_NAME = "gae_module_name"; | ||
public static final String GAE_APP_VERSION = "gae_app_version"; | ||
public static final String GAE_INSTANCE_ID = AttributeKeys.INSTANCE_ID; | ||
public static final String GAE_AVAILABILITY_ZONE = AttributeKeys.AVAILABILITY_ZONE; | ||
public static final String GAE_CLOUD_REGION = AttributeKeys.CLOUD_REGION; | ||
|
||
// Google Serverless Compute Attributes | ||
public static final String SERVERLESS_COMPUTE_NAME = "serverless_compute_name"; | ||
public static final String SERVERLESS_COMPUTE_REVISION = "serverless_compute_revision"; | ||
public static final String SERVERLESS_COMPUTE_AVAILABILITY_ZONE = AttributeKeys.AVAILABILITY_ZONE; | ||
public static final String SERVERLESS_COMPUTE_CLOUD_REGION = AttributeKeys.CLOUD_REGION; | ||
public static final String SERVERLESS_COMPUTE_INSTANCE_ID = AttributeKeys.INSTANCE_ID; | ||
|
||
static final String AVAILABILITY_ZONE = "availability_zone"; | ||
static final String CLOUD_REGION = "cloud_region"; | ||
static final String INSTANCE_ID = "instance_id"; | ||
static final String INSTANCE_NAME = "instance_name"; | ||
static final String MACHINE_TYPE = "machine_type"; | ||
} |
46 changes: 46 additions & 0 deletions
46
...rces-support/src/main/java/com/google/cloud/opentelemetry/detection/DetectedPlatform.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.google.cloud.opentelemetry.detection; | ||
|
||
import java.util.Map; | ||
|
||
/** Represents a GCP specific platform on which a cloud application can run. */ | ||
public interface DetectedPlatform { | ||
/** | ||
* Method to retrieve the underlying compute platform on which application is running. | ||
* | ||
* @return the {@link GCPPlatformDetector.SupportedPlatform} representing the Google Cloud | ||
* platform on which application is running. | ||
*/ | ||
GCPPlatformDetector.SupportedPlatform getSupportedPlatform(); | ||
|
||
/** | ||
* Method to retrieve the GCP Project ID in which the GCP specific platform exists. Every valid | ||
* platform must have a GCP Project ID associated with it. | ||
* | ||
* @return the Google Cloud project ID. | ||
*/ | ||
String getProjectId(); | ||
|
||
/** | ||
* Method to retrieve the attributes associated with the compute platform on which the application | ||
* is running as key-value pairs. The valid keys to query on this {@link Map} are specified in the | ||
* {@link AttributeKeys}. | ||
* | ||
* @return a {@link Map} of attributes specific to the underlying compute platform. | ||
*/ | ||
Map<String, String> getAttributes(); | ||
} |
33 changes: 33 additions & 0 deletions
33
...-support/src/main/java/com/google/cloud/opentelemetry/detection/EnvironmentVariables.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.google.cloud.opentelemetry.detection; | ||
|
||
/** | ||
* Provides API to fetch environment variables. This is useful in order to create a mock class for | ||
* testing. | ||
*/ | ||
interface EnvironmentVariables { | ||
/** Returns the current environment variables of the platform this is running in. */ | ||
EnvironmentVariables DEFAULT_INSTANCE = System::getenv; | ||
|
||
/** | ||
* Grabs the system environment variable. Returns null on failure. | ||
* | ||
* @param key the key of the environment variable in {@code System.getenv()} | ||
* @return the value received by {@code System.getenv(key)} | ||
*/ | ||
String get(String key); | ||
} |
168 changes: 168 additions & 0 deletions
168
...ces-support/src/main/java/com/google/cloud/opentelemetry/detection/GCPMetadataConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
/* | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.google.cloud.opentelemetry.detection; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.InputStreamReader; | ||
import java.net.HttpURLConnection; | ||
import java.net.URL; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* Retrieves Google Cloud project-id and a limited set of instance attributes from Metadata server. | ||
* | ||
* @see <a href="https://cloud.google.com/compute/docs/storing-retrieving-metadata"> | ||
* https://cloud.google.com/compute/docs/storing-retrieving-metadata</a> | ||
*/ | ||
final class GCPMetadataConfig { | ||
static final GCPMetadataConfig DEFAULT_INSTANCE = new GCPMetadataConfig(); | ||
|
||
private static final String DEFAULT_URL = "http://metadata.google.internal/computeMetadata/v1/"; | ||
private final String url; | ||
private final Map<String, String> cachedAttributes = new HashMap<>(); | ||
|
||
private GCPMetadataConfig() { | ||
this.url = DEFAULT_URL; | ||
} | ||
|
||
// For testing only | ||
GCPMetadataConfig(String url) { | ||
this.url = url; | ||
} | ||
|
||
// Returns null on failure to retrieve from metadata server | ||
String getProjectId() { | ||
return getAttribute("project/project-id"); | ||
} | ||
|
||
/** | ||
* Method to extract cloud availability zone from the metadata server. | ||
* | ||
* <p>Example response: projects/640212054955/zones/australia-southeast1-a | ||
* | ||
* <p>Example zone: australia-southeast1-a | ||
* | ||
* @return the extracted zone from the metadata server response or null in case of failure to | ||
* retrieve from metadata server. | ||
*/ | ||
String getZone() { | ||
String zone = getAttribute("instance/zone"); | ||
if (zone != null && zone.contains("/")) { | ||
zone = zone.substring(zone.lastIndexOf('/') + 1); | ||
} | ||
return zone; | ||
} | ||
|
||
/** | ||
* Use this method only when the region cannot be parsed from the zone. Known use-cases of this | ||
* method involve detecting region in GAE standard environment. | ||
* | ||
* <p>Example response: projects/5689182099321/regions/us-central1. | ||
* | ||
* @return the retrieved region or null in case of failure to retrieve from metadata server | ||
*/ | ||
String getRegion() { | ||
String region = getAttribute("instance/region"); | ||
if (region != null && region.contains("/")) { | ||
region = region.substring(region.lastIndexOf('/') + 1); | ||
} | ||
return region; | ||
} | ||
|
||
/** | ||
* Use this method to parse region from zone. | ||
* | ||
* <p>Example region: australia-southeast1 | ||
* | ||
* @return parsed region from the zone, if zone is not found or is invalid, this method returns | ||
* null. | ||
*/ | ||
String getRegionFromZone() { | ||
String region = null; | ||
String zone = getZone(); | ||
if (zone != null && !zone.isEmpty()) { | ||
// Parsing required to scope up to a region | ||
String[] splitArr = zone.split("-"); | ||
if (splitArr.length > 2) { | ||
region = String.join("-", splitArr[0], splitArr[1]); | ||
} | ||
} | ||
return region; | ||
} | ||
|
||
// Example response: projects/640212054955/machineTypes/e2-medium | ||
String getMachineType() { | ||
String machineType = getAttribute("instance/machine-type"); | ||
if (machineType != null && machineType.contains("/")) { | ||
machineType = machineType.substring(machineType.lastIndexOf('/') + 1); | ||
} | ||
return machineType; | ||
} | ||
|
||
// Returns null on failure to retrieve from metadata server | ||
String getInstanceId() { | ||
return getAttribute("instance/id"); | ||
} | ||
|
||
// Returns null on failure to retrieve from metadata server | ||
String getClusterName() { | ||
return getAttribute("instance/attributes/cluster-name"); | ||
} | ||
|
||
// Returns null on failure to retrieve from metadata server | ||
String getClusterLocation() { | ||
return getAttribute("instance/attributes/cluster-location"); | ||
} | ||
|
||
// Returns null on failure to retrieve from metadata server | ||
String getInstanceHostName() { | ||
return getAttribute("instance/hostname"); | ||
} | ||
|
||
// Returns null on failure to retrieve from metadata server | ||
String getInstanceName() { | ||
return getAttribute("instance/name"); | ||
} | ||
|
||
// Returns null on failure to retrieve from metadata server | ||
private String getAttribute(String attributeName) { | ||
return cachedAttributes.computeIfAbsent(attributeName, this::fetchAttribute); | ||
} | ||
|
||
// Return the attribute received at <attributeName> relative path or null on failure | ||
private String fetchAttribute(String attributeName) { | ||
try { | ||
URL url = new URL(this.url + attributeName); | ||
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); | ||
connection.setRequestProperty("Metadata-Flavor", "Google"); | ||
if (connection.getResponseCode() == 200 | ||
&& ("Google").equals(connection.getHeaderField("Metadata-Flavor"))) { | ||
InputStream input = connection.getInputStream(); | ||
try (BufferedReader reader = | ||
new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) { | ||
return reader.readLine(); | ||
} | ||
} | ||
} catch (IOException ignore) { | ||
// ignore | ||
} | ||
return null; | ||
} | ||
} |
Oops, something went wrong.