Skip to content

Commit

Permalink
4.x: Oci integration fixes (#8927)
Browse files Browse the repository at this point in the history
* Fix stack-overflow when getting region from SDK.

* Fixed missed configured option in OciConfig.
Using a custom webclient request to check if IMDS endpoint is valid (as the default that used Region discovery has hardcoded 7 retries and increasing delays between them).
Added config-yaml as a runtime dependency, as without it the OCI configuration does not work.
  • Loading branch information
tomas-langer authored Jul 1, 2024
1 parent 2802c0f commit 8a95d96
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 14 deletions.
10 changes: 7 additions & 3 deletions integrations/oci/oci/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,18 @@
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config-yaml</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.oracle.oci.sdk</groupId>
<artifactId>oci-java-sdk-common</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config-yaml</artifactId>
<scope>test</scope>
<groupId>io.helidon.webclient</groupId>
<artifactId>helidon-webclient</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.common.testing</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@
package io.helidon.integrations.oci;

import java.io.IOException;
import java.lang.System.Logger.Level;
import java.net.InetAddress;
import java.net.URI;
import java.time.Duration;

import io.helidon.common.media.type.MediaTypes;
import io.helidon.http.Status;
import io.helidon.webclient.api.ClientResponseTyped;
import io.helidon.webclient.api.WebClient;

import static io.helidon.integrations.oci.OciConfigSupport.IMDS_HOSTNAME;
import static io.helidon.integrations.oci.OciConfigSupport.IMDS_URI;

/**
* Helper methods for OCI integration.
Expand All @@ -42,17 +49,56 @@ public static boolean imdsAvailable(OciConfig config) {
Duration timeout = config.imdsTimeout();

try {
if (InetAddress.getByName(config.imdsBaseUri().map(URI::getHost).orElse(IMDS_HOSTNAME))
URI imdsUri = config.imdsBaseUri()
.orElse(IMDS_URI);

if (InetAddress.getByName(imdsUri.getHost())
.isReachable((int) timeout.toMillis())) {
return RegionProviderSdk.regionFromImds(config) != null;
return imdsAvailable(config, imdsUri);
}
return false;
} catch (IOException e) {
LOGGER.log(System.Logger.Level.TRACE,
LOGGER.log(Level.TRACE,
"IMDS service is not reachable, or timed out for address: "
+ IMDS_HOSTNAME + ".",
e);
return false;
}
}

private static boolean imdsAvailable(OciConfig config, URI imdsUri) {
// check if the endpoint is available (we have only checked the host/IP address)
int retries = config.imdsDetectRetries().orElse(0);

Exception firstException = null;
Status firstStatus = null;

for (int retry = 0; retry <= retries; retry++) {
try {
ClientResponseTyped<String> response = WebClient.builder()
.connectTimeout(config.imdsTimeout())
.readTimeout(config.imdsTimeout())
.baseUri(imdsUri)
.build()
.get("instance/regionInfo")
.accept(MediaTypes.APPLICATION_JSON)
.request(String.class);
if (response.status() == Status.OK_200) {
return true;
}
firstStatus = firstStatus == null ? response.status() : firstStatus;
} catch (Exception e) {
firstException = firstException == null ? e : firstException;
}
}
String message = "OCI IMDS not available on " + imdsUri;
if (firstException == null) {
LOGGER.log(Level.INFO, message + " Status received: " + firstStatus);
} else {
LOGGER.log(Level.INFO, message + " Exception logged only in TRACE");
LOGGER.log(Level.TRACE, message, firstException);
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ interface OciConfigBlueprint {
*
* @return number of retries, each provider has its own defaults
*/
@Option.Configured
Optional<Integer> imdsDetectRetries();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package io.helidon.integrations.oci;

import java.net.URI;

import io.helidon.builder.api.Prototype;
import io.helidon.common.config.Config;

Expand All @@ -28,6 +30,8 @@ final class OciConfigSupport {
// we do not use the constant, as it is marked as internal, and we only need the IP address anyway
// see com.oracle.bmc.auth.AbstractFederationClientAuthenticationDetailsProviderBuilder.METADATA_SERVICE_BASE_URL
static final String IMDS_HOSTNAME = "169.254.169.254";
@SuppressWarnings("HttpUrlsUsage") // this is a known endpoint available only on OCI instances
static final URI IMDS_URI = URI.create("http://" + IMDS_HOSTNAME + "/opc/v2/");

private OciConfigSupport() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,24 @@ class RegionProviderSdk implements OciRegion {
*/
static Region regionFromImds(OciConfig ociConfig) {
if (HelidonOci.imdsAvailable(ociConfig)) {
Optional<URI> uri = ociConfig.imdsBaseUri();
return uri.map(URI::toString)
.map(Region::getRegionFromImds)
.orElseGet(() -> {
Region.registerFromInstanceMetadataService();
return Region.getRegionFromImds();
});

return regionFromImdsDirect(ociConfig);
}
return null;
}

/**
* Only called when we know imds is available.
*/
static Region regionFromImdsDirect(OciConfig ociConfig) {
Optional<URI> uri = ociConfig.imdsBaseUri();
return uri.map(URI::toString)
.map(Region::getRegionFromImds)
.orElseGet(() -> {
Region.registerFromInstanceMetadataService();
return Region.getRegionFromImds();
});
}

@Override
public Optional<Region> region() {
return region.get();
Expand Down
1 change: 1 addition & 0 deletions integrations/oci/oci/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
requires io.helidon.service.registry;
requires io.helidon.common.config;
requires io.helidon.config;
requires io.helidon.webclient;

requires oci.java.sdk.common;
requires vavr;
Expand Down

0 comments on commit 8a95d96

Please sign in to comment.