Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit a95cc72

Browse files
authored
add support for opencensus http servlet plugin in spring cloud framework (#1650)
* add support for opencensus http servlet plugin in spring cloud framework * fix build error. * Changed filter order. * move to existing spring artifact. * add spring Test Version. * fix review comment. remove files from spring-core. * fix @SInCE annotations.
1 parent 679a51b commit a95cc72

12 files changed

Lines changed: 324 additions & 2 deletions

File tree

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ buildscript {
88
}
99
dependencies {
1010
classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.4.6'
11+
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE")
1112
classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.16'
1213
classpath "net.ltgt.gradle:gradle-apt-plugin:0.18"
1314
classpath 'com.github.ben-manes:gradle-versions-plugin:0.20.0'
@@ -168,6 +169,7 @@ subprojects {
168169
log4j2Version = '2.11.1'
169170
signalfxVersion = '0.0.48'
170171
springBootVersion = '1.5.15.RELEASE'
172+
springBootTestVersion = '2.1.1.RELEASE'
171173
springCloudVersion = '1.3.4.RELEASE'
172174
springVersion = '4.3.12.RELEASE'
173175
prometheusVersion = '0.6.0'
@@ -223,6 +225,7 @@ subprojects {
223225
mockito: 'org.mockito:mockito-core:1.9.5',
224226
spring_test: "org.springframework:spring-test:${springVersion}",
225227
truth: 'com.google.truth:truth:0.44',
228+
spring_boot_test: "org.springframework.boot:spring-boot-starter-test:${springBootTestVersion}",
226229
dropwizard: "io.dropwizard.metrics:metrics-core:${dropwizardVersion}",
227230
dropwizard5: "io.dropwizard.metrics5:metrics-core:${dropwizard5Version}",
228231
]

buildscripts/import-control.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,20 @@ General guidelines on imports:
134134
<allow pkg="io.opencensus.trace"/>
135135
</subpackage>
136136
<subpackage name="spring">
137+
<allow pkg="edu.umd.cs.findbugs.annotations"/>
137138
<allow pkg="io.opencensus.trace"/>
139+
<allow pkg="io.opencensus.contrib.http.servlet"/>
140+
<allow pkg="io.opencensus.contrib.spring"/>
138141
<allow pkg="org.aspectj.lang"/>
139142
<allow pkg="org.aspectj.lang.annotation"/>
140143
<allow pkg="org.aspectj.lang.reflect"/>
141144
<allow pkg="org.springframework.beans.factory.annotation"/>
145+
<allow pkg="org.springframework.beans.factory.config"/>
146+
<allow pkg="org.springframework.boot.autoconfigure"/>
147+
<allow pkg="org.springframework.boot.context"/>
148+
<allow pkg="org.springframework.context.annotation"/>
149+
<allow pkg="org.springframework.core"/>
150+
<allow pkg="org.springframework.stereotype"/>
142151
<subpackage name="sleuth">
143152
<allow pkg="io.opencensus.trace"/>
144153
<allow pkg="org.apache.commons.logging"/>

contrib/spring/build.gradle

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@ apply plugin: 'java'
99

1010
dependencies {
1111
compile project(':opencensus-api'),
12+
project(':opencensus-contrib-http-util'),
13+
project(':opencensus-contrib-http-servlet'),
1214
libraries.spring_aspects,
13-
libraries.spring_context
15+
libraries.spring_context,
16+
libraries.spring_boot_starter_web,
17+
libraries.spring_cloud_build,
18+
libraries.findbugs_annotations
1419

1520
testCompile project(':opencensus-impl'),
1621
project(':opencensus-testing'),
1722
libraries.aspectj,
18-
libraries.spring_test
23+
libraries.spring_test,
24+
libraries.spring_boot_test
1925

2026
signature "org.codehaus.mojo.signature:java17:1.0@signature"
2127
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2019, OpenCensus Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opencensus.contrib.spring.autoconfig;
18+
19+
import io.opencensus.common.ExperimentalApi;
20+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
21+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
22+
import org.springframework.context.annotation.ComponentScan;
23+
import org.springframework.context.annotation.Configuration;
24+
import org.springframework.core.Ordered;
25+
26+
/**
27+
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration Auto-configuration} to
28+
* enable tracing using OpenCensus.
29+
*
30+
* @since 0.23.0
31+
*/
32+
@Configuration
33+
@ComponentScan(basePackages = "io.opencensus")
34+
@ConditionalOnProperty(value = "opencensus.spring.enabled", matchIfMissing = true)
35+
@EnableConfigurationProperties(OpenCensusProperties.class)
36+
@ExperimentalApi
37+
public class OpenCensusAutoConfiguration {
38+
39+
/**
40+
* TRACE_FILTER_ORDER determines the order in which {@link
41+
* io.opencensus.contrib.spring.instrument.web.HttpServletFilter} is invoked. In order to capture
42+
* accurate request processing latency it is desirable that the filter is invoked as early as
43+
* possible. However, there may be some security related filters that my need to execute before,
44+
* hence +5 is added.
45+
*/
46+
public static final int TRACE_FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE + 5;
47+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2019, OpenCensus Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opencensus.contrib.spring.autoconfig;
18+
19+
import org.springframework.boot.context.properties.ConfigurationProperties;
20+
21+
/**
22+
* Opencensus settings.
23+
*
24+
* @since 0.23.0
25+
*/
26+
@ConfigurationProperties("opencensus.spring")
27+
public class OpenCensusProperties {
28+
29+
private boolean enabled = true;
30+
31+
public boolean isEnabled() {
32+
return this.enabled;
33+
}
34+
35+
public void setEnabled(boolean enabled) {
36+
this.enabled = enabled;
37+
}
38+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2019, OpenCensus Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opencensus.contrib.spring.instrument.web;
18+
19+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20+
import io.opencensus.contrib.http.servlet.OcHttpServletFilter;
21+
import io.opencensus.contrib.spring.autoconfig.OpenCensusAutoConfiguration;
22+
import javax.servlet.Filter;
23+
import org.springframework.core.annotation.Order;
24+
import org.springframework.stereotype.Component;
25+
26+
@Component
27+
@Order(OpenCensusAutoConfiguration.TRACE_FILTER_ORDER)
28+
@SuppressFBWarnings("RI_REDUNDANT_INTERFACES")
29+
public class HttpServletFilter extends OcHttpServletFilter implements Filter {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{"properties": [
2+
{
3+
"name": "opencensus.spring.enabled",
4+
"type": "java.lang.Boolean",
5+
"description": "Enable Spring Integration Opencensus Instrumentation.",
6+
"defaultValue": true
7+
}
8+
]}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Auto Configuration
2+
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
3+
io.opencensus.contrib.spring.autoconfig.OpenCensusAutoConfiguration
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2019, OpenCensus Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opencensus.contrib.spring.instrument.web;
18+
19+
import org.junit.Before;
20+
import org.springframework.beans.factory.annotation.Autowired;
21+
import org.springframework.test.context.web.WebAppConfiguration;
22+
import org.springframework.test.web.servlet.MockMvc;
23+
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
24+
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
25+
import org.springframework.web.context.WebApplicationContext;
26+
import org.springframework.web.servlet.view.InternalResourceViewResolver;
27+
28+
@WebAppConfiguration
29+
public abstract class AbstractMvcIntegrationTest {
30+
31+
@Autowired protected WebApplicationContext webApplicationContext;
32+
33+
protected MockMvc mockMvc;
34+
35+
@Before
36+
public void setup() {
37+
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
38+
viewResolver.setPrefix("/WEB-INF/jsp/view/");
39+
viewResolver.setSuffix(".jsp");
40+
DefaultMockMvcBuilder mockMvcBuilder =
41+
MockMvcBuilders.webAppContextSetup(this.webApplicationContext);
42+
configureMockMvcBuilder(mockMvcBuilder);
43+
this.mockMvc = mockMvcBuilder.build();
44+
}
45+
46+
/**
47+
* Override in a subclass to modify mockMvcBuilder configuration (e.g. add filter).
48+
*
49+
* <p>The method from super class should be called.
50+
*/
51+
protected void configureMockMvcBuilder(DefaultMockMvcBuilder mockMvcBuilder) {}
52+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright 2019, OpenCensus Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opencensus.contrib.spring.instrument.web;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import io.opencensus.testing.export.TestHandler;
22+
import io.opencensus.trace.Tracing;
23+
import io.opencensus.trace.config.TraceParams;
24+
import io.opencensus.trace.export.SpanData;
25+
import io.opencensus.trace.export.SpanExporter;
26+
import io.opencensus.trace.samplers.Samplers;
27+
import java.util.List;
28+
import org.junit.After;
29+
import org.junit.Before;
30+
import org.junit.Test;
31+
import org.junit.runner.RunWith;
32+
import org.springframework.beans.factory.annotation.Autowired;
33+
import org.springframework.boot.test.context.SpringBootTest;
34+
import org.springframework.context.annotation.Configuration;
35+
import org.springframework.http.MediaType;
36+
import org.springframework.test.context.ContextConfiguration;
37+
import org.springframework.test.context.junit4.SpringRunner;
38+
import org.springframework.test.web.servlet.MvcResult;
39+
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
40+
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
41+
import org.springframework.web.bind.annotation.RequestMapping;
42+
import org.springframework.web.bind.annotation.RestController;
43+
44+
@RunWith(SpringRunner.class)
45+
@SpringBootTest(
46+
classes = HttpServletFilterIntegrationTests.Config.class,
47+
properties = "opencensus.spring.enabled=true")
48+
@ContextConfiguration(
49+
locations = {"file:src/test/resources/beans/HttpServletFilterIntegrationTest-context.xml"})
50+
public class HttpServletFilterIntegrationTests extends AbstractMvcIntegrationTest {
51+
52+
private TestHandler handler;
53+
54+
@Autowired HttpServletFilter httpServletFilter;
55+
56+
@Before
57+
@Override
58+
public void setup() {
59+
super.setup();
60+
handler = new TestHandler();
61+
62+
SpanExporter exporter = Tracing.getExportComponent().getSpanExporter();
63+
exporter.registerHandler("testing", handler);
64+
65+
TraceParams params =
66+
Tracing.getTraceConfig()
67+
.getActiveTraceParams()
68+
.toBuilder()
69+
.setSampler(Samplers.alwaysSample())
70+
.build();
71+
Tracing.getTraceConfig().updateActiveTraceParams(params);
72+
}
73+
74+
@After
75+
public void teardown() {
76+
SpanExporter exporter = Tracing.getExportComponent().getSpanExporter();
77+
exporter.unregisterHandler("testing");
78+
}
79+
80+
@Override
81+
protected void configureMockMvcBuilder(DefaultMockMvcBuilder mockMvcBuilder) {
82+
mockMvcBuilder.addFilters(this.httpServletFilter);
83+
}
84+
85+
@Test(timeout = 10000)
86+
public void shouldCreateServerTrace() throws Exception {
87+
sendRequest();
88+
89+
List<SpanData> data = handler.waitForExport(1);
90+
assertThat(data).isNotNull();
91+
assertThat(data.size()).isEqualTo(1);
92+
assertThat(data.get(0).getName()).isEqualTo("/foo");
93+
}
94+
95+
private MvcResult sendRequest() throws Exception {
96+
MvcResult result =
97+
this.mockMvc
98+
.perform(MockMvcRequestBuilders.get("/foo").accept(MediaType.TEXT_PLAIN))
99+
.andReturn();
100+
return result;
101+
}
102+
103+
@Configuration
104+
protected static class Config {
105+
106+
@RestController
107+
public static class TestController {
108+
109+
@RequestMapping("/foo")
110+
public String ping() {
111+
return "fooResult";
112+
}
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)