Adds Spring Session support (#1961)
* Adds Spring Session support * Changes following the review
This commit is contained in:
committed by
GitHub
parent
821bc3abd4
commit
4fcc7cc32e
@@ -507,6 +507,46 @@ Fully qualified name of the enclosing class `org.springframework.cloud.sleuth.in
|
||||
|method|Method name that got annotated with @Scheduled.
|
||||
|===
|
||||
|
||||
=== Session Create Span
|
||||
|
||||
> Span created when a new session has to be created.
|
||||
|
||||
**Span name** `session.create`.
|
||||
|
||||
Fully qualified name of the enclosing class `org.springframework.cloud.sleuth.instrument.session.SleuthSessionSpan`
|
||||
|
||||
=== Session Delete Span
|
||||
|
||||
> Span created when a session is deleted.
|
||||
|
||||
**Span name** `session.delete`.
|
||||
|
||||
Fully qualified name of the enclosing class `org.springframework.cloud.sleuth.instrument.session.SleuthSessionSpan`
|
||||
|
||||
=== Session Find Span
|
||||
|
||||
> Span created when a new session is searched for.
|
||||
|
||||
**Span name** `session.find`.
|
||||
|
||||
Fully qualified name of the enclosing class `org.springframework.cloud.sleuth.instrument.session.SleuthSessionSpan`
|
||||
|
||||
IMPORTANT: All tags and events must be prefixed with `session.` prefix!
|
||||
|
||||
.Tag Keys
|
||||
|===
|
||||
|Name | Description
|
||||
|session.index.name|
|
||||
|===
|
||||
|
||||
=== Session Save Span
|
||||
|
||||
> Span created when a new session is saved.
|
||||
|
||||
**Span name** `session.save`.
|
||||
|
||||
Fully qualified name of the enclosing class `org.springframework.cloud.sleuth.instrument.session.SleuthSessionSpan`
|
||||
|
||||
=== Task Execution Listener Span
|
||||
|
||||
> Span created within the lifecycle of a task.
|
||||
|
||||
@@ -714,3 +714,11 @@ Please check the <<appendix.adoc#appendix,appendix>> page under `spring.sleuth.j
|
||||
You can configure P6Spy manually using one of available configuration methods. For more information please refer to the http://p6spy.readthedocs.io/en/latest/configandusage.html[P6Spy Configuration Guide].
|
||||
|
||||
In order to disable this instrumentation set `spring.sleuth.jdbc.enabled` to `false`.
|
||||
|
||||
[[sleuth-session-integration]]
|
||||
== Spring Session
|
||||
|
||||
This feature is available for all tracer implementations.
|
||||
|
||||
We're instrumenting the `Session` repositories that wraps all operations in a span.
|
||||
In order to disable this instrumentation set `spring.sleuth.session.enabled` to `false`.
|
||||
|
||||
@@ -213,6 +213,11 @@
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-data-redis</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- BRAVE -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2013-2021 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.cloud.sleuth.autoconfig.instrument.session;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.sleuth.CurrentTraceContext;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.autoconfig.brave.BraveAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.session.TraceSessionRepositoryAspect;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.session.SessionRepository;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
* Auto-configuration} that registers instrumentation for Spring Session.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.1.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(SessionRepository.class)
|
||||
@ConditionalOnProperty(value = "spring.sleuth.session.enabled", matchIfMissing = true)
|
||||
@ConditionalOnBean(Tracer.class)
|
||||
@AutoConfigureAfter(BraveAutoConfiguration.class)
|
||||
public class TraceSessionAutoConfiguration {
|
||||
|
||||
// Bean post processors don't work cause session-redis requires concrete classes
|
||||
@Bean
|
||||
TraceSessionRepositoryAspect traceSessionRepositoryAspect(Tracer tracer, CurrentTraceContext currentTraceContext) {
|
||||
return new TraceSessionRepositoryAspect(tracer, currentTraceContext);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -185,6 +185,12 @@
|
||||
"description": "Enable R2dbc instrumentation.",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"name": "spring.sleuth.session.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Enable Spring Session instrumentation.",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"name": "spring.sleuth.vault.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
|
||||
@@ -18,6 +18,7 @@ org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebClient
|
||||
org.springframework.cloud.sleuth.autoconfig.instrument.web.client.feign.TraceFeignClientAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.autoconfig.instrument.web.client.TraceWebAsyncClientAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.autoconfig.instrument.scheduling.TraceSchedulingAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.autoconfig.instrument.session.TraceSessionAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.autoconfig.instrument.reactor.TraceReactorAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceFunctionAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.autoconfig.instrument.messaging.TraceSpringIntegrationAutoConfiguration,\
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
@@ -62,7 +63,7 @@ public class BraveRpcAutoConfigurationIntegrationTests {
|
||||
@EnableAutoConfiguration(exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class })
|
||||
R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public static class Config {
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -150,8 +151,8 @@ public class WebClientTests {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableAutoConfiguration(exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
R2dbcAutoConfiguration.class, R2dbcDataAutoConfiguration.class, MongoAutoConfiguration.class,
|
||||
MongoDataAutoConfiguration.class })
|
||||
R2dbcAutoConfiguration.class, R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, MongoDataAutoConfiguration.class })
|
||||
@DisableSecurity
|
||||
public static class TestConfiguration {
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
@@ -53,7 +54,7 @@ public class TraceAsyncDefaultAutoConfigurationTests {
|
||||
@EnableAutoConfiguration(exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class })
|
||||
R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
@@ -115,10 +116,12 @@ public class TraceQuartzAutoConfigurationTest {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableAutoConfiguration(exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class })
|
||||
@EnableAutoConfiguration(
|
||||
exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class },
|
||||
excludeName = "org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration")
|
||||
public static class EnableAutoConfig {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2013-2021 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.cloud.sleuth.autoconfig.instrument.session;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceNoOpAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.session.TraceSessionRepositoryAspect;
|
||||
import org.springframework.session.SessionRepository;
|
||||
|
||||
class TraceSessionAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.sleuth.noop.enabled=true").withConfiguration(
|
||||
AutoConfigurations.of(TraceNoOpAutoConfiguration.class, TraceSessionAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void should_register_session_aspect() {
|
||||
this.contextRunner
|
||||
.run(context -> Assertions.assertThat(context).hasSingleBean(TraceSessionRepositoryAspect.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_not_register_session_aspect_when_session_repository_not_on_classpath() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(SessionRepository.class))
|
||||
.run(context -> Assertions.assertThat(context).doesNotHaveBean(TraceSessionRepositoryAspect.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_not_register_session_aspect_when_session_instrumentation_is_disabled() {
|
||||
this.contextRunner.withPropertyValues("spring.sleuth.session.enabled=false")
|
||||
.run(context -> Assertions.assertThat(context).doesNotHaveBean(TraceSessionRepositoryAspect.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
@@ -123,7 +124,7 @@ public class BraveWebClientAutoConfigurationTests {
|
||||
@EnableAutoConfiguration(exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class })
|
||||
R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
static class Config {
|
||||
|
||||
// custom builder
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
@@ -57,7 +58,7 @@ public class GH846Tests {
|
||||
@EnableAutoConfiguration(exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class })
|
||||
R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
static class App {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
@@ -46,7 +47,7 @@ public class TraceWebClientDisabledTests {
|
||||
@EnableAutoConfiguration(exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class })
|
||||
R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
public static class Config {
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.boot.actuate.autoconfigure.security.servlet.Managemen
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
@@ -53,10 +54,12 @@ public class ZipkinSamplerTests {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableAutoConfiguration(exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class })
|
||||
@EnableAutoConfiguration(
|
||||
exclude = { GatewayClassPathWarningAutoConfiguration.class, GatewayAutoConfiguration.class,
|
||||
GatewayMetricsAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class,
|
||||
MongoAutoConfiguration.class, QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class,
|
||||
R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class },
|
||||
excludeName = "org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration")
|
||||
static class TestConfig {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
logging.level.org.springframework.cloud: DEBUG
|
||||
|
||||
spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.cloud.gateway.config.GatewayAutoConfiguration, org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration, org.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration, org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration, org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration, org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration, org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
|
||||
spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.cloud.gateway.config.GatewayAutoConfiguration, org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration, org.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration, org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration, org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration, org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration, org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration, org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration, org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
|
||||
|
||||
@@ -197,6 +197,11 @@
|
||||
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-data-redis</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>p6spy</groupId>
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
|
||||
/**
|
||||
* Aspec around {@link CircuitBreaker} creation.
|
||||
* Aspect around {@link CircuitBreaker} creation.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.0.0
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2013-2021 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.cloud.sleuth.instrument.session;
|
||||
|
||||
import org.springframework.cloud.sleuth.docs.DocumentedSpan;
|
||||
import org.springframework.cloud.sleuth.docs.TagKey;
|
||||
|
||||
enum SleuthSessionSpan implements DocumentedSpan {
|
||||
|
||||
/**
|
||||
* Span created when a new session has to be created.
|
||||
*/
|
||||
SESSION_CREATE_SPAN {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "session.create";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Span created when a new session is searched for.
|
||||
*/
|
||||
SESSION_FIND_SPAN {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "session.find";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagKey[] getTagKeys() {
|
||||
return Tags.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String prefix() {
|
||||
return "session.";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Span created when a new session is saved.
|
||||
*/
|
||||
SESSION_SAVE_SPAN {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "session.save";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Span created when a session is deleted.
|
||||
*/
|
||||
SESSION_DELETE_SPAN {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "session.delete";
|
||||
}
|
||||
};
|
||||
|
||||
enum Tags implements TagKey {
|
||||
|
||||
INDEX_NAME {
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "session.index.name";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2018-2021 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.cloud.sleuth.instrument.session;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.docs.AssertingSpan;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
|
||||
class TraceFindByIndexNameSessionRepository extends TraceSessionRepository implements FindByIndexNameSessionRepository {
|
||||
|
||||
private final FindByIndexNameSessionRepository delegate;
|
||||
|
||||
TraceFindByIndexNameSessionRepository(Tracer tracer, FindByIndexNameSessionRepository delegate) {
|
||||
super(tracer, delegate);
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map findByPrincipalName(String principalName) {
|
||||
AssertingSpan span = newSessionFindSpan();
|
||||
try (Tracer.SpanInScope ws = this.tracer.withSpan(span.start())) {
|
||||
return this.delegate.findByPrincipalName(principalName);
|
||||
}
|
||||
finally {
|
||||
span.end();
|
||||
}
|
||||
}
|
||||
|
||||
private AssertingSpan newSessionFindSpan() {
|
||||
return AssertingSpan.of(SleuthSessionSpan.SESSION_FIND_SPAN, this.tracer.nextSpan())
|
||||
.name(SleuthSessionSpan.SESSION_FIND_SPAN.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map findByIndexNameAndIndexValue(String indexName, String indexValue) {
|
||||
AssertingSpan span = newSessionFindSpan();
|
||||
try (Tracer.SpanInScope ws = this.tracer.withSpan(span.start())) {
|
||||
span.tag(SleuthSessionSpan.Tags.INDEX_NAME, indexName);
|
||||
return this.delegate.findByIndexNameAndIndexValue(indexName, indexValue);
|
||||
}
|
||||
finally {
|
||||
span.end();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2018-2021 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.cloud.sleuth.instrument.session;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.sleuth.CurrentTraceContext;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth;
|
||||
import org.springframework.session.ReactiveSessionRepository;
|
||||
import org.springframework.session.Session;
|
||||
|
||||
class TraceReactiveSessionRepository implements ReactiveSessionRepository {
|
||||
|
||||
private final ReactiveSessionRepository delegate;
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
private final CurrentTraceContext currentTraceContext;
|
||||
|
||||
TraceReactiveSessionRepository(Tracer tracer, CurrentTraceContext currentTraceContext,
|
||||
ReactiveSessionRepository delegate) {
|
||||
this.delegate = delegate;
|
||||
this.tracer = tracer;
|
||||
this.currentTraceContext = currentTraceContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono createSession() {
|
||||
return ReactorSleuth.tracedMono(this.tracer, this.currentTraceContext,
|
||||
SleuthSessionSpan.SESSION_CREATE_SPAN.getName(), () -> this.delegate.createSession());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> save(Session session) {
|
||||
return ReactorSleuth.tracedMono(this.tracer, this.currentTraceContext,
|
||||
SleuthSessionSpan.SESSION_SAVE_SPAN.getName(), () -> this.delegate.save(session));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono findById(String id) {
|
||||
return ReactorSleuth.tracedMono(this.tracer, this.currentTraceContext,
|
||||
SleuthSessionSpan.SESSION_FIND_SPAN.getName(), () -> this.delegate.findById(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteById(String id) {
|
||||
return ReactorSleuth.tracedMono(this.tracer, this.currentTraceContext,
|
||||
SleuthSessionSpan.SESSION_DELETE_SPAN.getName(), () -> this.delegate.deleteById(id));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2018-2021 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.cloud.sleuth.instrument.session;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.docs.AssertingSpan;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.SessionRepository;
|
||||
|
||||
class TraceSessionRepository implements SessionRepository {
|
||||
|
||||
private static final Log log = LogFactory.getLog(TraceSessionRepository.class);
|
||||
|
||||
private final SessionRepository delegate;
|
||||
|
||||
protected final Tracer tracer;
|
||||
|
||||
TraceSessionRepository(Tracer tracer, SessionRepository delegate) {
|
||||
this.delegate = delegate;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session createSession() {
|
||||
return wrap(SleuthSessionSpan.SESSION_CREATE_SPAN, (Supplier<Session>) this.delegate::createSession);
|
||||
}
|
||||
|
||||
private <T> T wrap(SleuthSessionSpan sessionSpan, Supplier<T> supplier) {
|
||||
AssertingSpan span = newSpan(sessionSpan);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(
|
||||
"Wrapping call in a span with name [" + span.getDocumentedSpan().getName() + "] - [" + span + "]");
|
||||
}
|
||||
try (Tracer.SpanInScope ws = this.tracer.withSpan(span.start())) {
|
||||
return supplier.get();
|
||||
}
|
||||
finally {
|
||||
span.end();
|
||||
}
|
||||
}
|
||||
|
||||
private void wrap(SleuthSessionSpan sessionSpan, Runnable runnable) {
|
||||
wrap(sessionSpan, () -> {
|
||||
runnable.run();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private AssertingSpan newSpan(SleuthSessionSpan sessionCreateSpan) {
|
||||
return AssertingSpan.of(sessionCreateSpan, this.tracer.nextSpan()).name(sessionCreateSpan.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(Session session) {
|
||||
wrap(SleuthSessionSpan.SESSION_SAVE_SPAN, () -> this.delegate.save(session));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session findById(String id) {
|
||||
return wrap(SleuthSessionSpan.SESSION_FIND_SPAN, () -> this.delegate.findById(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(String id) {
|
||||
wrap(SleuthSessionSpan.SESSION_DELETE_SPAN, () -> this.delegate.deleteById(id));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2018-2021 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.cloud.sleuth.instrument.session;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
|
||||
import org.springframework.cloud.sleuth.CurrentTraceContext;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.ReactiveSessionRepository;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Aspect around {@link SessionRepository} and {@link ReactiveSessionRepository} method
|
||||
* execution.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.1.0
|
||||
*/
|
||||
@Aspect
|
||||
public class TraceSessionRepositoryAspect {
|
||||
|
||||
private static final Log log = LogFactory.getLog(TraceSessionRepositoryAspect.class);
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
private final CurrentTraceContext currentTraceContext;
|
||||
|
||||
public TraceSessionRepositoryAspect(Tracer tracer, CurrentTraceContext currentTraceContext) {
|
||||
this.tracer = tracer;
|
||||
this.currentTraceContext = currentTraceContext;
|
||||
}
|
||||
|
||||
// RedisIndexedSessionRepository
|
||||
@Around("execution(public * org.springframework.session.SessionRepository.*(..))")
|
||||
public Object wrapSessionRepository(ProceedingJoinPoint pjp) throws Throwable {
|
||||
SessionRepository target = (SessionRepository) pjp.getTarget();
|
||||
if (target instanceof TraceSessionRepository) {
|
||||
return pjp.proceed();
|
||||
}
|
||||
target = wrapSessionRepository(target);
|
||||
return callMethodOnWrappedObject(pjp, target);
|
||||
}
|
||||
|
||||
private SessionRepository wrapSessionRepository(SessionRepository target) {
|
||||
if (target instanceof FindByIndexNameSessionRepository) {
|
||||
return new TraceFindByIndexNameSessionRepository(this.tracer, (FindByIndexNameSessionRepository) target);
|
||||
}
|
||||
return new TraceSessionRepository(this.tracer, target);
|
||||
}
|
||||
|
||||
private <T> Object callMethodOnWrappedObject(ProceedingJoinPoint pjp, T target) throws Throwable {
|
||||
Method method = getMethod(pjp, target);
|
||||
if (method != null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Found a corresponding method on the trace representation [" + method + "]");
|
||||
}
|
||||
return method.invoke(target, pjp.getArgs());
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Method [" + pjp.getSignature().getName()
|
||||
+ "] not found on the trace representation. Will run the original one.");
|
||||
}
|
||||
return pjp.proceed();
|
||||
}
|
||||
|
||||
@Around("execution(public * org.springframework.session.ReactiveSessionRepository.*(..))")
|
||||
public Object wrapReactiveSessionRepository(ProceedingJoinPoint pjp) throws Throwable {
|
||||
ReactiveSessionRepository target = (ReactiveSessionRepository) pjp.getTarget();
|
||||
if (target instanceof TraceReactiveSessionRepository) {
|
||||
return pjp.proceed();
|
||||
}
|
||||
target = new TraceReactiveSessionRepository(this.tracer, this.currentTraceContext, target);
|
||||
return callMethodOnWrappedObject(pjp, target);
|
||||
}
|
||||
|
||||
private Method getMethod(ProceedingJoinPoint pjp, Object tracingWrapper) {
|
||||
MethodSignature signature = (MethodSignature) pjp.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
Method foundMethodOnTracingWrapper = ReflectionUtils.findMethod(tracingWrapper.getClass(), method.getName(),
|
||||
method.getParameterTypes());
|
||||
if (foundMethodOnTracingWrapper != null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Found an exact match for method execution [" + foundMethodOnTracingWrapper + "]");
|
||||
}
|
||||
return foundMethodOnTracingWrapper;
|
||||
}
|
||||
Method[] uniquePublicDeclaredMethodsOnTracingWrapper = ReflectionUtils
|
||||
.getUniqueDeclaredMethods(tracingWrapper.getClass(), m -> Modifier.isPublic(m.getModifiers()));
|
||||
if (uniquePublicDeclaredMethodsOnTracingWrapper.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Will pick one of the unique declared methods ["
|
||||
+ Arrays.toString(uniquePublicDeclaredMethodsOnTracingWrapper) + "] that has a name ["
|
||||
+ method.getName() + "]");
|
||||
}
|
||||
Object[] argsOnOriginalObject = pjp.getArgs();
|
||||
return Arrays.stream(uniquePublicDeclaredMethodsOnTracingWrapper)
|
||||
.filter(m -> m.getName().equals(method.getName())
|
||||
&& paramsAreOfSameTyperInherited(argsOnOriginalObject, m.getParameterTypes()))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private boolean paramsAreOfSameTyperInherited(Object[] argsOnOriginalObject, Class<?>[] typeOnTracingWrapper) {
|
||||
if (argsOnOriginalObject.length != typeOnTracingWrapper.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < argsOnOriginalObject.length; i++) {
|
||||
Class<?> argType = argsOnOriginalObject[i].getClass();
|
||||
Class<?> typeOnWrapper = typeOnTracingWrapper[i];
|
||||
if (!typeOnWrapper.isAssignableFrom(argType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013-2021 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.cloud.sleuth.instrument.session;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.cloud.sleuth.tracer.SimpleSpan;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.SessionRepository;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
class TraceFindByIndexNameSessionRepositoryTests extends TraceSessionRepositoryTests {
|
||||
|
||||
FindByIndexNameSessionRepository delegate = mock(FindByIndexNameSessionRepository.class);
|
||||
|
||||
TraceFindByIndexNameSessionRepository traceSessionRepository = new TraceFindByIndexNameSessionRepository(
|
||||
this.simpleTracer, this.delegate);
|
||||
|
||||
@Test
|
||||
void should_trace_session_find_by_principle_name() {
|
||||
this.traceSessionRepository.findByPrincipalName("foo");
|
||||
|
||||
verify(this.delegate).findByPrincipalName(any());
|
||||
SimpleSpan lastSpan = this.simpleTracer.getLastSpan();
|
||||
then(lastSpan.name).isEqualTo(SleuthSessionSpan.SESSION_FIND_SPAN.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_trace_session_find_by_index_name_value() {
|
||||
this.traceSessionRepository.findByIndexNameAndIndexValue("indexName1", "indexValue1");
|
||||
|
||||
verify(this.delegate).findByIndexNameAndIndexValue(any(), any());
|
||||
SimpleSpan lastSpan = this.simpleTracer.getLastSpan();
|
||||
then(lastSpan.name).isEqualTo(SleuthSessionSpan.SESSION_FIND_SPAN.getName());
|
||||
then(lastSpan.tags).containsEntry(SleuthSessionSpan.Tags.INDEX_NAME.getKey(), "indexName1");
|
||||
}
|
||||
|
||||
@Override
|
||||
SessionRepository sessionRepositoryDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
SessionRepository sessionRepository() {
|
||||
return this.traceSessionRepository;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2013-2021 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.cloud.sleuth.instrument.session;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.sleuth.tracer.SimpleCurrentTraceContext;
|
||||
import org.springframework.cloud.sleuth.tracer.SimpleSpan;
|
||||
import org.springframework.cloud.sleuth.tracer.SimpleTracer;
|
||||
import org.springframework.session.ReactiveSessionRepository;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
class TraceReactiveSessionRepositoryTests {
|
||||
|
||||
SimpleCurrentTraceContext simpleCurrentTraceContext = new SimpleCurrentTraceContext();
|
||||
|
||||
SimpleTracer simpleTracer = new SimpleTracer() {
|
||||
@Override
|
||||
public SimpleSpan nextSpan() {
|
||||
SimpleSpan span = super.nextSpan();
|
||||
simpleCurrentTraceContext.traceContext = span.context();
|
||||
return span;
|
||||
}
|
||||
};
|
||||
|
||||
ReactiveSessionRepository delegate = mock(ReactiveSessionRepository.class);
|
||||
|
||||
ReactiveSessionRepository traceSessionRepository = new TraceReactiveSessionRepository(this.simpleTracer,
|
||||
this.simpleCurrentTraceContext, delegate);
|
||||
|
||||
@Test
|
||||
void should_trace_session_creation() {
|
||||
given(this.delegate.createSession()).willReturn(Mono.empty());
|
||||
|
||||
this.traceSessionRepository.createSession().block(Duration.ofMillis(10));
|
||||
|
||||
verify(this.delegate).createSession();
|
||||
then(this.simpleTracer.getLastSpan().name).isEqualTo(SleuthSessionSpan.SESSION_CREATE_SPAN.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_trace_session_save() {
|
||||
given(this.delegate.save(any())).willReturn(Mono.empty());
|
||||
|
||||
this.traceSessionRepository.save(null).block(Duration.ofMillis(10));
|
||||
|
||||
verify(this.delegate).save(any());
|
||||
then(this.simpleTracer.getLastSpan().name).isEqualTo(SleuthSessionSpan.SESSION_SAVE_SPAN.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_trace_session_find_by_id() {
|
||||
given(this.delegate.findById(any())).willReturn(Mono.empty());
|
||||
|
||||
this.traceSessionRepository.findById("").block(Duration.ofMillis(10));
|
||||
|
||||
verify(this.delegate).findById(any());
|
||||
then(this.simpleTracer.getLastSpan().name).isEqualTo(SleuthSessionSpan.SESSION_FIND_SPAN.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_trace_session_delete_by_id() {
|
||||
given(this.delegate.deleteById(any())).willReturn(Mono.empty());
|
||||
|
||||
this.traceSessionRepository.deleteById("").block(Duration.ofMillis(10));
|
||||
|
||||
verify(this.delegate).deleteById(any());
|
||||
then(this.simpleTracer.getLastSpan().name).isEqualTo(SleuthSessionSpan.SESSION_DELETE_SPAN.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2013-2021 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.cloud.sleuth.instrument.session;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.cloud.sleuth.tracer.SimpleTracer;
|
||||
import org.springframework.session.SessionRepository;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
class TraceSessionRepositoryTests {
|
||||
|
||||
SimpleTracer simpleTracer = new SimpleTracer();
|
||||
|
||||
SessionRepository delegate = mock(SessionRepository.class);
|
||||
|
||||
SessionRepository traceSessionRepository = new TraceSessionRepository(this.simpleTracer, delegate);
|
||||
|
||||
@Test
|
||||
void should_trace_session_creation() {
|
||||
sessionRepository().createSession();
|
||||
|
||||
verify(sessionRepositoryDelegate()).createSession();
|
||||
then(this.simpleTracer.getLastSpan().name).isEqualTo(SleuthSessionSpan.SESSION_CREATE_SPAN.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_trace_session_save() {
|
||||
sessionRepository().save(null);
|
||||
|
||||
verify(sessionRepositoryDelegate()).save(any());
|
||||
then(this.simpleTracer.getLastSpan().name).isEqualTo(SleuthSessionSpan.SESSION_SAVE_SPAN.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_trace_session_find_by_id() {
|
||||
sessionRepository().findById("");
|
||||
|
||||
verify(sessionRepositoryDelegate()).findById(any());
|
||||
then(this.simpleTracer.getLastSpan().name).isEqualTo(SleuthSessionSpan.SESSION_FIND_SPAN.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_trace_session_delete_by_id() {
|
||||
sessionRepository().deleteById("");
|
||||
|
||||
verify(sessionRepositoryDelegate()).deleteById(any());
|
||||
then(this.simpleTracer.getLastSpan().name).isEqualTo(SleuthSessionSpan.SESSION_DELETE_SPAN.getName());
|
||||
}
|
||||
|
||||
SessionRepository sessionRepository() {
|
||||
return this.traceSessionRepository;
|
||||
}
|
||||
|
||||
SessionRepository sessionRepositoryDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -104,4 +104,11 @@ public class SimpleSpan implements Span {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SimpleSpan{" + "tags=" + tags + ", started=" + started + ", ended=" + ended + ", throwable=" + throwable
|
||||
+ ", remoteServiceName='" + remoteServiceName + '\'' + ", spanKind=" + spanKind + ", events=" + events
|
||||
+ ", name='" + name + '\'' + '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import brave.sampler.Sampler;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
@@ -74,8 +75,9 @@ public class MultipleHopsIntegrationTests
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableAutoConfiguration(exclude = { MongoAutoConfiguration.class, QuartzAutoConfiguration.class,
|
||||
JmxAutoConfiguration.class, R2dbcAutoConfiguration.class, R2dbcDataAutoConfiguration.class })
|
||||
@EnableAutoConfiguration(
|
||||
exclude = { MongoAutoConfiguration.class, QuartzAutoConfiguration.class, JmxAutoConfiguration.class,
|
||||
R2dbcAutoConfiguration.class, R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
@@ -168,8 +169,9 @@ public class JmsTracingConfigurationTest {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableAutoConfiguration(exclude = { KafkaAutoConfiguration.class, MongoAutoConfiguration.class,
|
||||
QuartzAutoConfiguration.class, R2dbcAutoConfiguration.class, R2dbcDataAutoConfiguration.class })
|
||||
@EnableAutoConfiguration(
|
||||
exclude = { KafkaAutoConfiguration.class, MongoAutoConfiguration.class, QuartzAutoConfiguration.class,
|
||||
R2dbcAutoConfiguration.class, R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
class JmsTestTracingConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import brave.test.TestSpanHandler;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
||||
@@ -33,7 +34,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
|
||||
R2dbcAutoConfiguration.class, R2dbcDataAutoConfiguration.class })
|
||||
R2dbcAutoConfiguration.class, R2dbcDataAutoConfiguration.class, RedisAutoConfiguration.class })
|
||||
@ImportResource("classpath:beans/applicationContext.xml")
|
||||
@EnableIntegration
|
||||
@EnableAsync
|
||||
|
||||
Reference in New Issue
Block a user