Skip to content

Commit aca304d

Browse files
committed
Merge remote-tracking branch 'origin/main' into draft-interface-clients-autoconfiguration
2 parents 308bbd1 + 5c7ea74 commit aca304d

File tree

35 files changed

+899
-151
lines changed

35 files changed

+899
-151
lines changed

buildSrc/build.gradle

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ dependencies {
4040
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}")
4141

4242
implementation(platform("org.springframework:spring-framework-bom:${versions.springFramework}"))
43-
implementation("com.diffplug.gradle:goomph:3.37.2")
4443
implementation("dev.adamko.dokkatoo:dokkatoo-plugin:2.3.1")
4544
implementation("com.fasterxml.jackson.core:jackson-databind:${versions.jackson}")
4645
implementation("com.github.node-gradle:gradle-node-plugin:3.5.1")
@@ -129,10 +128,6 @@ gradlePlugin {
129128
id = "org.springframework.boot.optional-dependencies"
130129
implementationClass = "org.springframework.boot.build.optional.OptionalDependenciesPlugin"
131130
}
132-
processedAnnotationsPlugin {
133-
id = "org.springframework.boot.processed-annotations"
134-
implementationClass = "org.springframework.boot.build.processors.ProcessedAnnotationsPlugin"
135-
}
136131
starterPlugin {
137132
id = "org.springframework.boot.starter"
138133
implementationClass = "org.springframework.boot.build.starters.StarterPlugin"

buildSrc/src/main/java/org/springframework/boot/build/antora/AntoraAsciidocAttributes.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public Map<String, String> get() {
7777
Map<String, String> attributes = new LinkedHashMap<>();
7878
addGitHubAttributes(attributes);
7979
addVersionAttributes(attributes);
80-
addUrlArtifactRepository(attributes);
80+
addArtifactAttributes(attributes);
8181
addUrlJava(attributes);
8282
addUrlLibraryLinkAttributes(attributes);
8383
addPropertyAttributes(attributes);
@@ -139,8 +139,9 @@ private void addDependencyVersion(Map<String, String> attributes, String name, S
139139
attributes.put("version-" + name, version);
140140
}
141141

142-
private void addUrlArtifactRepository(Map<String, String> attributes) {
142+
private void addArtifactAttributes(Map<String, String> attributes) {
143143
attributes.put("url-artifact-repository", this.artifactRelease.getDownloadRepo());
144+
attributes.put("artifact-release-type", this.artifactRelease.getType());
144145
}
145146

146147
private void addUrlJava(Map<String, String> attributes) {

buildSrc/src/main/java/org/springframework/boot/build/context/properties/ConfigurationPropertiesPlugin.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,7 +33,6 @@
3333
import org.gradle.api.tasks.compile.JavaCompile;
3434
import org.gradle.language.base.plugins.LifecycleBasePlugin;
3535

36-
import org.springframework.boot.build.processors.ProcessedAnnotationsPlugin;
3736
import org.springframework.util.StringUtils;
3837

3938
/**
@@ -92,7 +91,6 @@ private void configureConfigurationPropertiesAnnotationProcessor(Project project
9291
.add(project.getDependencies()
9392
.project(Collections.singletonMap("path",
9493
":spring-boot-project:spring-boot-tools:spring-boot-configuration-processor")));
95-
project.getPlugins().apply(ProcessedAnnotationsPlugin.class);
9694
}
9795

9896
private void disableIncrementalCompilation(Project project) {

buildSrc/src/main/java/org/springframework/boot/build/processors/ProcessedAnnotationsPlugin.java

Lines changed: 0 additions & 39 deletions
This file was deleted.

buildSrc/src/test/java/org/springframework/boot/build/antora/AntoraAsciidocAttributesTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,27 @@ void urlArtifactRepositoryWhenSnapshot() {
112112
assertThat(attributes.get()).containsEntry("url-artifact-repository", "https://repo.spring.io/snapshot");
113113
}
114114

115+
@Test
116+
void artifactReleaseTypeWhenRelease() {
117+
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3", true, null,
118+
mockDependencyVersions(), null);
119+
assertThat(attributes.get()).containsEntry("artifact-release-type", "release");
120+
}
121+
122+
@Test
123+
void artifactReleaseTypeWhenMilestone() {
124+
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3-M1", true, null,
125+
mockDependencyVersions(), null);
126+
assertThat(attributes.get()).containsEntry("artifact-release-type", "milestone");
127+
}
128+
129+
@Test
130+
void artifactReleaseTypeWhenSnapshot() {
131+
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3-SNAPSHOT", true, null,
132+
mockDependencyVersions(), null);
133+
assertThat(attributes.get()).containsEntry("artifact-release-type", "snapshot");
134+
}
135+
115136
@Test
116137
void urlLinksFromLibrary() {
117138
Map<String, Function<LibraryVersion, String>> links = new LinkedHashMap<>();

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import io.micrometer.tracing.exporter.SpanReporter;
2525
import io.micrometer.tracing.otel.bridge.CompositeSpanExporter;
2626
import io.micrometer.tracing.otel.bridge.EventListener;
27-
import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper;
2827
import io.micrometer.tracing.otel.bridge.OtelBaggageManager;
2928
import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext;
3029
import io.micrometer.tracing.otel.bridge.OtelPropagator;
@@ -35,7 +34,6 @@
3534
import io.opentelemetry.api.OpenTelemetry;
3635
import io.opentelemetry.api.metrics.MeterProvider;
3736
import io.opentelemetry.api.trace.Tracer;
38-
import io.opentelemetry.context.ContextStorage;
3937
import io.opentelemetry.context.propagation.ContextPropagators;
4038
import io.opentelemetry.context.propagation.TextMapPropagator;
4139
import io.opentelemetry.sdk.resources.Resource;
@@ -164,8 +162,7 @@ EventPublisher otelTracerEventPublisher(List<EventListener> eventListeners) {
164162

165163
@Bean
166164
@ConditionalOnMissingBean
167-
OtelCurrentTraceContext otelCurrentTraceContext(EventPublisher publisher) {
168-
ContextStorage.addWrapper(new EventPublishingContextWrapper(publisher));
165+
OtelCurrentTraceContext otelCurrentTraceContext() {
169166
return new OtelCurrentTraceContext();
170167
}
171168

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.tracing;
18+
19+
import java.util.List;
20+
import java.util.concurrent.atomic.AtomicBoolean;
21+
import java.util.function.UnaryOperator;
22+
23+
import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper;
24+
import io.micrometer.tracing.otel.bridge.OtelTracer.EventPublisher;
25+
import io.opentelemetry.context.Context;
26+
import io.opentelemetry.context.ContextStorage;
27+
import io.opentelemetry.context.Scope;
28+
29+
import org.springframework.boot.context.event.ApplicationStartingEvent;
30+
import org.springframework.context.ApplicationContext;
31+
import org.springframework.context.ApplicationEvent;
32+
import org.springframework.context.ApplicationListener;
33+
import org.springframework.context.event.ContextClosedEvent;
34+
import org.springframework.context.event.ContextRefreshedEvent;
35+
import org.springframework.context.event.GenericApplicationListener;
36+
import org.springframework.core.Ordered;
37+
import org.springframework.core.ResolvableType;
38+
import org.springframework.util.ClassUtils;
39+
import org.springframework.util.LinkedMultiValueMap;
40+
import org.springframework.util.MultiValueMap;
41+
42+
/**
43+
* {@link ApplicationListener} to add an OpenTelemetry {@link ContextStorage} wrapper for
44+
* {@link EventPublisher} bean support. A single {@link ContextStorage} wrapper is added
45+
* as early as possible then updated with {@link EventPublisher} beans as needed.
46+
*
47+
* @author Phillip Webb
48+
*/
49+
class OpenTelemetryEventPublisherApplicationListener implements GenericApplicationListener {
50+
51+
private static final boolean OTEL_CONTEXT_PRESENT = ClassUtils.isPresent("io.opentelemetry.context.ContextStorage",
52+
null);
53+
54+
private static final boolean MICROMETER_OTEL_PRESENT = ClassUtils
55+
.isPresent("io.micrometer.tracing.otel.bridge.OtelTracer", null);
56+
57+
@Override
58+
public int getOrder() {
59+
return Ordered.HIGHEST_PRECEDENCE;
60+
}
61+
62+
@Override
63+
public boolean supportsEventType(ResolvableType eventType) {
64+
Class<?> type = eventType.getRawClass();
65+
return (type != null) && (ApplicationStartingEvent.class.isAssignableFrom(type)
66+
|| ContextRefreshedEvent.class.isAssignableFrom(type)
67+
|| ContextClosedEvent.class.isAssignableFrom(type));
68+
}
69+
70+
@Override
71+
public void onApplicationEvent(ApplicationEvent event) {
72+
if (!OTEL_CONTEXT_PRESENT || !MICROMETER_OTEL_PRESENT) {
73+
return;
74+
}
75+
if (event instanceof ApplicationStartingEvent) {
76+
EventPublisherBeansContextWrapper.addWrapperIfNecessary();
77+
}
78+
if (event instanceof ContextRefreshedEvent contextRefreshedEvent) {
79+
ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();
80+
List<EventPublishingContextWrapper> publishers = applicationContext
81+
.getBeansOfType(EventPublisher.class, true, false)
82+
.values()
83+
.stream()
84+
.map(EventPublishingContextWrapper::new)
85+
.toList();
86+
EventPublisherBeansContextWrapper.instance.put(applicationContext, publishers);
87+
}
88+
if (event instanceof ContextClosedEvent contextClosedEvent) {
89+
EventPublisherBeansContextWrapper.instance.remove(contextClosedEvent.getApplicationContext());
90+
}
91+
}
92+
93+
/**
94+
* The single {@link ContextStorage} wrapper that delegates to {@link EventPublisher}
95+
* beans.
96+
*/
97+
static class EventPublisherBeansContextWrapper implements UnaryOperator<ContextStorage> {
98+
99+
private static final AtomicBoolean added = new AtomicBoolean();
100+
101+
private static final EventPublisherBeansContextWrapper instance = new EventPublisherBeansContextWrapper();
102+
103+
private final MultiValueMap<ApplicationContext, EventPublishingContextWrapper> publishers = new LinkedMultiValueMap<>();
104+
105+
private volatile ContextStorage delegate;
106+
107+
static void addWrapperIfNecessary() {
108+
if (added.compareAndSet(false, true)) {
109+
ContextStorage.addWrapper(instance);
110+
}
111+
}
112+
113+
@Override
114+
public ContextStorage apply(ContextStorage contextStorage) {
115+
return new EventPublisherBeansContextStorage(contextStorage);
116+
}
117+
118+
void put(ApplicationContext applicationContext, List<EventPublishingContextWrapper> publishers) {
119+
synchronized (this) {
120+
this.publishers.addAll(applicationContext, publishers);
121+
this.delegate = null;
122+
}
123+
}
124+
125+
void remove(ApplicationContext applicationContext) {
126+
synchronized (this) {
127+
this.publishers.remove(applicationContext);
128+
this.delegate = null;
129+
}
130+
}
131+
132+
private ContextStorage getDelegate(ContextStorage parent) {
133+
ContextStorage delegate = this.delegate;
134+
if (delegate == null) {
135+
synchronized (this) {
136+
delegate = parent;
137+
for (List<EventPublishingContextWrapper> publishers : this.publishers.values()) {
138+
for (EventPublishingContextWrapper publisher : publishers) {
139+
delegate = publisher.apply(delegate);
140+
}
141+
}
142+
}
143+
}
144+
return delegate;
145+
}
146+
147+
/**
148+
* The wrapped {@link ContextStorage} that delegates to the
149+
* {@link EventPublisherBeansContextWrapper}.
150+
*/
151+
class EventPublisherBeansContextStorage implements ContextStorage {
152+
153+
private final ContextStorage parent;
154+
155+
EventPublisherBeansContextStorage(ContextStorage wrapped) {
156+
this.parent = wrapped;
157+
}
158+
159+
@Override
160+
public Scope attach(Context toAttach) {
161+
return getDelegate(this.parent).attach(toAttach);
162+
}
163+
164+
@Override
165+
public Context current() {
166+
return getDelegate(this.parent).current();
167+
}
168+
169+
@Override
170+
public Context root() {
171+
return getDelegate(this.parent).root();
172+
}
173+
174+
}
175+
176+
}
177+
178+
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ org.springframework.boot.actuate.autoconfigure.metrics.ValidationFailureAnalyzer
1010
# Environment Post Processors
1111
org.springframework.boot.env.EnvironmentPostProcessor=\
1212
org.springframework.boot.actuate.autoconfigure.tracing.LogCorrelationEnvironmentPostProcessor
13+
14+
# Application Listeners
15+
org.springframework.context.ApplicationListener=\
16+
org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryEventPublisherApplicationListener

0 commit comments

Comments
 (0)