From c416d40a2b27f00958b5523755a2c27fb5c71a38 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Fri, 11 Aug 2023 09:40:49 -0400 Subject: [PATCH] In support of #7327 --- .../oci/sdk/runtime/OciExtension.java | 59 ++++++++++++++----- .../oci/sdk/runtime/OciConfigTest.java | 10 +++- .../oci/sdk/runtime/OciExtensionTest.java | 26 ++++++++ .../src/test/resources/application.yaml | 18 ++++++ .../runtime/src/test/resources/test-oci.yaml | 3 + 5 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 integrations/oci/sdk/runtime/src/test/resources/application.yaml diff --git a/integrations/oci/sdk/runtime/src/main/java/io/helidon/integrations/oci/sdk/runtime/OciExtension.java b/integrations/oci/sdk/runtime/src/main/java/io/helidon/integrations/oci/sdk/runtime/OciExtension.java index 3bd78530b2c..92c9665479c 100644 --- a/integrations/oci/sdk/runtime/src/main/java/io/helidon/integrations/oci/sdk/runtime/OciExtension.java +++ b/integrations/oci/sdk/runtime/src/main/java/io/helidon/integrations/oci/sdk/runtime/OciExtension.java @@ -18,13 +18,17 @@ import java.nio.file.Paths; import java.util.Arrays; +import java.util.Objects; import java.util.Optional; +import java.util.function.Supplier; import io.helidon.common.LazyValue; import io.helidon.config.Config; import io.helidon.config.ConfigSources; import io.helidon.inject.api.Bootstrap; import io.helidon.inject.api.InjectionServices; +import io.helidon.inject.api.ServiceProvider; +import io.helidon.inject.api.Services; import com.oracle.bmc.auth.AbstractAuthenticationDetailsProvider; @@ -120,13 +124,13 @@ public final class OciExtension { .toList()) .build()); private static String overrideOciConfigFile; - private static OciConfig ociConfig; + private static Supplier ociConfigSupplier; private OciExtension() { } /** - * Returns the global {@link OciConfig} that is currently defined in the bootstrap environment. + * Returns the global {@link OciConfig} bean that is currently defined in the bootstrap environment. *

* The implementation will first look for an {@code oci.yaml} file, and if found will use that file to establish the global * oci-specific bootstrap {@link io.helidon.config.spi.ConfigSource}. @@ -141,16 +145,7 @@ private OciExtension() { * @see OciConfigBlueprint */ public static OciConfig ociConfig() { - if (ociConfig != null) { - return ociConfig; - } - - // we do it this way to allow for the possibility of system and env vars to be used for the auth-strategy definition - // (not advertised in the javadoc) - String ociConfigFile = ociConfigFilename(); - io.helidon.common.config.Config config = Config.create( - ConfigSources.classpath(ociConfigFile).optional(), - ConfigSources.file(Paths.get(ociConfigFile)).optional()); + io.helidon.common.config.Config config = configSupplier().get(); if (!config.exists() || !config.get(OciAuthenticationDetailsProvider.KEY_AUTH_STRATEGY).exists()) { // fallback @@ -173,14 +168,46 @@ public static OciConfig ociConfig() { } } - LOGGER.log(System.Logger.Level.DEBUG, "Using specified oci config"); - ociConfig = OciConfig.create(config); - return ociConfig; + return OciConfig.create(config); + } + + /** + * The supplier for the raw config-backed by the OCI config source(s). + * + * @return the supplier for the raw config-backed by the OCI config source(s) + */ + public static Supplier configSupplier() { + if (ociConfigSupplier == null) { + ociConfigSupplier = () -> { + // we do it this way to allow for the possibility of system and env vars to be used for the auth-strategy definition + // (not advertised in the javadoc) + String ociConfigFile = ociConfigFilename(); + return Config.create( + ConfigSources.classpath(ociConfigFile).optional(), + ConfigSources.file(Paths.get(ociConfigFile)).optional()); + }; + } + + return ociConfigSupplier; + } + + /** + * The supplier for the globally configured authentication provider. + * + * @return the supplier for the globally configured authentication provider + */ + public static Supplier ociAuthenticationProvider() { + return () -> { + Services services = InjectionServices.realizedServices(); + ServiceProvider authProvider = + services.lookupFirst(AbstractAuthenticationDetailsProvider.class); + return Objects.requireNonNull(authProvider.get()); + }; } static void ociConfigFileName(String fileName) { overrideOciConfigFile = fileName; - ociConfig = null; + ociConfigSupplier = null; } static String ociConfigFilename() { diff --git a/integrations/oci/sdk/runtime/src/test/java/io/helidon/integrations/oci/sdk/runtime/OciConfigTest.java b/integrations/oci/sdk/runtime/src/test/java/io/helidon/integrations/oci/sdk/runtime/OciConfigTest.java index f023f286ec1..30d65d5c996 100644 --- a/integrations/oci/sdk/runtime/src/test/java/io/helidon/integrations/oci/sdk/runtime/OciConfigTest.java +++ b/integrations/oci/sdk/runtime/src/test/java/io/helidon/integrations/oci/sdk/runtime/OciConfigTest.java @@ -18,6 +18,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Objects; import io.helidon.config.Config; import io.helidon.config.ConfigSources; @@ -212,15 +213,18 @@ void defaultOciConfigAttributes() { @Test void ociYamlConfigFile() { - // setup + // setup (teardown happens after each run) OciExtension.ociConfigFileName("test-oci.yaml"); OciConfig ociConfig = OciExtension.ociConfig(); assertThat(ociConfig.authStrategy(), optionalValue(equalTo("resource-principal"))); + } - assertSame(ociConfig, - OciExtension.ociConfig(), + @Test + void ociRawConfigShouldBeCached() { + assertSame(Objects.requireNonNull(OciExtension.configSupplier()), + OciExtension.configSupplier(), "The oci configuration from the config source should be cached"); } diff --git a/integrations/oci/sdk/runtime/src/test/java/io/helidon/integrations/oci/sdk/runtime/OciExtensionTest.java b/integrations/oci/sdk/runtime/src/test/java/io/helidon/integrations/oci/sdk/runtime/OciExtensionTest.java index 2daeb9cfbb9..4af679c1cb2 100644 --- a/integrations/oci/sdk/runtime/src/test/java/io/helidon/integrations/oci/sdk/runtime/OciExtensionTest.java +++ b/integrations/oci/sdk/runtime/src/test/java/io/helidon/integrations/oci/sdk/runtime/OciExtensionTest.java @@ -16,18 +16,44 @@ package io.helidon.integrations.oci.sdk.runtime; +import io.helidon.config.Config; +import io.helidon.inject.api.Bootstrap; +import io.helidon.inject.api.InjectionServices; + +import com.oracle.bmc.auth.AbstractAuthenticationDetailsProvider; +import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static io.helidon.inject.testing.InjectionTestingSupport.resetAll; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.sameInstance; class OciExtensionTest { + @BeforeAll + static void setUp() { + InjectionServices.globalBootstrap(Bootstrap.builder().config(Config.create()).build()); + } + + @AfterAll + static void tearDown() { + resetAll(); + } + @Test void ociConfig() { assertThat(OciExtension.ociConfig(), notNullValue()); assertThat(OciExtension.ociConfig(), sameInstance(OciExtension.ociConfig())); } + @Test + void defaultOciAuthenticationProvider() { + AbstractAuthenticationDetailsProvider auth = OciExtension.ociAuthenticationProvider().get(); + assertThat(auth, instanceOf(ConfigFileAuthenticationDetailsProvider.class)); + } + } diff --git a/integrations/oci/sdk/runtime/src/test/resources/application.yaml b/integrations/oci/sdk/runtime/src/test/resources/application.yaml new file mode 100644 index 00000000000..f76545fc15a --- /dev/null +++ b/integrations/oci/sdk/runtime/src/test/resources/application.yaml @@ -0,0 +1,18 @@ +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# +# 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. +# + +inject: + permits-dynamic: true diff --git a/integrations/oci/sdk/runtime/src/test/resources/test-oci.yaml b/integrations/oci/sdk/runtime/src/test/resources/test-oci.yaml index dff6ca17bd7..3569461a37e 100644 --- a/integrations/oci/sdk/runtime/src/test/resources/test-oci.yaml +++ b/integrations/oci/sdk/runtime/src/test/resources/test-oci.yaml @@ -15,3 +15,6 @@ # auth-strategy: "resource-principal" + +inject: + permits-dynamic: true