Add ConnectionDetail support to Influx auto-configuration

Update Influx auto-configuration so that `InfluxDbConnectionDetails`
beans may be optionally used to provide connection details.

See gh-34657

Co-Authored-By: Mortitz Halbritter <mkammerer@vmware.com>
Co-Authored-By: Phillip Webb <pwebb@vmware.com>
pull/34759/head
Andy Wilkinson 2 years ago
parent 4cc7958c0b
commit d860d875b9

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2022 the original author or authors. * Copyright 2012-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.influx; package org.springframework.boot.autoconfigure.influx;
import java.net.URI;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import org.influxdb.InfluxDB; import org.influxdb.InfluxDB;
import org.influxdb.impl.InfluxDBImpl; import org.influxdb.impl.InfluxDBImpl;
@ -23,11 +25,15 @@ import org.influxdb.impl.InfluxDBImpl;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.Conditional;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for InfluxDB. * {@link EnableAutoConfiguration Auto-configuration} for InfluxDB.
@ -35,6 +41,9 @@ import org.springframework.context.annotation.Bean;
* @author Sergey Kuptsov * @author Sergey Kuptsov
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @since 2.0.0 * @since 2.0.0
*/ */
@AutoConfiguration @AutoConfiguration
@ -44,11 +53,14 @@ public class InfluxDbAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnProperty("spring.influx.url") @Conditional(InfluxDBCondition.class)
public InfluxDB influxDb(InfluxDbProperties properties, ObjectProvider<InfluxDbOkHttpClientBuilderProvider> builder, public InfluxDB influxDb(InfluxDbProperties properties, ObjectProvider<InfluxDbOkHttpClientBuilderProvider> builder,
ObjectProvider<InfluxDbCustomizer> customizers) { ObjectProvider<InfluxDbCustomizer> customizers,
InfluxDB influxDb = new InfluxDBImpl(properties.getUrl(), properties.getUser(), properties.getPassword(), ObjectProvider<InfluxDbConnectionDetails> connectionDetailsProvider) {
determineBuilder(builder.getIfAvailable())); InfluxDbConnectionDetails connectionDetails = connectionDetailsProvider
.getIfAvailable(() -> new PropertiesInfluxDbConnectionDetails(properties));
InfluxDB influxDb = new InfluxDBImpl(connectionDetails.getUrl().toString(), connectionDetails.getUsername(),
connectionDetails.getPassword(), determineBuilder(builder.getIfAvailable()));
customizers.orderedStream().forEach((customizer) -> customizer.customize(influxDb)); customizers.orderedStream().forEach((customizer) -> customizer.customize(influxDb));
return influxDb; return influxDb;
} }
@ -60,4 +72,54 @@ public class InfluxDbAutoConfiguration {
return new OkHttpClient.Builder(); return new OkHttpClient.Builder();
} }
/**
* {@link Condition} that matches when either {@code spring.influx.url} has been set
* or there is an {@link InfluxDbConnectionDetails} bean.
*/
static final class InfluxDBCondition extends AnyNestedCondition {
InfluxDBCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnProperty(prefix = "spring.influx", name = "url")
private static final class InfluxUrlCondition {
}
@ConditionalOnBean(InfluxDbConnectionDetails.class)
private static final class InfluxDbConnectionDetailsCondition {
}
}
/**
* Adapts {@link InfluxDbProperties} to {@link InfluxDbConnectionDetails}.
*/
static class PropertiesInfluxDbConnectionDetails implements InfluxDbConnectionDetails {
private final InfluxDbProperties properties;
PropertiesInfluxDbConnectionDetails(InfluxDbProperties properties) {
this.properties = properties;
}
@Override
public URI getUrl() {
return URI.create(this.properties.getUrl());
}
@Override
public String getUsername() {
return this.properties.getUser();
}
@Override
public String getPassword() {
return this.properties.getPassword();
}
}
} }

@ -0,0 +1,51 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* 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
*
* https://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 org.springframework.boot.autoconfigure.influx;
import java.net.URI;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
/**
* Details required to establish a connection to an InfluxDB service.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @since 3.1.0
*/
public interface InfluxDbConnectionDetails extends ConnectionDetails {
/**
* URL of the InfluxDB instance to which to connect.
* @return the URL of the InfluxDB instance to which to connect
*/
URI getUrl();
/**
* Login user.
* @return the login user or {@code null}
*/
String getUsername();
/**
* Login password.
* @return the login password or {@code null}
*/
String getPassword();
}

@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.influx; package org.springframework.boot.autoconfigure.influx;
import java.net.URI;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@ -38,6 +39,9 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Sergey Kuptsov * @author Sergey Kuptsov
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/ */
class InfluxDbAutoConfigurationTests { class InfluxDbAutoConfigurationTests {
@ -49,6 +53,27 @@ class InfluxDbAutoConfigurationTests {
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(InfluxDB.class)); this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(InfluxDB.class));
} }
@Test
void shouldUseConnectionDetails() {
this.contextRunner.withBean(InfluxDbConnectionDetails.class, this::influxDbConnectionDetails).run((context) -> {
assertThat(context).hasSingleBean(InfluxDB.class);
InfluxDB influxDb = context.getBean(InfluxDB.class);
assertThat(influxDb).hasFieldOrPropertyWithValue("hostName", "localhost");
});
}
@Test
void connectionDetailsOverwriteProperties() {
this.contextRunner.withBean(InfluxDbConnectionDetails.class, this::influxDbConnectionDetails)
.withPropertyValues("spring.influx.url=http://some-other-host", "spring.influx.user=user",
"spring.influx.password=password")
.run((context) -> {
assertThat(context).hasSingleBean(InfluxDB.class);
InfluxDB influxDb = context.getBean(InfluxDB.class);
assertThat(influxDb).hasFieldOrPropertyWithValue("hostName", "localhost");
});
}
@Test @Test
void influxDbCanBeCustomized() { void influxDbCanBeCustomized() {
this.contextRunner this.contextRunner
@ -95,6 +120,27 @@ class InfluxDbAutoConfigurationTests {
return callFactory.readTimeoutMillis(); return callFactory.readTimeoutMillis();
} }
private InfluxDbConnectionDetails influxDbConnectionDetails() {
return new InfluxDbConnectionDetails() {
@Override
public URI getUrl() {
return URI.create("http://localhost");
}
@Override
public String getUsername() {
return "user-1";
}
@Override
public String getPassword() {
return "password-1";
}
};
}
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
static class CustomOkHttpClientBuilderProviderConfig { static class CustomOkHttpClientBuilderProviderConfig {

Loading…
Cancel
Save