Revert "Merge branch 'spring-projects:main' into main"
This reverts commit ce390b00e1
.
pull/30567/head
parent
c644529e8b
commit
37059a5e92
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.metrics.export.wavefront;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
/**
|
||||
* {@link ConfigurationProperties @ConfigurationProperties} for configuring Wavefront
|
||||
* metrics export.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@ConfigurationProperties("management.wavefront.metrics.export")
|
||||
public class WavefrontProperties extends PushRegistryProperties {
|
||||
|
||||
/**
|
||||
* URI to ship metrics to.
|
||||
*/
|
||||
private URI uri = URI.create("https://longboard.wavefront.com");
|
||||
|
||||
/**
|
||||
* Unique identifier for the app instance that is the source of metrics being
|
||||
* published to Wavefront. Defaults to the local host name.
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* API token used when publishing metrics directly to the Wavefront API host.
|
||||
*/
|
||||
private String apiToken;
|
||||
|
||||
/**
|
||||
* Global prefix to separate metrics originating from this app's white box
|
||||
* instrumentation from those originating from other Wavefront integrations when
|
||||
* viewed in the Wavefront UI.
|
||||
*/
|
||||
private String globalPrefix;
|
||||
|
||||
private final Sender sender = new Sender();
|
||||
|
||||
public URI getUri() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
public void setUri(URI uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public String getApiToken() {
|
||||
return this.apiToken;
|
||||
}
|
||||
|
||||
public void setApiToken(String apiToken) {
|
||||
this.apiToken = apiToken;
|
||||
}
|
||||
|
||||
public String getGlobalPrefix() {
|
||||
return this.globalPrefix;
|
||||
}
|
||||
|
||||
public void setGlobalPrefix(String globalPrefix) {
|
||||
this.globalPrefix = globalPrefix;
|
||||
}
|
||||
|
||||
public Sender getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
public static class Sender {
|
||||
|
||||
private int maxQueueSize = 50000;
|
||||
|
||||
private Duration flushInterval = Duration.ofSeconds(1);
|
||||
|
||||
private DataSize messageSize = DataSize.ofBytes(Integer.MAX_VALUE);
|
||||
|
||||
public int getMaxQueueSize() {
|
||||
return this.maxQueueSize;
|
||||
}
|
||||
|
||||
public void setMaxQueueSize(int maxQueueSize) {
|
||||
this.maxQueueSize = maxQueueSize;
|
||||
}
|
||||
|
||||
public Duration getFlushInterval() {
|
||||
return this.flushInterval;
|
||||
}
|
||||
|
||||
public void setFlushInterval(Duration flushInterval) {
|
||||
this.flushInterval = flushInterval;
|
||||
}
|
||||
|
||||
public DataSize getMessageSize() {
|
||||
return this.messageSize;
|
||||
}
|
||||
|
||||
public void setMessageSize(DataSize messageSize) {
|
||||
this.messageSize = messageSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import brave.Tracing;
|
||||
import brave.Tracing.Builder;
|
||||
import brave.TracingCustomizer;
|
||||
import brave.handler.SpanHandler;
|
||||
import brave.propagation.B3Propagation;
|
||||
import brave.propagation.CurrentTraceContext;
|
||||
import brave.propagation.CurrentTraceContext.ScopeDecorator;
|
||||
import brave.propagation.CurrentTraceContextCustomizer;
|
||||
import brave.propagation.Propagation.Factory;
|
||||
import brave.propagation.ThreadLocalCurrentTraceContext;
|
||||
import brave.sampler.Sampler;
|
||||
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
|
||||
import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext;
|
||||
import io.micrometer.tracing.brave.bridge.BraveTracer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Brave.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class)
|
||||
@ConditionalOnClass(brave.Tracer.class)
|
||||
@EnableConfigurationProperties(TracingProperties.class)
|
||||
public class BraveAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Default value for application name if {@code spring.application.name} is not set.
|
||||
*/
|
||||
private static final String DEFAULT_APPLICATION_NAME = "application";
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Tracing braveTracing(Environment environment, List<SpanHandler> spanHandlers,
|
||||
List<TracingCustomizer> tracingCustomizers, CurrentTraceContext currentTraceContext,
|
||||
Factory propagationFactory, Sampler sampler) {
|
||||
String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
|
||||
Builder builder = Tracing.newBuilder().currentTraceContext(currentTraceContext)
|
||||
.propagationFactory(propagationFactory).sampler(sampler).localServiceName(applicationName);
|
||||
for (SpanHandler spanHandler : spanHandlers) {
|
||||
builder.addSpanHandler(spanHandler);
|
||||
}
|
||||
for (TracingCustomizer tracingCustomizer : tracingCustomizers) {
|
||||
tracingCustomizer.customize(builder);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public brave.Tracer braveTracer(Tracing tracing) {
|
||||
return tracing.tracer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public CurrentTraceContext braveCurrentTraceContext(List<CurrentTraceContext.ScopeDecorator> scopeDecorators,
|
||||
List<CurrentTraceContextCustomizer> currentTraceContextCustomizers) {
|
||||
ThreadLocalCurrentTraceContext.Builder builder = ThreadLocalCurrentTraceContext.newBuilder();
|
||||
for (ScopeDecorator scopeDecorator : scopeDecorators) {
|
||||
builder.addScopeDecorator(scopeDecorator);
|
||||
}
|
||||
for (CurrentTraceContextCustomizer currentTraceContextCustomizer : currentTraceContextCustomizers) {
|
||||
currentTraceContextCustomizer.customize(builder);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Factory bravePropagationFactory() {
|
||||
return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Sampler braveSampler(TracingProperties properties) {
|
||||
return Sampler.create(properties.getSampling().getProbability());
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(BraveTracer.class)
|
||||
static class BraveMicrometer {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BraveTracer braveTracerBridge(brave.Tracer tracer, CurrentTraceContext currentTraceContext,
|
||||
BraveBaggageManager braveBaggageManager) {
|
||||
return new BraveTracer(tracer, new BraveCurrentTraceContext(currentTraceContext), braveBaggageManager);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BraveBaggageManager braveBaggageManager() {
|
||||
return new BraveBaggageManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.handler.DefaultTracingObservationHandler;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for the Micrometer Tracing API.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(Tracer.class)
|
||||
public class MicrometerTracingAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(Tracer.class)
|
||||
public DefaultTracingObservationHandler defaultTracingObservationHandler(Tracer tracer) {
|
||||
return new DefaultTracingObservationHandler(tracer);
|
||||
}
|
||||
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.MicrometerConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.SdkConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.TracerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry.
|
||||
*
|
||||
* It uses imports on {@link OpenTelemetryConfigurations} to guarantee the correct
|
||||
* configuration ordering.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class)
|
||||
@Import({ SdkConfiguration.class, TracerConfiguration.class, MicrometerConfiguration.class })
|
||||
public class OpenTelemetryAutoConfiguration {
|
||||
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.micrometer.tracing.otel.bridge.OtelBaggageManager;
|
||||
import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext;
|
||||
import io.micrometer.tracing.otel.bridge.OtelTracer;
|
||||
import io.micrometer.tracing.otel.bridge.OtelTracer.EventPublisher;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.trace.Tracer;
|
||||
import io.opentelemetry.context.propagation.ContextPropagators;
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
|
||||
import io.opentelemetry.sdk.trace.SpanProcessor;
|
||||
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
import io.opentelemetry.sdk.trace.samplers.Sampler;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
|
||||
import org.springframework.boot.SpringBootVersion;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* Configurations for Open Telemetry. Those are imported by
|
||||
* {@link OpenTelemetryAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class OpenTelemetryConfigurations {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(SdkTracerProvider.class)
|
||||
@EnableConfigurationProperties(TracingProperties.class)
|
||||
static class SdkConfiguration {
|
||||
|
||||
/**
|
||||
* Default value for application name if {@code spring.application.name} is not
|
||||
* set.
|
||||
*/
|
||||
private static final String DEFAULT_APPLICATION_NAME = "application";
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
OpenTelemetry openTelemetry(SdkTracerProvider sdkTracerProvider, ContextPropagators contextPropagators) {
|
||||
return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider).setPropagators(contextPropagators)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
SdkTracerProvider otelSdkTracerProvider(Environment environment, List<SpanProcessor> spanProcessors,
|
||||
Sampler sampler) {
|
||||
String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
|
||||
SdkTracerProviderBuilder builder = SdkTracerProvider.builder().setSampler(sampler)
|
||||
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName)));
|
||||
for (SpanProcessor spanProcessor : spanProcessors) {
|
||||
builder.addSpanProcessor(spanProcessor);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ContextPropagators otelContextPropagators(List<TextMapPropagator> textMapPropagators) {
|
||||
return ContextPropagators.create(TextMapPropagator.composite(textMapPropagators));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
Sampler otelSampler(TracingProperties properties) {
|
||||
return Sampler.traceIdRatioBased(properties.getSampling().getProbability());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
SpanProcessor otelSpanProcessor(List<SpanExporter> spanExporter) {
|
||||
return SpanProcessor.composite(spanExporter.stream()
|
||||
.map((exporter) -> BatchSpanProcessor.builder(exporter).build()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(Tracer.class)
|
||||
static class TracerConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(OpenTelemetry.class)
|
||||
Tracer otelTracer(OpenTelemetry openTelemetry) {
|
||||
return openTelemetry.getTracer("org.springframework.boot", SpringBootVersion.getVersion());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(OtelTracer.class)
|
||||
static class MicrometerConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(Tracer.class)
|
||||
OtelTracer micrometerOtelTracer(Tracer tracer, EventPublisher eventPublisher,
|
||||
OtelCurrentTraceContext otelCurrentTraceContext) {
|
||||
return new OtelTracer(tracer, otelCurrentTraceContext, eventPublisher,
|
||||
new OtelBaggageManager(otelCurrentTraceContext, List.of(), List.of()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
EventPublisher otelTracerEventPublisher() {
|
||||
return (event) -> {
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
OtelCurrentTraceContext otelCurrentTraceContext() {
|
||||
return new OtelCurrentTraceContext();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for tracing.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@ConfigurationProperties("management.tracing")
|
||||
public class TracingProperties {
|
||||
|
||||
/**
|
||||
* Sampling configuration.
|
||||
*/
|
||||
private final Sampling sampling = new Sampling();
|
||||
|
||||
public Sampling getSampling() {
|
||||
return this.sampling;
|
||||
}
|
||||
|
||||
public static class Sampling {
|
||||
|
||||
/**
|
||||
* Probability in the range from 0.0 to 1.0 that a trace will be sampled.
|
||||
*/
|
||||
private float probability = 0.10f;
|
||||
|
||||
public float getProbability() {
|
||||
return this.probability;
|
||||
}
|
||||
|
||||
public void setProbability(float probability) {
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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 Micrometer Tracing.
|
||||
*/
|
||||
package org.springframework.boot.actuate.autoconfigure.tracing;
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.wavefront;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.tracing.reporter.wavefront.SpanMetrics;
|
||||
|
||||
/**
|
||||
* Bridges {@link SpanMetrics} to a {@link MeterRegistry}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class MeterRegistrySpanMetrics implements SpanMetrics {
|
||||
|
||||
private final Counter spansReceived;
|
||||
|
||||
private final Counter spansDropped;
|
||||
|
||||
private final Counter reportErrors;
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
MeterRegistrySpanMetrics(MeterRegistry meterRegistry) {
|
||||
this.meterRegistry = meterRegistry;
|
||||
this.spansReceived = meterRegistry.counter("wavefront.reporter.spans.received");
|
||||
this.spansDropped = meterRegistry.counter("wavefront.reporter.spans.dropped");
|
||||
this.reportErrors = meterRegistry.counter("wavefront.reporter.errors");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportDropped() {
|
||||
this.spansDropped.increment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportReceived() {
|
||||
this.spansReceived.increment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportErrors() {
|
||||
this.reportErrors.increment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerQueueSize(BlockingQueue<?> queue) {
|
||||
this.meterRegistry.gauge("wavefront.reporter.queue.size", queue, (q) -> (double) q.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerQueueRemainingCapacity(BlockingQueue<?> queue) {
|
||||
this.meterRegistry.gauge("wavefront.reporter.queue.remaining_capacity", queue,
|
||||
(q) -> (double) q.remainingCapacity());
|
||||
}
|
||||
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.wavefront;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import brave.handler.SpanHandler;
|
||||
import com.wavefront.sdk.common.WavefrontSender;
|
||||
import com.wavefront.sdk.common.application.ApplicationTags;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.tracing.reporter.wavefront.SpanMetrics;
|
||||
import io.micrometer.tracing.reporter.wavefront.WavefrontBraveSpanHandler;
|
||||
import io.micrometer.tracing.reporter.wavefront.WavefrontOtelSpanHandler;
|
||||
import io.micrometer.tracing.reporter.wavefront.WavefrontSpanHandler;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties;
|
||||
import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Tracing;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Wavefront.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class,
|
||||
WavefrontAutoConfiguration.class })
|
||||
@EnableConfigurationProperties(WavefrontProperties.class)
|
||||
@ConditionalOnBean(WavefrontSender.class)
|
||||
public class WavefrontTracingAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Default value for application name if {@code spring.application.name} is not set.
|
||||
*/
|
||||
private static final String DEFAULT_APPLICATION_NAME = "application";
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ApplicationTags applicationTags(Environment environment, WavefrontProperties properties) {
|
||||
String springApplicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
|
||||
Tracing tracing = properties.getTracing();
|
||||
String applicationName = (tracing.getApplicationName() != null) ? tracing.getApplicationName()
|
||||
: springApplicationName;
|
||||
String serviceName = (tracing.getServiceName() != null) ? tracing.getServiceName() : springApplicationName;
|
||||
return new ApplicationTags.Builder(applicationName, serviceName).build();
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(WavefrontSpanHandler.class)
|
||||
static class WavefrontMicrometer {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
WavefrontSpanHandler wavefrontSpanHandler(WavefrontProperties properties, WavefrontSender wavefrontSender,
|
||||
SpanMetrics spanMetrics, ApplicationTags applicationTags) {
|
||||
return new WavefrontSpanHandler(properties.getSender().getMaxQueueSize(), wavefrontSender, spanMetrics,
|
||||
properties.getSourceOrDefault(), applicationTags, Set.of());
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBean(MeterRegistry.class)
|
||||
static class MeterRegistrySpanMetricsConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
MeterRegistrySpanMetrics meterRegistrySpanMetrics(MeterRegistry meterRegistry) {
|
||||
return new MeterRegistrySpanMetrics(meterRegistry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(MeterRegistry.class)
|
||||
static class NoopSpanMetricsConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
SpanMetrics meterRegistrySpanMetrics() {
|
||||
return SpanMetrics.NOOP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(SpanHandler.class)
|
||||
static class WavefrontBrave {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
WavefrontBraveSpanHandler wavefrontBraveSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) {
|
||||
return new WavefrontBraveSpanHandler(wavefrontSpanHandler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(SpanExporter.class)
|
||||
static class WavefrontOpenTelemetry {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
WavefrontOtelSpanHandler wavefrontOtelSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) {
|
||||
return new WavefrontOtelSpanHandler(wavefrontSpanHandler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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 tracing with Wavefront.
|
||||
*/
|
||||
package org.springframework.boot.actuate.autoconfigure.tracing.wavefront;
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import zipkin2.Span;
|
||||
import zipkin2.codec.BytesEncoder;
|
||||
import zipkin2.codec.SpanBytesEncoder;
|
||||
import zipkin2.reporter.Sender;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.ReporterConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Zipkin.
|
||||
*
|
||||
* It uses imports on {@link ZipkinConfigurations} to guarantee the correct configuration
|
||||
* ordering.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@AutoConfiguration(after = RestTemplateAutoConfiguration.class)
|
||||
@ConditionalOnClass(Sender.class)
|
||||
@Import({ SenderConfiguration.class, ReporterConfiguration.class, BraveConfiguration.class,
|
||||
OpenTelemetryConfiguration.class })
|
||||
public class ZipkinAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public BytesEncoder<Span> spanBytesEncoder() {
|
||||
return SpanBytesEncoder.JSON_V2;
|
||||
}
|
||||
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import brave.handler.SpanHandler;
|
||||
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
|
||||
import zipkin2.Span;
|
||||
import zipkin2.codec.BytesEncoder;
|
||||
import zipkin2.reporter.AsyncReporter;
|
||||
import zipkin2.reporter.Reporter;
|
||||
import zipkin2.reporter.Sender;
|
||||
import zipkin2.reporter.brave.ZipkinSpanHandler;
|
||||
import zipkin2.reporter.urlconnection.URLConnectionSender;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Configurations for Zipkin. Those are imported by {@link ZipkinAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class ZipkinConfigurations {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(ZipkinProperties.class)
|
||||
static class SenderConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(URLConnectionSender.class)
|
||||
Sender urlConnectionSender(ZipkinProperties properties) {
|
||||
return URLConnectionSender.newBuilder().connectTimeout((int) properties.getConnectTimeout().getSeconds())
|
||||
.readTimeout((int) properties.getReadTimeout().getSeconds()).endpoint(properties.getEndpoint())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(RestTemplateBuilder.class)
|
||||
@ConditionalOnMissingClass("zipkin2.reporter.urlconnection.URLConnectionSender")
|
||||
Sender restTemplateSender(ZipkinProperties properties, RestTemplateBuilder restTemplateBuilder) {
|
||||
RestTemplate restTemplate = restTemplateBuilder.setConnectTimeout(properties.getConnectTimeout())
|
||||
.setReadTimeout(properties.getReadTimeout()).build();
|
||||
return new ZipkinRestTemplateSender(properties.getEndpoint(), restTemplate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ReporterConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(Sender.class)
|
||||
Reporter<Span> spanReporter(Sender sender, BytesEncoder<Span> encoder) {
|
||||
return AsyncReporter.builder(sender).build(encoder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ZipkinSpanHandler.class)
|
||||
static class BraveConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(Reporter.class)
|
||||
SpanHandler zipkinSpanHandler(Reporter<Span> spanReporter) {
|
||||
return ZipkinSpanHandler.newBuilder(spanReporter).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ZipkinSpanExporter.class)
|
||||
static class OpenTelemetryConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(Sender.class)
|
||||
ZipkinSpanExporter zipkinSpanExporter(BytesEncoder<Span> encoder, Sender sender) {
|
||||
return ZipkinSpanExporter.builder().setEncoder(encoder).setSender(sender).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for {@link ZipkinAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@ConfigurationProperties("management.zipkin.tracing")
|
||||
public class ZipkinProperties {
|
||||
|
||||
/**
|
||||
* URL to the Zipkin API.
|
||||
*/
|
||||
private String endpoint = "http://localhost:9411/api/v2/spans";
|
||||
|
||||
/**
|
||||
* Connection timeout for requests to Zipkin.
|
||||
*/
|
||||
private Duration connectTimeout = Duration.ofSeconds(1);
|
||||
|
||||
/**
|
||||
* Read timeout for requests to Zipkin.
|
||||
*/
|
||||
private Duration readTimeout = Duration.ofSeconds(10);
|
||||
|
||||
public String getEndpoint() {
|
||||
return this.endpoint;
|
||||
}
|
||||
|
||||
public void setEndpoint(String endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public Duration getConnectTimeout() {
|
||||
return this.connectTimeout;
|
||||
}
|
||||
|
||||
public void setConnectTimeout(Duration connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
public Duration getReadTimeout() {
|
||||
return this.readTimeout;
|
||||
}
|
||||
|
||||
public void setReadTimeout(Duration readTimeout) {
|
||||
this.readTimeout = readTimeout;
|
||||
}
|
||||
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import zipkin2.Call;
|
||||
import zipkin2.Callback;
|
||||
import zipkin2.CheckResult;
|
||||
import zipkin2.codec.Encoding;
|
||||
import zipkin2.reporter.BytesMessageEncoder;
|
||||
import zipkin2.reporter.ClosedSenderException;
|
||||
import zipkin2.reporter.Sender;
|
||||
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* A Zipkin {@link Sender} which uses {@link RestTemplate} for HTTP communication.
|
||||
* Supports automatic compression with gzip.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class ZipkinRestTemplateSender extends Sender {
|
||||
|
||||
private static final DataSize MESSAGE_MAX_BYTES = DataSize.ofKilobytes(512);
|
||||
|
||||
private final String endpoint;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
private volatile boolean closed;
|
||||
|
||||
ZipkinRestTemplateSender(String endpoint, RestTemplate restTemplate) {
|
||||
this.endpoint = endpoint;
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Encoding encoding() {
|
||||
return Encoding.JSON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int messageMaxBytes() {
|
||||
return (int) MESSAGE_MAX_BYTES.toBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int messageSizeInBytes(List<byte[]> encodedSpans) {
|
||||
return encoding().listSizeInBytes(encodedSpans);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int messageSizeInBytes(int encodedSizeInBytes) {
|
||||
return encoding().listSizeInBytes(encodedSizeInBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Call<Void> sendSpans(List<byte[]> encodedSpans) {
|
||||
if (this.closed) {
|
||||
throw new ClosedSenderException();
|
||||
}
|
||||
return new HttpCall(this.endpoint, BytesMessageEncoder.JSON.encode(encodedSpans), this.restTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckResult check() {
|
||||
try {
|
||||
sendSpans(List.of()).execute();
|
||||
return CheckResult.OK;
|
||||
}
|
||||
catch (IOException | RuntimeException ex) {
|
||||
return CheckResult.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
private static class HttpCall extends Call.Base<Void> {
|
||||
|
||||
/**
|
||||
* Only use gzip compression on data which is bigger than this in bytes.
|
||||
*/
|
||||
private static final DataSize COMPRESSION_THRESHOLD = DataSize.ofKilobytes(1);
|
||||
|
||||
private final String endpoint;
|
||||
|
||||
private final byte[] body;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
HttpCall(String endpoint, byte[] body, RestTemplate restTemplate) {
|
||||
this.endpoint = endpoint;
|
||||
this.body = body;
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doExecute() throws IOException {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("b3", "0");
|
||||
headers.set("Content-Type", "application/json");
|
||||
byte[] body;
|
||||
if (needsCompression(this.body)) {
|
||||
headers.set("Content-Encoding", "gzip");
|
||||
body = compress(this.body);
|
||||
}
|
||||
else {
|
||||
body = this.body;
|
||||
}
|
||||
HttpEntity<byte[]> request = new HttpEntity<>(body, headers);
|
||||
this.restTemplate.exchange(this.endpoint, HttpMethod.POST, request, Void.class);
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean needsCompression(byte[] body) {
|
||||
return body.length > COMPRESSION_THRESHOLD.toBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEnqueue(Callback<Void> callback) {
|
||||
try {
|
||||
doExecute();
|
||||
callback.onSuccess(null);
|
||||
}
|
||||
catch (IOException | RuntimeException ex) {
|
||||
callback.onError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Call<Void> clone() {
|
||||
return new HttpCall(this.endpoint, this.body, this.restTemplate);
|
||||
}
|
||||
|
||||
private byte[] compress(byte[] input) throws IOException {
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzip = new GZIPOutputStream(result)) {
|
||||
gzip.write(input);
|
||||
}
|
||||
return result.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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 tracing with Zipkin.
|
||||
*/
|
||||
package org.springframework.boot.actuate.autoconfigure.tracing.zipkin;
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.wavefront;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import com.wavefront.sdk.common.WavefrontSender;
|
||||
import com.wavefront.sdk.common.clients.WavefrontClient.Builder;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.wavefront.WavefrontTracingAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Wavefront common infrastructure.
|
||||
* Metrics are auto-configured in {@link WavefrontMetricsExportAutoConfiguration}, tracing
|
||||
* is auto-configured in {@link WavefrontTracingAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(WavefrontSender.class)
|
||||
@EnableConfigurationProperties(WavefrontProperties.class)
|
||||
public class WavefrontAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WavefrontSender wavefrontSender(WavefrontProperties properties) {
|
||||
Builder builder = new Builder(properties.getEffectiveUri().toString(), properties.getApiTokenOrThrow());
|
||||
PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||
WavefrontProperties.Sender sender = properties.getSender();
|
||||
mapper.from(sender.getMaxQueueSize()).to(builder::maxQueueSize);
|
||||
mapper.from(sender.getFlushInterval()).asInt(Duration::getSeconds).to(builder::flushIntervalSeconds);
|
||||
mapper.from(sender.getMessageSize()).asInt(DataSize::toBytes).to(builder::messageSizeBytes);
|
||||
mapper.from(sender.getBatchSize()).to(builder::batchSize);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
@ -1,290 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.wavefront;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.UnknownHostException;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
/**
|
||||
* Configuration properties to configure Wavefront.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "management.wavefront")
|
||||
public class WavefrontProperties {
|
||||
|
||||
/**
|
||||
* URI to ship metrics and traces to.
|
||||
*/
|
||||
private URI uri = URI.create("https://longboard.wavefront.com");
|
||||
|
||||
/**
|
||||
* Unique identifier for the app instance that is the source of metrics being
|
||||
* published to Wavefront. Defaults to the local host name.
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* API token used when publishing metrics directly to the Wavefront API host.
|
||||
*/
|
||||
private String apiToken;
|
||||
|
||||
/**
|
||||
* Sender configuration.
|
||||
*/
|
||||
private final Sender sender = new Sender();
|
||||
|
||||
/**
|
||||
* Metrics configuration.
|
||||
*/
|
||||
private final Metrics metrics = new Metrics();
|
||||
|
||||
/**
|
||||
* Tracing configuration.
|
||||
*/
|
||||
private final Tracing tracing = new Tracing();
|
||||
|
||||
public Sender getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
public Metrics getMetrics() {
|
||||
return this.metrics;
|
||||
}
|
||||
|
||||
public Tracing getTracing() {
|
||||
return this.tracing;
|
||||
}
|
||||
|
||||
public URI getUri() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
public void setUri(URI uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public String getApiToken() {
|
||||
return this.apiToken;
|
||||
}
|
||||
|
||||
public void setApiToken(String apiToken) {
|
||||
this.apiToken = apiToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective URI of the wavefront instance. This will not be the same URI
|
||||
* given through {@link #setUri(URI)} when a proxy is used.
|
||||
* @return the effective URI of the wavefront instance
|
||||
*/
|
||||
public URI getEffectiveUri() {
|
||||
if (usesProxy()) {
|
||||
// See io.micrometer.wavefront.WavefrontMeterRegistry.getWavefrontReportingUri
|
||||
return URI.create(this.uri.toString().replace("proxy://", "http://"));
|
||||
}
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the API token or throws an exception if the API token is mandatory. If a
|
||||
* proxy is used, the API token is optional.
|
||||
* @return the API token
|
||||
*/
|
||||
public String getApiTokenOrThrow() {
|
||||
if (this.apiToken == null && !usesProxy()) {
|
||||
throw new InvalidConfigurationPropertyValueException("management.wavefront.api-token", null,
|
||||
"This property is mandatory whenever publishing directly to the Wavefront API");
|
||||
}
|
||||
return this.apiToken;
|
||||
}
|
||||
|
||||
public String getSourceOrDefault() {
|
||||
if (this.source != null) {
|
||||
return this.source;
|
||||
}
|
||||
return getSourceDefault();
|
||||
}
|
||||
|
||||
private String getSourceDefault() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
}
|
||||
catch (UnknownHostException ex) {
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
private boolean usesProxy() {
|
||||
return "proxy".equals(this.uri.getScheme());
|
||||
}
|
||||
|
||||
public static class Sender {
|
||||
|
||||
/**
|
||||
* Maximum size of queued messages.
|
||||
*/
|
||||
private int maxQueueSize = 50000;
|
||||
|
||||
/**
|
||||
* Flush interval to send queued messages.
|
||||
*/
|
||||
private Duration flushInterval = Duration.ofSeconds(1);
|
||||
|
||||
/**
|
||||
* Maximum size of a message.
|
||||
*/
|
||||
private DataSize messageSize = DataSize.ofBytes(Integer.MAX_VALUE);
|
||||
|
||||
/**
|
||||
* Number of measurements per request to use for Wavefront. If more measurements
|
||||
* are found, then multiple requests will be made.
|
||||
*/
|
||||
private int batchSize = 10000;
|
||||
|
||||
public int getMaxQueueSize() {
|
||||
return this.maxQueueSize;
|
||||
}
|
||||
|
||||
public void setMaxQueueSize(int maxQueueSize) {
|
||||
this.maxQueueSize = maxQueueSize;
|
||||
}
|
||||
|
||||
public Duration getFlushInterval() {
|
||||
return this.flushInterval;
|
||||
}
|
||||
|
||||
public void setFlushInterval(Duration flushInterval) {
|
||||
this.flushInterval = flushInterval;
|
||||
}
|
||||
|
||||
public DataSize getMessageSize() {
|
||||
return this.messageSize;
|
||||
}
|
||||
|
||||
public void setMessageSize(DataSize messageSize) {
|
||||
this.messageSize = messageSize;
|
||||
}
|
||||
|
||||
public int getBatchSize() {
|
||||
return this.batchSize;
|
||||
}
|
||||
|
||||
public void setBatchSize(int batchSize) {
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Metrics {
|
||||
|
||||
/**
|
||||
* Export configuration.
|
||||
*/
|
||||
private Export export = new Export();
|
||||
|
||||
public Export getExport() {
|
||||
return this.export;
|
||||
}
|
||||
|
||||
public void setExport(Export export) {
|
||||
this.export = export;
|
||||
}
|
||||
|
||||
public static class Export extends PushRegistryProperties {
|
||||
|
||||
/**
|
||||
* Global prefix to separate metrics originating from this app's
|
||||
* instrumentation from those originating from other Wavefront integrations
|
||||
* when viewed in the Wavefront UI.
|
||||
*/
|
||||
private String globalPrefix;
|
||||
|
||||
public String getGlobalPrefix() {
|
||||
return this.globalPrefix;
|
||||
}
|
||||
|
||||
public void setGlobalPrefix(String globalPrefix) {
|
||||
this.globalPrefix = globalPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link PushRegistryProperties#getBatchSize()}.
|
||||
*/
|
||||
@Override
|
||||
public Integer getBatchSize() {
|
||||
throw new UnsupportedOperationException("Use Sender.getBatchSize() instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link PushRegistryProperties#setBatchSize(Integer)}.
|
||||
*/
|
||||
@Override
|
||||
public void setBatchSize(Integer batchSize) {
|
||||
throw new UnsupportedOperationException("Use Sender.setBatchSize(int) instead");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Tracing {
|
||||
|
||||
/**
|
||||
* Application name. Defaults to 'spring.application.name'.
|
||||
*/
|
||||
private String applicationName;
|
||||
|
||||
/**
|
||||
* Service name. Defaults to 'spring.application.name'.
|
||||
*/
|
||||
private String serviceName;
|
||||
|
||||
public String getServiceName() {
|
||||
return this.serviceName;
|
||||
}
|
||||
|
||||
public void setServiceName(String serviceName) {
|
||||
this.serviceName = serviceName;
|
||||
}
|
||||
|
||||
public String getApplicationName() {
|
||||
return this.applicationName;
|
||||
}
|
||||
|
||||
public void setApplicationName(String applicationName) {
|
||||
this.applicationName = applicationName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes shared between Wavefront tracing and metrics.
|
||||
*/
|
||||
package org.springframework.boot.actuate.autoconfigure.wavefront;
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.elasticsearch;
|
||||
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ElasticSearchRestHealthContributorAutoConfiguration}.
|
||||
*
|
||||
* @author Filip Hrisafov
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class ElasticSearchRestHealthContributorAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class,
|
||||
ElasticSearchRestHealthContributorAutoConfiguration.class,
|
||||
HealthContributorAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void runShouldCreateIndicator() {
|
||||
this.contextRunner.run((context) -> assertThat(context)
|
||||
.hasSingleBean(ElasticsearchRestClientHealthIndicator.class).hasBean("elasticsearchHealthContributor"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void runWithoutRestHighLevelClientAndWithoutRestClientShouldNotCreateIndicator() {
|
||||
this.contextRunner
|
||||
.withClassLoader(
|
||||
new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class, RestClient.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)
|
||||
.doesNotHaveBean("elasticsearchHealthContributor"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWithoutRestHighLevelClientAndWithRestClientShouldCreateIndicator() {
|
||||
this.contextRunner.withUserConfiguration(CustomRestClientConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class)
|
||||
.hasBean("elasticsearchHealthContributor"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWithRestHighLevelClientAndWithRestClientShouldCreateIndicator() {
|
||||
this.contextRunner.withUserConfiguration(CustomRestHighClientConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class)
|
||||
.hasBean("elasticsearchHealthContributor"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWhenDisabledShouldNotCreateIndicator() {
|
||||
this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)
|
||||
.doesNotHaveBean("elasticsearchHealthContributor"));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomRestClientConfiguration {
|
||||
|
||||
@Bean
|
||||
RestClient customRestClient(RestClientBuilder builder) {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@SuppressWarnings("deprecation")
|
||||
static class CustomRestHighClientConfiguration {
|
||||
|
||||
@Bean
|
||||
org.elasticsearch.client.RestHighLevelClient customRestHighClient(RestClientBuilder builder) {
|
||||
return new org.elasticsearch.client.RestHighLevelClient(builder);
|
||||
}
|
||||
|
||||
@Bean
|
||||
RestClient customClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) {
|
||||
return restHighLevelClient.getLowLevelClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
20
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesMetricsExportTests.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesTests.java
20
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesMetricsExportTests.java → spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesTests.java
@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import brave.Tracer;
|
||||
import brave.Tracing;
|
||||
import brave.propagation.CurrentTraceContext;
|
||||
import brave.propagation.Propagation.Factory;
|
||||
import brave.sampler.Sampler;
|
||||
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
|
||||
import io.micrometer.tracing.brave.bridge.BraveTracer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link BraveAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class BraveAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(BraveAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBraveBeans() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(Tracing.class);
|
||||
assertThat(context).hasSingleBean(Tracer.class);
|
||||
assertThat(context).hasSingleBean(CurrentTraceContext.class);
|
||||
assertThat(context).hasSingleBean(Factory.class);
|
||||
assertThat(context).hasSingleBean(Sampler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBraveBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomBraveConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customTracing");
|
||||
assertThat(context).hasSingleBean(Tracing.class);
|
||||
assertThat(context).hasBean("customTracer");
|
||||
assertThat(context).hasSingleBean(Tracer.class);
|
||||
assertThat(context).hasBean("customCurrentTraceContext");
|
||||
assertThat(context).hasSingleBean(CurrentTraceContext.class);
|
||||
assertThat(context).hasBean("customFactory");
|
||||
assertThat(context).hasSingleBean(Factory.class);
|
||||
assertThat(context).hasBean("customSampler");
|
||||
assertThat(context).hasSingleBean(Sampler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupplyMicrometerBeans() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(BraveTracer.class);
|
||||
assertThat(context).hasSingleBean(BraveBaggageManager.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomMicrometerBraveBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomMicrometerBraveConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customBraveTracer");
|
||||
assertThat(context).hasSingleBean(BraveTracer.class);
|
||||
assertThat(context).hasBean("customBraveBaggageManager");
|
||||
assertThat(context).hasSingleBean(BraveBaggageManager.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyBraveBeansIfBraveIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("brave")).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(Tracing.class);
|
||||
assertThat(context).doesNotHaveBean(Tracer.class);
|
||||
assertThat(context).doesNotHaveBean(CurrentTraceContext.class);
|
||||
assertThat(context).doesNotHaveBean(Factory.class);
|
||||
assertThat(context).doesNotHaveBean(Sampler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyMicrometerBeansIfMicrometerIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer")).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(BraveTracer.class);
|
||||
assertThat(context).doesNotHaveBean(BraveBaggageManager.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomBraveConfiguration {
|
||||
|
||||
@Bean
|
||||
Tracing customTracing() {
|
||||
return Mockito.mock(Tracing.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
Tracer customTracer() {
|
||||
return Mockito.mock(Tracer.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
CurrentTraceContext customCurrentTraceContext() {
|
||||
return Mockito.mock(CurrentTraceContext.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
Factory customFactory() {
|
||||
return Mockito.mock(Factory.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
Sampler customSampler() {
|
||||
return Mockito.mock(Sampler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomMicrometerBraveConfiguration {
|
||||
|
||||
@Bean
|
||||
BraveTracer customBraveTracer() {
|
||||
return Mockito.mock(BraveTracer.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
BraveBaggageManager customBraveBaggageManager() {
|
||||
return Mockito.mock(BraveBaggageManager.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.handler.DefaultTracingObservationHandler;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MicrometerTracingAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class MicrometerTracingAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(MicrometerTracingAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.withUserConfiguration(TracerConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(DefaultTracingObservationHandler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customDefaultTracingObservationHandler");
|
||||
assertThat(context).hasSingleBean(DefaultTracingObservationHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyBeansIfMicrometerIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer"))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(DefaultTracingObservationHandler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyDefaultTracingObservationHandlerIfTracerIsMissing() {
|
||||
this.contextRunner
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(DefaultTracingObservationHandler.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class TracerConfiguration {
|
||||
|
||||
@Bean
|
||||
Tracer tracer() {
|
||||
return Mockito.mock(Tracer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
DefaultTracingObservationHandler customDefaultTracingObservationHandler() {
|
||||
return Mockito.mock(DefaultTracingObservationHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext;
|
||||
import io.micrometer.tracing.otel.bridge.OtelTracer;
|
||||
import io.micrometer.tracing.otel.bridge.OtelTracer.EventPublisher;
|
||||
import io.opentelemetry.api.trace.Tracer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.MicrometerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MicrometerConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class OpenTelemetryConfigurationsMicrometerConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(MicrometerConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.withUserConfiguration(TracerConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(OtelTracer.class);
|
||||
assertThat(context).hasSingleBean(EventPublisher.class);
|
||||
assertThat(context).hasSingleBean(OtelCurrentTraceContext.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyBeansIfMicrometerTracingBridgeOtelIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.tracing.otel"))
|
||||
.withUserConfiguration(TracerConfiguration.class).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(OtelTracer.class);
|
||||
assertThat(context).doesNotHaveBean(EventPublisher.class);
|
||||
assertThat(context).doesNotHaveBean(OtelCurrentTraceContext.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyOtelTracerIfTracerIsMissing() {
|
||||
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(OtelTracer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customOtelTracer");
|
||||
assertThat(context).hasSingleBean(OtelTracer.class);
|
||||
assertThat(context).hasBean("customEventPublisher");
|
||||
assertThat(context).hasSingleBean(EventPublisher.class);
|
||||
assertThat(context).hasBean("customOtelCurrentTraceContext");
|
||||
assertThat(context).hasSingleBean(OtelCurrentTraceContext.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
OtelTracer customOtelTracer() {
|
||||
return Mockito.mock(OtelTracer.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
EventPublisher customEventPublisher() {
|
||||
return Mockito.mock(EventPublisher.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
OtelCurrentTraceContext customOtelCurrentTraceContext() {
|
||||
return Mockito.mock(OtelCurrentTraceContext.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class TracerConfiguration {
|
||||
|
||||
@Bean
|
||||
Tracer tracer() {
|
||||
return Mockito.mock(Tracer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.context.propagation.ContextPropagators;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||
import io.opentelemetry.sdk.trace.SpanProcessor;
|
||||
import io.opentelemetry.sdk.trace.samplers.Sampler;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.SdkConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SdkConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class OpenTelemetryConfigurationsSdkConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(SdkConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(OpenTelemetry.class);
|
||||
assertThat(context).hasSingleBean(SdkTracerProvider.class);
|
||||
assertThat(context).hasSingleBean(ContextPropagators.class);
|
||||
assertThat(context).hasSingleBean(Sampler.class);
|
||||
assertThat(context).hasSingleBean(SpanProcessor.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomBeans.class).run((context) -> {
|
||||
assertThat(context).hasBean("customOpenTelemetry");
|
||||
assertThat(context).hasSingleBean(OpenTelemetry.class);
|
||||
assertThat(context).hasBean("customSdkTracerProvider");
|
||||
assertThat(context).hasSingleBean(SdkTracerProvider.class);
|
||||
assertThat(context).hasBean("customContextPropagators");
|
||||
assertThat(context).hasSingleBean(ContextPropagators.class);
|
||||
assertThat(context).hasBean("customSampler");
|
||||
assertThat(context).hasSingleBean(Sampler.class);
|
||||
assertThat(context).hasBean("customSpanProcessor");
|
||||
assertThat(context).hasSingleBean(SpanProcessor.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyBeansIfSdkIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk")).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(OpenTelemetry.class);
|
||||
assertThat(context).doesNotHaveBean(SdkTracerProvider.class);
|
||||
assertThat(context).doesNotHaveBean(ContextPropagators.class);
|
||||
assertThat(context).doesNotHaveBean(Sampler.class);
|
||||
assertThat(context).doesNotHaveBean(SpanProcessor.class);
|
||||
});
|
||||
}
|
||||
|
||||
private static class CustomBeans {
|
||||
|
||||
@Bean
|
||||
OpenTelemetry customOpenTelemetry() {
|
||||
return Mockito.mock(OpenTelemetry.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
SdkTracerProvider customSdkTracerProvider() {
|
||||
return SdkTracerProvider.builder().build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ContextPropagators customContextPropagators() {
|
||||
return Mockito.mock(ContextPropagators.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
Sampler customSampler() {
|
||||
return Mockito.mock(Sampler.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
SpanProcessor customSpanProcessor() {
|
||||
return Mockito.mock(SpanProcessor.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing;
|
||||
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.api.trace.Tracer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.TracerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link TracerConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class OpenTelemetryConfigurationsTracerConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(TracerConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.withUserConfiguration(OpenTelemetryConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(Tracer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyBeansIfApiIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.api"))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(Tracer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyTracerIfOpenTelemetryIsMissing() {
|
||||
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(Tracer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(OpenTelemetryConfiguration.class, CustomConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("customTracer");
|
||||
assertThat(context).hasSingleBean(Tracer.class);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class OpenTelemetryConfiguration {
|
||||
|
||||
@Bean
|
||||
OpenTelemetry tracer() {
|
||||
return Mockito.mock(OpenTelemetry.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
Tracer customTracer() {
|
||||
return Mockito.mock(Tracer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.wavefront;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Gauge;
|
||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MeterRegistrySpanMetrics}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class MeterRegistrySpanMetricsTests {
|
||||
|
||||
private SimpleMeterRegistry meterRegistry;
|
||||
|
||||
private MeterRegistrySpanMetrics sut;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.meterRegistry = new SimpleMeterRegistry();
|
||||
this.sut = new MeterRegistrySpanMetrics(this.meterRegistry);
|
||||
}
|
||||
|
||||
@Test
|
||||
void reportDroppedShouldIncreaseCounter() {
|
||||
this.sut.reportDropped();
|
||||
assertThat(getCounterValue("wavefront.reporter.spans.dropped")).isEqualTo(1);
|
||||
this.sut.reportDropped();
|
||||
assertThat(getCounterValue("wavefront.reporter.spans.dropped")).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void reportReceivedShouldIncreaseCounter() {
|
||||
this.sut.reportReceived();
|
||||
assertThat(getCounterValue("wavefront.reporter.spans.received")).isEqualTo(1);
|
||||
this.sut.reportReceived();
|
||||
assertThat(getCounterValue("wavefront.reporter.spans.received")).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void reportErrorsShouldIncreaseCounter() {
|
||||
this.sut.reportErrors();
|
||||
assertThat(getCounterValue("wavefront.reporter.errors")).isEqualTo(1);
|
||||
this.sut.reportErrors();
|
||||
assertThat(getCounterValue("wavefront.reporter.errors")).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerQueueSizeShouldCreateGauge() {
|
||||
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(2);
|
||||
this.sut.registerQueueSize(queue);
|
||||
assertThat(getGaugeValue("wavefront.reporter.queue.size")).isEqualTo(0);
|
||||
queue.offer(1);
|
||||
assertThat(getGaugeValue("wavefront.reporter.queue.size")).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerQueueRemainingCapacityShouldCreateGauge() {
|
||||
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(2);
|
||||
this.sut.registerQueueRemainingCapacity(queue);
|
||||
assertThat(getGaugeValue("wavefront.reporter.queue.remaining_capacity")).isEqualTo(2);
|
||||
queue.offer(1);
|
||||
assertThat(getGaugeValue("wavefront.reporter.queue.remaining_capacity")).isEqualTo(1);
|
||||
}
|
||||
|
||||
private double getGaugeValue(String name) {
|
||||
Gauge gauge = this.meterRegistry.find(name).gauge();
|
||||
assertThat(gauge).withFailMessage("Gauge '%s' not found", name).isNotNull();
|
||||
return gauge.value();
|
||||
}
|
||||
|
||||
private double getCounterValue(String name) {
|
||||
Counter counter = this.meterRegistry.find(name).counter();
|
||||
assertThat(counter).withFailMessage("Counter '%s' not found", name).isNotNull();
|
||||
return counter.count();
|
||||
}
|
||||
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.wavefront;
|
||||
|
||||
import com.wavefront.sdk.common.WavefrontSender;
|
||||
import com.wavefront.sdk.common.application.ApplicationTags;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||
import io.micrometer.tracing.reporter.wavefront.SpanMetrics;
|
||||
import io.micrometer.tracing.reporter.wavefront.WavefrontBraveSpanHandler;
|
||||
import io.micrometer.tracing.reporter.wavefront.WavefrontOtelSpanHandler;
|
||||
import io.micrometer.tracing.reporter.wavefront.WavefrontSpanHandler;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link WavefrontTracingAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class WavefrontTracingAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(WavefrontTracingAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(ApplicationTags.class);
|
||||
assertThat(context).hasSingleBean(WavefrontSpanHandler.class);
|
||||
assertThat(context).hasSingleBean(SpanMetrics.class);
|
||||
assertThat(context).hasSingleBean(WavefrontBraveSpanHandler.class);
|
||||
assertThat(context).hasSingleBean(WavefrontOtelSpanHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyBeansIfWavefrontSenderIsMissing() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(ApplicationTags.class);
|
||||
assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class);
|
||||
assertThat(context).doesNotHaveBean(SpanMetrics.class);
|
||||
assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class);
|
||||
assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyBeansIfMicrometerReporterWavefrontIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.tracing.reporter.wavefront"))
|
||||
.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class);
|
||||
assertThat(context).doesNotHaveBean(SpanMetrics.class);
|
||||
assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class);
|
||||
assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupplyMeterRegistrySpanMetricsIfMeterRegistryIsAvailable() {
|
||||
this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class, MeterRegistryConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(SpanMetrics.class);
|
||||
assertThat(context).hasSingleBean(MeterRegistrySpanMetrics.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyWavefrontBraveSpanHandlerIfBraveIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("brave"))
|
||||
.withUserConfiguration(WavefrontSenderConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyWavefrontOtelSpanHandlerIfOtelIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk.trace"))
|
||||
.withUserConfiguration(WavefrontSenderConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHaveADefaultApplicationName() {
|
||||
this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> {
|
||||
ApplicationTags applicationTags = context.getBean(ApplicationTags.class);
|
||||
assertThat(applicationTags.getApplication()).isEqualTo("application");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHonorConfigProperties() {
|
||||
this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class)
|
||||
.withPropertyValues("spring.application.name=super-application",
|
||||
"management.wavefront.tracing.service-name=super-service")
|
||||
.run((context) -> {
|
||||
ApplicationTags applicationTags = context.getBean(ApplicationTags.class);
|
||||
assertThat(applicationTags.getApplication()).isEqualTo("super-application");
|
||||
assertThat(applicationTags.getService()).isEqualTo("super-service");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class, CustomConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasBean("customApplicationTags");
|
||||
assertThat(context).hasSingleBean(ApplicationTags.class);
|
||||
assertThat(context).hasBean("customWavefrontSpanHandler");
|
||||
assertThat(context).hasSingleBean(WavefrontSpanHandler.class);
|
||||
assertThat(context).hasBean("customSpanMetrics");
|
||||
assertThat(context).hasSingleBean(SpanMetrics.class);
|
||||
assertThat(context).hasBean("customWavefrontBraveSpanHandler");
|
||||
assertThat(context).hasSingleBean(WavefrontBraveSpanHandler.class);
|
||||
assertThat(context).hasBean("customWavefrontOtelSpanHandler");
|
||||
assertThat(context).hasSingleBean(WavefrontOtelSpanHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
ApplicationTags customApplicationTags() {
|
||||
return Mockito.mock(ApplicationTags.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
WavefrontSpanHandler customWavefrontSpanHandler() {
|
||||
return Mockito.mock(WavefrontSpanHandler.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
SpanMetrics customSpanMetrics() {
|
||||
return Mockito.mock(SpanMetrics.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
WavefrontBraveSpanHandler customWavefrontBraveSpanHandler() {
|
||||
return Mockito.mock(WavefrontBraveSpanHandler.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
WavefrontOtelSpanHandler customWavefrontOtelSpanHandler() {
|
||||
return Mockito.mock(WavefrontOtelSpanHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class WavefrontSenderConfiguration {
|
||||
|
||||
@Bean
|
||||
WavefrontSender wavefrontSender() {
|
||||
return mock(WavefrontSender.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class MeterRegistryConfiguration {
|
||||
|
||||
@Bean
|
||||
MeterRegistry meterRegistry() {
|
||||
return new SimpleMeterRegistry();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import zipkin2.Call;
|
||||
import zipkin2.Callback;
|
||||
import zipkin2.codec.Encoding;
|
||||
import zipkin2.reporter.Sender;
|
||||
|
||||
class NoopSender extends Sender {
|
||||
|
||||
@Override
|
||||
public Encoding encoding() {
|
||||
return Encoding.JSON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int messageMaxBytes() {
|
||||
return 1024;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int messageSizeInBytes(List<byte[]> encodedSpans) {
|
||||
return encoding().listSizeInBytes(encodedSpans);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Call<Void> sendSpans(List<byte[]> encodedSpans) {
|
||||
return new Call.Base<>() {
|
||||
@Override
|
||||
public Call<Void> clone() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doExecute() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doEnqueue(Callback<Void> callback) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import zipkin2.Span;
|
||||
import zipkin2.codec.BytesEncoder;
|
||||
import zipkin2.codec.SpanBytesEncoder;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ZipkinAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class ZipkinAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ZipkinAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(BytesEncoder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyBeansIfZipkinReporterIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("zipkin2.reporter"))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(BytesEncoder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customBytesEncoder");
|
||||
assertThat(context).hasSingleBean(BytesEncoder.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
BytesEncoder<Span> customBytesEncoder() {
|
||||
return SpanBytesEncoder.JSON_V2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import brave.handler.SpanHandler;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import zipkin2.Span;
|
||||
import zipkin2.reporter.Reporter;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link BraveConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class ZipkinConfigurationsBraveConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(BraveConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.withUserConfiguration(ReporterConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(SpanHandler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplySpanHandlerIfReporterIsMissing() {
|
||||
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(SpanHandler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyIfZipkinReporterBraveIsNotOnClasspath() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("zipkin2.reporter.brave"))
|
||||
.withUserConfiguration(ReporterConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(SpanHandler.class));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customSpanHandler");
|
||||
assertThat(context).hasSingleBean(SpanHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class ReporterConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unchecked")
|
||||
Reporter<Span> reporter() {
|
||||
return Mockito.mock(Reporter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
SpanHandler customSpanHandler() {
|
||||
return Mockito.mock(SpanHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import zipkin2.Span;
|
||||
import zipkin2.codec.BytesEncoder;
|
||||
import zipkin2.codec.SpanBytesEncoder;
|
||||
import zipkin2.reporter.Sender;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link OpenTelemetryConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class ZipkinConfigurationsOpenTelemetryConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(BaseConfiguration.class, OpenTelemetryConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.withUserConfiguration(SenderConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ZipkinSpanExporter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyZipkinSpanExporterIfSenderIsMissing() {
|
||||
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ZipkinSpanExporter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyZipkinSpanExporterIfNotOnClasspath() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.exporter.zipkin"))
|
||||
.withUserConfiguration(SenderConfiguration.class)
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ZipkinSpanExporter.class));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customZipkinSpanExporter");
|
||||
assertThat(context).hasSingleBean(ZipkinSpanExporter.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class SenderConfiguration {
|
||||
|
||||
@Bean
|
||||
Sender sender() {
|
||||
return new NoopSender();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
ZipkinSpanExporter customZipkinSpanExporter() {
|
||||
return ZipkinSpanExporter.builder().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class BaseConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BytesEncoder<Span> spanBytesEncoder() {
|
||||
return SpanBytesEncoder.JSON_V2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import zipkin2.Span;
|
||||
import zipkin2.codec.BytesEncoder;
|
||||
import zipkin2.codec.SpanBytesEncoder;
|
||||
import zipkin2.reporter.Reporter;
|
||||
import zipkin2.reporter.Sender;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.ReporterConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReporterConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class ZipkinConfigurationsReporterConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(BaseConfiguration.class, ReporterConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.withUserConfiguration(SenderConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(Reporter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyReporterIfSenderIsMissing() {
|
||||
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(Reporter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customReporter");
|
||||
assertThat(context).hasSingleBean(Reporter.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class SenderConfiguration {
|
||||
|
||||
@Bean
|
||||
Sender sender() {
|
||||
return new NoopSender();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unchecked")
|
||||
Reporter<Span> customReporter() {
|
||||
return Mockito.mock(Reporter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class BaseConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
BytesEncoder<Span> spanBytesEncoder() {
|
||||
return SpanBytesEncoder.JSON_V2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import zipkin2.reporter.Sender;
|
||||
import zipkin2.reporter.urlconnection.URLConnectionSender;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SenderConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class ZipkinConfigurationsSenderConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(SenderConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldSupplyBeans() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(Sender.class);
|
||||
assertThat(context).hasSingleBean(URLConnectionSender.class);
|
||||
assertThat(context).doesNotHaveBean(ZipkinRestTemplateSender.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseRestTemplateSenderIfUrlConnectionSenderIsNotAvailable() {
|
||||
this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class)
|
||||
.withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection")).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(URLConnectionSender.class);
|
||||
assertThat(context).hasSingleBean(Sender.class);
|
||||
assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSupplyRestTemplateSenderIfNoBuilderIsAvailable() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(ZipkinRestTemplateSender.class);
|
||||
assertThat(context).hasSingleBean(Sender.class);
|
||||
assertThat(context).hasSingleBean(URLConnectionSender.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBackOffOnCustomBeans() {
|
||||
this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasBean("customSender");
|
||||
assertThat(context).hasSingleBean(Sender.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class RestTemplateConfiguration {
|
||||
|
||||
@Bean
|
||||
RestTemplateBuilder restTemplateBuilder() {
|
||||
return new RestTemplateBuilder();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
private static class CustomConfiguration {
|
||||
|
||||
@Bean
|
||||
Sender customSender() {
|
||||
return Mockito.mock(Sender.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.tracing.zipkin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import zipkin2.CheckResult;
|
||||
import zipkin2.reporter.ClosedSenderException;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.test.web.client.MockRestServiceServer;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
|
||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
|
||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
|
||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
|
||||
|
||||
/**
|
||||
* Tests for {@link ZipkinRestTemplateSender}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class ZipkinRestTemplateSenderTests {
|
||||
|
||||
private static final String ZIPKIN_URL = "http://localhost:9411/api/v2/spans";
|
||||
|
||||
private MockRestServiceServer mockServer;
|
||||
|
||||
private ZipkinRestTemplateSender sut;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
this.mockServer = MockRestServiceServer.createServer(restTemplate);
|
||||
this.sut = new ZipkinRestTemplateSender(ZIPKIN_URL, restTemplate);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
this.mockServer.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkShouldSendEmptySpanList() {
|
||||
this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST))
|
||||
.andExpect(content().string("[]")).andRespond(withStatus(HttpStatus.ACCEPTED));
|
||||
assertThat(this.sut.check()).isEqualTo(CheckResult.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkShouldNotRaiseException() {
|
||||
this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST))
|
||||
.andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
|
||||
CheckResult result = this.sut.check();
|
||||
assertThat(result.ok()).isFalse();
|
||||
assertThat(result.error()).hasMessageContaining("500 Internal Server Error");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendSpansShouldSendSpansToZipkin() throws IOException {
|
||||
this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST))
|
||||
.andExpect(content().contentType("application/json")).andExpect(content().string("[span1,span2]"))
|
||||
.andRespond(withStatus(HttpStatus.ACCEPTED));
|
||||
this.sut.sendSpans(List.of(toByteArray("span1"), toByteArray("span2"))).execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendSpansShouldThrowOnHttpFailure() throws IOException {
|
||||
this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST))
|
||||
.andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
|
||||
assertThatThrownBy(() -> this.sut.sendSpans(List.of()).execute())
|
||||
.hasMessageContaining("500 Internal Server Error");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendSpansShouldThrowIfCloseWasCalled() throws IOException {
|
||||
this.sut.close();
|
||||
assertThatThrownBy(() -> this.sut.sendSpans(List.of())).isInstanceOf(ClosedSenderException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendSpansShouldCompressData() throws IOException {
|
||||
String uncompressed = "a".repeat(10000);
|
||||
// This is gzip compressed 10000 times 'a'
|
||||
byte[] compressed = Base64.getDecoder()
|
||||
.decode("H4sIAAAAAAAA/+3BMQ0AAAwDIKFLj/k3UR8NcA8AAAAAAAAAAAADUsAZfeASJwAA");
|
||||
this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST))
|
||||
.andExpect(header("Content-Encoding", "gzip")).andExpect(content().contentType("application/json"))
|
||||
.andExpect(content().bytes(compressed)).andRespond(withStatus(HttpStatus.ACCEPTED));
|
||||
this.sut.sendSpans(List.of(toByteArray(uncompressed))).execute();
|
||||
}
|
||||
|
||||
private byte[] toByteArray(String input) {
|
||||
return input.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.wavefront;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import com.wavefront.sdk.common.WavefrontSender;
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
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.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.as;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link WavefrontAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class WavefrontAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(WavefrontAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldNotFailIfWavefrontIsMissing() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("com.wavefront"))
|
||||
.run(((context) -> assertThat(context).doesNotHaveBean(WavefrontSender.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void failsWithoutAnApiTokenWhenPublishingDirectly() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasFailed());
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultWavefrontSenderSettingsAreConsistent() {
|
||||
this.contextRunner.withPropertyValues("management.wavefront.api-token=abcde").run((context) -> {
|
||||
WavefrontProperties properties = new WavefrontProperties();
|
||||
WavefrontSender sender = context.getBean(WavefrontSender.class);
|
||||
assertThat(sender)
|
||||
.extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class)))
|
||||
.satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size())
|
||||
.isEqualTo(properties.getSender().getMaxQueueSize()));
|
||||
assertThat(sender).hasFieldOrPropertyWithValue("batchSize", properties.getSender().getBatchSize());
|
||||
assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes",
|
||||
(int) properties.getSender().getMessageSize().toBytes());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void configureWavefrontSender() {
|
||||
this.contextRunner.withPropertyValues("management.wavefront.api-token=abcde",
|
||||
"management.wavefront.sender.batch-size=50", "management.wavefront.sender.max-queue-size=100",
|
||||
"management.wavefront.sender.message-size=1KB").run((context) -> {
|
||||
WavefrontSender sender = context.getBean(WavefrontSender.class);
|
||||
assertThat(sender).hasFieldOrPropertyWithValue("batchSize", 50);
|
||||
assertThat(sender)
|
||||
.extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class)))
|
||||
.satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()).isEqualTo(100));
|
||||
assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", 1024);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void allowsWavefrontSenderToBeCustomized() {
|
||||
this.contextRunner.withUserConfiguration(CustomSenderConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(WavefrontSender.class).hasBean("customSender"));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomSenderConfiguration {
|
||||
|
||||
@Bean
|
||||
WavefrontSender customSender() {
|
||||
return mock(WavefrontSender.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.autoconfigure.wavefront;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link WavefrontProperties}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class WavefrontPropertiesTests {
|
||||
|
||||
@Test
|
||||
void apiTokenIsOptionalWhenUsingProxy() {
|
||||
WavefrontProperties sut = new WavefrontProperties();
|
||||
sut.setUri(URI.create("proxy://localhost:2878"));
|
||||
sut.setApiToken(null);
|
||||
assertThat(sut.getApiTokenOrThrow()).isNull();
|
||||
assertThat(sut.getEffectiveUri()).isEqualTo(URI.create("http://localhost:2878"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void apiTokenIsMandatoryWhenNotUsingProxy() {
|
||||
WavefrontProperties sut = new WavefrontProperties();
|
||||
sut.setUri(URI.create("http://localhost:2878"));
|
||||
sut.setApiToken(null);
|
||||
assertThat(sut.getEffectiveUri()).isEqualTo(URI.create("http://localhost:2878"));
|
||||
assertThatThrownBy(sut::getApiTokenOrThrow).isInstanceOf(InvalidConfigurationPropertyValueException.class)
|
||||
.hasMessageContaining("management.wavefront.api-token");
|
||||
}
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.actuate.elasticsearch;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.elasticsearch.client.Request;
|
||||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.json.JsonParser;
|
||||
import org.springframework.boot.json.JsonParserFactory;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* {@link HealthIndicator} for an Elasticsearch cluster using a {@link RestClient}.
|
||||
*
|
||||
* @author Artsiom Yudovin
|
||||
* @author Brian Clozel
|
||||
* @author Filip Hrisafov
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public class ElasticsearchRestClientHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private static final String RED_STATUS = "red";
|
||||
|
||||
private final RestClient client;
|
||||
|
||||
private final JsonParser jsonParser;
|
||||
|
||||
public ElasticsearchRestClientHealthIndicator(RestClient client) {
|
||||
super("Elasticsearch health check failed");
|
||||
this.client = client;
|
||||
this.jsonParser = JsonParserFactory.getJsonParser();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
Response response = this.client.performRequest(new Request("GET", "/_cluster/health/"));
|
||||
StatusLine statusLine = response.getStatusLine();
|
||||
if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
|
||||
builder.down();
|
||||
builder.withDetail("statusCode", statusLine.getStatusCode());
|
||||
builder.withDetail("reasonPhrase", statusLine.getReasonPhrase());
|
||||
return;
|
||||
}
|
||||
try (InputStream inputStream = response.getEntity().getContent()) {
|
||||
doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
private void doHealthCheck(Health.Builder builder, String json) {
|
||||
Map<String, Object> response = this.jsonParser.parseMap(json);
|
||||
String status = (String) response.get("status");
|
||||
if (RED_STATUS.equals(status)) {
|
||||
builder.outOfService();
|
||||
}
|
||||
else {
|
||||
builder.up();
|
||||
}
|
||||
builder.withDetails(response);
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue