Skip to content

Commit 9048466

Browse files
Update Springboot to 3.2.2 (#789)
- Updated SpringBoot to 3.2.2 to fix CVE-2024-22233 - Fix springboot autoconfiguration config bug in app starter
1 parent b564165 commit 9048466

File tree

17 files changed

+155
-76
lines changed

17 files changed

+155
-76
lines changed

allow-list.xml

+7
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,11 @@
88
<cve>CVE-2022-45688</cve>
99
<cve>CVE-2023-5072</cve>
1010
</suppress>
11+
<suppress>
12+
<notes><![CDATA[
13+
From SpringBoot bom dependency
14+
]]></notes>
15+
<gav>com.jayway.jsonpath:json-path:2.8.0</gav>
16+
<cve>CVE-2023-51074</cve>
17+
</suppress>
1118
</suppressions>

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
22
id "io.github.gradle-nexus.publish-plugin" version "1.3.0"
3-
id "org.owasp.dependencycheck" version "8.2.1"
3+
id "org.owasp.dependencycheck" version "9.0.9"
44
}
55

66
ext.projectVersion = '3.0.0-SNAPSHOT'

symphony-bdk-bom/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ repositories {
1616

1717
dependencies {
1818
// import Spring Boot's BOM
19-
api platform('org.springframework.boot:spring-boot-dependencies:3.2.1')
19+
api platform('org.springframework.boot:spring-boot-dependencies:3.2.2')
2020
// import Jackson's BOM
2121
api platform('com.fasterxml.jackson:jackson-bom:2.16.0')
2222
// import Jersey's BOM

symphony-bdk-examples/bdk-app-spring-boot-example/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
22
id 'bdk.java-common-conventions'
3-
id 'org.springframework.boot' version "3.2.1"
3+
id 'org.springframework.boot' version "3.2.2"
44
}
55

66
description = 'Symphony Java BDK Examples for the SpringBoot integration'

symphony-bdk-examples/bdk-spring-boot-example/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
22
id 'bdk.java-common-conventions'
3-
id 'org.springframework.boot' version "3.2.1"
3+
id 'org.springframework.boot' version "3.2.2"
44
}
55

66
description = 'Symphony Java BDK Examples for the SpringBoot integration'

symphony-bdk-spring/symphony-bdk-app-spring-boot-starter/src/main/java/com/symphony/bdk/app/spring/SymphonyBdkAppAutoConfiguration.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package com.symphony.bdk.app.spring;
22

33
import com.symphony.bdk.app.spring.config.BdkExtAppControllerConfig;
4-
54
import com.symphony.bdk.app.spring.config.BdkExtAppSecurityConfig;
6-
75
import com.symphony.bdk.app.spring.config.BdkExtAppTracingFilterConfig;
6+
import com.symphony.bdk.app.spring.config.BdkHealthIndicatorConfig;
87

98
import org.springframework.boot.context.properties.EnableConfigurationProperties;
109
import org.springframework.context.annotation.Import;
@@ -15,7 +14,8 @@
1514
@Import({
1615
BdkExtAppControllerConfig.class,
1716
BdkExtAppSecurityConfig.class,
18-
BdkExtAppTracingFilterConfig.class
17+
BdkExtAppTracingFilterConfig.class,
18+
BdkHealthIndicatorConfig.class
1919
})
2020
@EnableConfigurationProperties(SymphonyBdkAppProperties.class)
2121
public class SymphonyBdkAppAutoConfiguration {

symphony-bdk-spring/symphony-bdk-app-spring-boot-starter/src/main/java/com/symphony/bdk/app/spring/config/BdkExtAppControllerConfig.java

+3-11
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,19 @@
44
import com.symphony.bdk.app.spring.auth.CircleOfTrustController;
55
import com.symphony.bdk.app.spring.auth.service.CircleOfTrustService;
66
import com.symphony.bdk.app.spring.exception.GlobalControllerExceptionHandler;
7-
import com.symphony.bdk.app.spring.service.SymphonyBdkHealthIndicator;
87
import com.symphony.bdk.core.auth.ExtensionAppAuthenticator;
9-
import com.symphony.bdk.core.service.health.HealthService;
108
import com.symphony.bdk.spring.SymphonyBdkCoreProperties;
119

12-
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
1310
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
1411
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
1512
import org.springframework.context.annotation.Bean;
1613

1714
/**
1815
* Configuration and injection of the main rest controllers for extension app APIs as beans within the Spring application context.
1916
*/
20-
public class BdkExtAppControllerConfig {
2117

22-
@Bean
23-
@ConditionalOnProperty("bdk.bot.username")
24-
@ConditionalOnMissingBean
25-
public SymphonyBdkHealthIndicator symphonyBdkHealthIndicator(HealthService healthService) {
26-
return new SymphonyBdkHealthIndicator(healthService);
27-
}
18+
@ConditionalOnProperty(name = "bdk-app.auth.enabled", havingValue = "true")
19+
public class BdkExtAppControllerConfig {
2820

2921
@Bean
3022
@ConditionalOnMissingBean
@@ -34,7 +26,7 @@ public CircleOfTrustService circleOfTrustService(ExtensionAppAuthenticator authe
3426
}
3527

3628
@Bean
37-
@ConditionalOnProperty(name = "bdk-app.auth.enabled", havingValue = "true")
29+
@ConditionalOnMissingBean
3830
public CircleOfTrustController circleOfTrustController(
3931
SymphonyBdkAppProperties properties,
4032
CircleOfTrustService circleOfTrustService

symphony-bdk-spring/symphony-bdk-app-spring-boot-starter/src/main/java/com/symphony/bdk/app/spring/config/BdkExtAppSecurityConfig.java

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import lombok.RequiredArgsConstructor;
77
import lombok.extern.slf4j.Slf4j;
8+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
89
import org.springframework.context.annotation.Bean;
910
import org.springframework.web.cors.CorsConfiguration;
1011
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@@ -17,6 +18,7 @@
1718
*/
1819
@Slf4j
1920
@RequiredArgsConstructor
21+
@ConditionalOnProperty(name = "bdk-app.auth.enabled", havingValue = "true")
2022
public class BdkExtAppSecurityConfig {
2123
private final SymphonyBdkAppProperties properties;
2224

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.symphony.bdk.app.spring.config;
2+
3+
import com.symphony.bdk.app.spring.service.SymphonyBdkHealthIndicator;
4+
import com.symphony.bdk.app.spring.service.SymphonyBdkHealthIndicator.CustomStatusCodeMapper;
5+
import com.symphony.bdk.core.service.health.HealthService;
6+
7+
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
8+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
9+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
10+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
11+
import org.springframework.context.annotation.Bean;
12+
13+
14+
@ConditionalOnProperty("bdk.bot.username")
15+
public class BdkHealthIndicatorConfig {
16+
17+
@Bean(name = "bot")
18+
@ConditionalOnMissingBean
19+
public SymphonyBdkHealthIndicator symphonyBdkHealthIndicator(HealthService healthService) {
20+
return new SymphonyBdkHealthIndicator(healthService);
21+
}
22+
23+
@Bean
24+
@ConditionalOnBean(name = "bot")
25+
public HttpCodeStatusMapper customStatusCodeMapper() {
26+
return new CustomStatusCodeMapper();
27+
}
28+
}

symphony-bdk-spring/symphony-bdk-app-spring-boot-starter/src/main/java/com/symphony/bdk/app/spring/service/SymphonyBdkHealthIndicator.java

+33-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.apiguardian.api.API;
1313
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
1414
import org.springframework.boot.actuate.health.Health;
15+
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
1516
import org.springframework.boot.actuate.health.Status;
1617

1718
import java.util.Map;
@@ -49,8 +50,7 @@ protected void doHealthCheck(Health.Builder builder) throws Exception {
4950
V3Health health = healthService.healthCheckExtended();
5051
buildHealthDetail(builder, health);
5152
} catch (ApiRuntimeException e) {
52-
log.debug("Health check failed, trying to parse the failure response body.", e);
53-
log.trace("Health check failure response body - {}", e.getResponseBody());
53+
log.warn("Health check response with exception, try parse the response entity - [{}]", e.getMessage());
5454
try {
5555
V3Health health = MAPPER.readValue(e.getResponseBody(), V3Health.class);
5656
buildHealthDetail(builder, health);
@@ -91,4 +91,35 @@ private void buildHealthDownDetail(Health.Builder builder) {
9191
.withDetail(CE, DOWN)
9292
.withDetail(DFL, DOWN);
9393
}
94+
95+
96+
/**
97+
* A custom spring actuator health endpoint status code mapper.
98+
*
99+
* It will return 500 for all status except Status.UP
100+
*/
101+
@API(status = API.Status.INTERNAL)
102+
public static class CustomStatusCodeMapper implements HttpCodeStatusMapper {
103+
104+
@Override
105+
public int getStatusCode(Status status) {
106+
if (status == Status.DOWN) {
107+
return 500;
108+
}
109+
110+
if (status == Status.OUT_OF_SERVICE) {
111+
return 503;
112+
}
113+
114+
if (status == Status.UNKNOWN) {
115+
return 500;
116+
}
117+
118+
if (status.getCode().equals(WARNING)) {
119+
return 500;
120+
}
121+
122+
return 200;
123+
}
124+
}
94125
}

symphony-bdk-spring/symphony-bdk-app-spring-boot-starter/src/main/resources/META-INF/spring.factories

-2
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.symphony.bdk.app.spring.SymphonyBdkAppAutoConfiguration

symphony-bdk-spring/symphony-bdk-app-spring-boot-starter/src/test/java/com/symphony/bdk/app/spring/config/BdkExtAppControllerConfigTest.java

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
package com.symphony.bdk.app.spring.config;
22

3-
import static org.junit.jupiter.api.Assertions.assertNotNull;
4-
import static org.mockito.Mockito.mock;
5-
63
import com.symphony.bdk.app.spring.SymphonyBdkAppProperties;
74
import com.symphony.bdk.app.spring.auth.service.CircleOfTrustService;
8-
import com.symphony.bdk.core.service.health.HealthService;
95

106
import org.junit.jupiter.api.Test;
117

12-
public class BdkExtAppControllerConfigTest {
13-
14-
@Test
15-
void createSymphonyBdkHealthIndicatorTest() {
16-
final BdkExtAppControllerConfig config = new BdkExtAppControllerConfig();
17-
final HealthService healthService = mock(HealthService.class);
8+
import static org.junit.jupiter.api.Assertions.assertNotNull;
9+
import static org.mockito.Mockito.mock;
1810

19-
assertNotNull(config.symphonyBdkHealthIndicator(healthService));
20-
}
11+
public class BdkExtAppControllerConfigTest {
2112

2213
@Test
2314
void createCircleOfTrustControllerTest() {

symphony-bdk-spring/symphony-bdk-app-spring-boot-starter/src/test/java/com/symphony/bdk/app/spring/config/BdkExtAppSecurityConfigTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class BdkExtAppSecurityConfigTest {
1414
void corsFilters() {
1515
final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
1616
.withPropertyValues(
17+
"bdk-app.auth.enabled=true",
1718
"bdk-app.cors.[/**].allowed-origins=*",
1819
"bdk-app.cors.[/**].allow-credentials=false",
1920
"bdk-app.cors.[/**].allowed-methods=POST,GET",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.symphony.bdk.app.spring.config;
2+
3+
import com.symphony.bdk.core.service.health.HealthService;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
import static org.junit.jupiter.api.Assertions.*;
8+
import static org.mockito.Mockito.mock;
9+
10+
class BdkHealthIndicatorConfigTest {
11+
12+
@Test
13+
void createSymphonyBdkHealthIndicatorTest() {
14+
final BdkHealthIndicatorConfig config = new BdkHealthIndicatorConfig();
15+
final HealthService healthService = mock(HealthService.class);
16+
17+
assertNotNull(config.symphonyBdkHealthIndicator(healthService));
18+
19+
assertNotNull(config.customStatusCodeMapper());
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,33 @@
11
package com.symphony.bdk.app.spring.service;
22

3-
import static org.assertj.core.api.Assertions.assertThat;
4-
import static org.mockito.Mockito.doThrow;
5-
import static org.mockito.Mockito.when;
6-
3+
import com.symphony.bdk.app.spring.service.SymphonyBdkHealthIndicator.CustomStatusCodeMapper;
74
import com.symphony.bdk.core.service.health.HealthService;
85
import com.symphony.bdk.gen.api.model.V3Health;
96
import com.symphony.bdk.gen.api.model.V3HealthComponent;
107
import com.symphony.bdk.gen.api.model.V3HealthStatus;
118
import com.symphony.bdk.http.api.ApiException;
129
import com.symphony.bdk.http.api.ApiRuntimeException;
1310

11+
import org.junit.jupiter.api.Nested;
1412
import org.junit.jupiter.api.Test;
1513
import org.junit.jupiter.api.extension.ExtendWith;
14+
import org.junit.jupiter.params.ParameterizedTest;
15+
import org.junit.jupiter.params.provider.Arguments;
16+
import org.junit.jupiter.params.provider.CsvSource;
17+
import org.junit.jupiter.params.provider.MethodSource;
1618
import org.mockito.InjectMocks;
1719
import org.mockito.Mock;
1820
import org.mockito.junit.jupiter.MockitoExtension;
1921
import org.springframework.boot.actuate.health.Health;
22+
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
23+
import org.springframework.boot.actuate.health.Status;
2024

2125
import java.util.Collections;
26+
import java.util.stream.Stream;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
import static org.mockito.Mockito.doThrow;
30+
import static org.mockito.Mockito.when;
2231

2332
@ExtendWith(MockitoExtension.class)
2433
class SymphonyBdkHealthIndicatorTest {
@@ -59,34 +68,15 @@ void doHealthCheck_withCEDown_up() throws Exception {
5968

6069
@Test
6170
void doHealthCheck_exception() throws Exception {
62-
final String body = "{\n"
63-
+ " \"status\": \"UP\",\n"
64-
+ " \"version\": \"2.57.0\",\n"
65-
+ " \"services\": {\n"
66-
+ " \"pod\": {\n"
67-
+ " \"status\": \"UP\",\n"
68-
+ " \"version\": \"1.57.0\"\n"
69-
+ " },\n"
70-
+ " \"datafeed\": {\n"
71-
+ " \"status\": \"UP\",\n"
72-
+ " \"version\": \"2.1.28\"\n"
73-
+ " },\n"
74-
+ " \"key_manager\": {\n"
75-
+ " \"status\": \"UP\",\n"
76-
+ " \"version\": \"1.56.0\"\n"
77-
+ " }\n"
78-
+ " },\n"
79-
+ " \"users\": {\n"
80-
+ " \"agentservice\": {\n"
81-
+ " \"status\": \"DOWN\"\n"
82-
+ " },\n"
83-
+ " \"ceservice\": {\n"
84-
+ " \"status\": \"DOWN\",\n"
85-
+ " \"message\": \"Ceservice authentication credentials missing or misconfigured\"\n"
86-
+ " }\n"
87-
+ " }\n"
88-
+ "}";
89-
71+
final String body =
72+
"{\n" + " \"status\": \"UP\",\n" + " \"version\": \"2.57.0\",\n" + " \"services\": {\n" + " \"pod\": {\n"
73+
+ " \"status\": \"UP\",\n" + " \"version\": \"1.57.0\"\n" + " },\n" + " \"datafeed\": {\n"
74+
+ " \"status\": \"UP\",\n" + " \"version\": \"2.1.28\"\n" + " },\n"
75+
+ " \"key_manager\": {\n" + " \"status\": \"UP\",\n" + " \"version\": \"1.56.0\"\n" + " }\n"
76+
+ " },\n" + " \"users\": {\n" + " \"agentservice\": {\n" + " \"status\": \"DOWN\"\n" + " },\n"
77+
+ " \"ceservice\": {\n" + " \"status\": \"DOWN\",\n"
78+
+ " \"message\": \"Ceservice authentication credentials missing or misconfigured\"\n" + " }\n"
79+
+ " }\n" + "}";
9080

9181
doThrow(new ApiRuntimeException(new ApiException(503, "message", Collections.EMPTY_MAP, body))).when(healthService)
9282
.healthCheckExtended();
@@ -99,13 +89,8 @@ void doHealthCheck_exception() throws Exception {
9989

10090
@Test
10191
void doHealthCheck_badGw_exception() throws Exception {
102-
final String body = "<html>\n"
103-
+ "<head><title>502 Bad Gateway</title></head>\n"
104-
+ "<body>\n"
105-
+ "<center><h1>502 Bad Gateway</h1></center>\n"
106-
+ "</body>\n"
107-
+ "</html>";
108-
92+
final String body = "<html>\n" + "<head><title>502 Bad Gateway</title></head>\n" + "<body>\n"
93+
+ "<center><h1>502 Bad Gateway</h1></center>\n" + "</body>\n" + "</html>";
10994

11095
doThrow(new ApiRuntimeException(new ApiException(502, "message", Collections.EMPTY_MAP, body))).when(healthService)
11196
.healthCheckExtended();
@@ -114,4 +99,25 @@ void doHealthCheck_badGw_exception() throws Exception {
11499
Health build = builder.build();
115100
assertThat(build.getStatus().getCode()).isEqualTo("DOWN");
116101
}
102+
103+
@Nested
104+
class CustomStatusCodeMapperTest {
105+
106+
HttpCodeStatusMapper mapper = new CustomStatusCodeMapper();
107+
108+
@ParameterizedTest
109+
@MethodSource("getStatusArguments")
110+
void getStatusCode_status_code(Status status, int code) {
111+
assertThat(mapper.getStatusCode(status)).isEqualTo(code);
112+
}
113+
114+
private static Stream<Arguments> getStatusArguments() {
115+
return Stream.of(
116+
Arguments.of(Status.UP, 200),
117+
Arguments.of(Status.DOWN, 500),
118+
Arguments.of(new Status("WARNING"), 500),
119+
Arguments.of(Status.OUT_OF_SERVICE, 503),
120+
Arguments.of(Status.UNKNOWN, 500));
121+
}
122+
}
117123
}

0 commit comments

Comments
 (0)