Polish "Add support for Neo4j Java Driver 6.0.0"
See gh-47381
This commit is contained in:
parent
2542430e5b
commit
6f1bcc4bfa
|
@ -1042,6 +1042,13 @@ management:
|
|||
|
||||
|
||||
|
||||
[[actuator.metrics.supported.neo4j]]
|
||||
=== Neo4j Metrics
|
||||
|
||||
Auto-configuration registers a javadoc:org.neo4j.driver.observation.micrometer.MicrometerObservationProvider[] for the auto-configured javadoc:org.neo4j.driver.Driver[].
|
||||
|
||||
|
||||
|
||||
[[actuator.metrics.supported.jetty]]
|
||||
=== Jetty Metrics
|
||||
|
||||
|
|
|
@ -35,8 +35,9 @@ dependencies {
|
|||
optional(project(":core:spring-boot-docker-compose"))
|
||||
optional(project(":core:spring-boot-testcontainers"))
|
||||
optional(project(":module:spring-boot-health"))
|
||||
optional("org.testcontainers:neo4j")
|
||||
optional(project(":module:spring-boot-micrometer-observation"))
|
||||
optional("org.neo4j.driver:neo4j-java-driver-observation-micrometer")
|
||||
optional("org.testcontainers:neo4j")
|
||||
|
||||
dockerTestImplementation(project(":core:spring-boot-test"))
|
||||
dockerTestImplementation(project(":test-support:spring-boot-docker-test-support"))
|
||||
|
@ -49,6 +50,7 @@ dependencies {
|
|||
testImplementation(project(":core:spring-boot-test"))
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
testImplementation(testFixtures(project(":core:spring-boot-testcontainers")))
|
||||
testImplementation("io.micrometer:micrometer-observation-test")
|
||||
testImplementation("io.projectreactor:reactor-test")
|
||||
|
||||
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||
|
|
|
@ -21,12 +21,9 @@ import java.net.URI;
|
|||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.neo4j.bolt.connection.BoltConnectionProviderFactory;
|
||||
import org.neo4j.driver.AuthToken;
|
||||
import org.neo4j.driver.AuthTokenManager;
|
||||
import org.neo4j.driver.AuthTokens;
|
||||
|
@ -35,7 +32,6 @@ import org.neo4j.driver.Config.TrustStrategy;
|
|||
import org.neo4j.driver.Driver;
|
||||
import org.neo4j.driver.GraphDatabase;
|
||||
import org.neo4j.driver.internal.Scheme;
|
||||
import org.neo4j.driver.observation.micrometer.MicrometerObservationProvider;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
|
@ -48,7 +44,6 @@ import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Authenticati
|
|||
import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Pool;
|
||||
import org.springframework.boot.neo4j.autoconfigure.Neo4jProperties.Security;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
@ -67,20 +62,6 @@ import org.springframework.util.StringUtils;
|
|||
@EnableConfigurationProperties(Neo4jProperties.class)
|
||||
public final class Neo4jAutoConfiguration {
|
||||
|
||||
private static final boolean HAS_DRIVER_METRICS;
|
||||
|
||||
static {
|
||||
boolean metricsObservationProviderFound = true;
|
||||
try {
|
||||
Class.forName("org.neo4j.driver.observation.micrometer.MicrometerObservationProvider", false,
|
||||
Neo4jAutoConfiguration.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
metricsObservationProviderFound = false;
|
||||
}
|
||||
HAS_DRIVER_METRICS = metricsObservationProviderFound;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(Neo4jConnectionDetails.class)
|
||||
PropertiesNeo4jConnectionDetails neo4jConnectionDetails(Neo4jProperties properties,
|
||||
|
@ -90,12 +71,10 @@ public final class Neo4jAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
Driver neo4jDriver(Neo4jProperties properties, Environment environment, Neo4jConnectionDetails connectionDetails,
|
||||
ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers,
|
||||
ObjectProvider<ObservationRegistry> observationRegistryProvider) {
|
||||
|
||||
Driver neo4jDriver(Neo4jProperties properties, Neo4jConnectionDetails connectionDetails,
|
||||
ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers) {
|
||||
Config config = mapDriverConfig(properties, connectionDetails,
|
||||
configBuilderCustomizers.orderedStream().toList(), observationRegistryProvider);
|
||||
configBuilderCustomizers.orderedStream().toList());
|
||||
AuthTokenManager authTokenManager = connectionDetails.getAuthTokenManager();
|
||||
if (authTokenManager != null) {
|
||||
return GraphDatabase.driver(connectionDetails.getUri(), authTokenManager, config);
|
||||
|
@ -105,10 +84,9 @@ public final class Neo4jAutoConfiguration {
|
|||
}
|
||||
|
||||
Config mapDriverConfig(Neo4jProperties properties, Neo4jConnectionDetails connectionDetails,
|
||||
List<ConfigBuilderCustomizer> customizers,
|
||||
ObjectProvider<ObservationRegistry> observationRegistryProvider) {
|
||||
List<ConfigBuilderCustomizer> customizers) {
|
||||
Config.ConfigBuilder builder = Config.builder();
|
||||
configurePoolSettings(builder, properties.getPool(), observationRegistryProvider);
|
||||
configurePoolSettings(builder, properties.getPool());
|
||||
URI uri = connectionDetails.getUri();
|
||||
String scheme = (uri != null) ? uri.getScheme() : "bolt";
|
||||
configureDriverSettings(builder, properties, isSimpleScheme(scheme));
|
||||
|
@ -118,16 +96,10 @@ public final class Neo4jAutoConfiguration {
|
|||
|
||||
private boolean isSimpleScheme(String scheme) {
|
||||
String lowerCaseScheme = scheme.toLowerCase(Locale.ENGLISH);
|
||||
if (!ServiceLoader.load(BoltConnectionProviderFactory.class)
|
||||
.stream()
|
||||
.anyMatch((p) -> p.get().supports(lowerCaseScheme))) {
|
||||
throw new IllegalArgumentException(String.format("'%s' is not a supported scheme.", scheme));
|
||||
}
|
||||
return !Scheme.isSecurityScheme(lowerCaseScheme);
|
||||
}
|
||||
|
||||
private void configurePoolSettings(Config.ConfigBuilder builder, Pool pool,
|
||||
ObjectProvider<ObservationRegistry> observationRegistryProvider) {
|
||||
private void configurePoolSettings(Config.ConfigBuilder builder, Pool pool) {
|
||||
if (pool.isLogLeakedSessions()) {
|
||||
builder.withLeakedSessionsLogging();
|
||||
}
|
||||
|
@ -139,11 +111,6 @@ public final class Neo4jAutoConfiguration {
|
|||
builder.withMaxConnectionLifetime(pool.getMaxConnectionLifetime().toMillis(), TimeUnit.MILLISECONDS);
|
||||
builder.withConnectionAcquisitionTimeout(pool.getConnectionAcquisitionTimeout().toMillis(),
|
||||
TimeUnit.MILLISECONDS);
|
||||
observationRegistryProvider.ifAvailable((orp) -> {
|
||||
if (pool.isMetricsEnabled() && HAS_DRIVER_METRICS) {
|
||||
builder.withObservationProvider(MicrometerObservationProvider.builder(orp).build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void configureDriverSettings(Config.ConfigBuilder builder, Neo4jProperties properties,
|
||||
|
|
|
@ -150,11 +150,6 @@ public class Neo4jProperties {
|
|||
|
||||
public static class Pool {
|
||||
|
||||
/**
|
||||
* Whether to enable metrics.
|
||||
*/
|
||||
private boolean metricsEnabled = false;
|
||||
|
||||
/**
|
||||
* Whether to log leaked sessions.
|
||||
*/
|
||||
|
@ -223,14 +218,6 @@ public class Neo4jProperties {
|
|||
this.connectionAcquisitionTimeout = connectionAcquisitionTimeout;
|
||||
}
|
||||
|
||||
public boolean isMetricsEnabled() {
|
||||
return this.metricsEnabled;
|
||||
}
|
||||
|
||||
public void setMetricsEnabled(boolean metricsEnabled) {
|
||||
this.metricsEnabled = metricsEnabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Security {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.neo4j.autoconfigure.observation;
|
||||
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.neo4j.driver.Config.ConfigBuilder;
|
||||
import org.neo4j.driver.observation.micrometer.MicrometerObservationProvider;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.neo4j.autoconfigure.ConfigBuilderCustomizer;
|
||||
import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* Auto-configuration for Neo4j observability.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration(before = Neo4jAutoConfiguration.class,
|
||||
afterName = "org.springframework.boot.micrometer.observation.autoconfigure.ObservationAutoConfiguration")
|
||||
@ConditionalOnBean(ObservationRegistry.class)
|
||||
@ConditionalOnClass({ ConfigBuilder.class, MicrometerObservationProvider.class, Observation.class })
|
||||
public final class Neo4jObservationAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(ObservationRegistry.class)
|
||||
ConfigBuilderCustomizer neo4jObservationCustomizer(ObservationRegistry registry) {
|
||||
return (builder) -> builder.withObservationProvider(MicrometerObservationProvider.builder(registry).build());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for Neo4j observation.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.neo4j.autoconfigure.observation;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -7,6 +7,14 @@
|
|||
"description": "Whether to enable Neo4j health check.",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"name": "spring.neo4j.pool.metrics-enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"deprecation": {
|
||||
"reason": "Use 'management.metrics.enable' to restrict certain metrics.",
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.neo4j.uri",
|
||||
"defaultValue": "bolt://localhost:7687"
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration
|
||||
org.springframework.boot.neo4j.autoconfigure.health.Neo4jHealthContributorAutoConfiguration
|
||||
org.springframework.boot.neo4j.autoconfigure.observation.Neo4jObservationAutoConfiguration
|
||||
|
|
|
@ -21,9 +21,7 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
@ -34,7 +32,6 @@ import org.neo4j.driver.Config;
|
|||
import org.neo4j.driver.Config.ConfigBuilder;
|
||||
import org.neo4j.driver.Driver;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
||||
import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration.PropertiesNeo4jConnectionDetails;
|
||||
|
@ -105,7 +102,7 @@ class Neo4jAutoConfigurationTests {
|
|||
this.contextRunner.withPropertyValues("spring.neo4j.uri=" + invalidScheme + "://localhost:4711")
|
||||
.run((ctx) -> assertThat(ctx).hasFailed()
|
||||
.getFailure()
|
||||
.hasMessageContaining("'%s' is not a supported scheme.", invalidScheme));
|
||||
.hasMessageContaining("Unsupported scheme: %s", invalidScheme));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -320,13 +317,7 @@ class Neo4jAutoConfigurationTests {
|
|||
|
||||
private Config mapDriverConfig(Neo4jProperties properties, ConfigBuilderCustomizer... customizers) {
|
||||
return new Neo4jAutoConfiguration().mapDriverConfig(properties,
|
||||
new PropertiesNeo4jConnectionDetails(properties, null), Arrays.asList(customizers),
|
||||
new ObjectProvider<>() {
|
||||
@Override
|
||||
public Stream<ObservationRegistry> stream() {
|
||||
return Stream.empty();
|
||||
}
|
||||
});
|
||||
new PropertiesNeo4jConnectionDetails(properties, null), Arrays.asList(customizers));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2012-present 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.neo4j.autoconfigure.observation;
|
||||
|
||||
import io.micrometer.observation.tck.TestObservationRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.neo4j.driver.Driver;
|
||||
import org.neo4j.driver.internal.observation.NoopObservationProvider;
|
||||
import org.neo4j.driver.observation.micrometer.MicrometerObservationProvider;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.neo4j.autoconfigure.Neo4jAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link Neo4jObservationAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class Neo4jObservationAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(Neo4jObservationAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void whenThereIsAnObservationRegistryThenMicrometerObservationProviderIsAdded() {
|
||||
this.contextRunner.withBean(TestObservationRegistry.class, TestObservationRegistry::create)
|
||||
.withConfiguration(AutoConfigurations.of(Neo4jAutoConfiguration.class))
|
||||
.run((context) -> assertThat(context.getBean(Driver.class)).extracting("observationProvider")
|
||||
.isInstanceOf(MicrometerObservationProvider.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenThereIsNoObservationRegistryThenConfigBuilderCustomizationBacksOff() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(Neo4jAutoConfiguration.class))
|
||||
.run((context) -> assertThat(context.getBean(Driver.class)).extracting("observationProvider")
|
||||
.isInstanceOf(NoopObservationProvider.class));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue