Skip to content

Commit c16df34

Browse files
committed
Update SpringBoot
1 parent 966a12c commit c16df34

9 files changed

Lines changed: 59 additions & 108 deletions

File tree

pom.xml

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<dependency>
2424
<groupId>org.springframework.boot</groupId>
2525
<artifactId>spring-boot-dependencies</artifactId>
26-
<version>3.5.7</version>
26+
<version>4.0.0</version>
2727
<type>pom</type>
2828
<scope>import</scope>
2929
</dependency>
@@ -36,12 +36,6 @@
3636
<groupId>com.fasterxml.jackson.core</groupId>
3737
<artifactId>jackson-databind</artifactId>
3838
</dependency>
39-
<dependency>
40-
<groupId>com.redis.testcontainers</groupId>
41-
<artifactId>testcontainers-redis-junit-jupiter</artifactId>
42-
<version>1.4.6</version>
43-
<scope>test</scope>
44-
</dependency>
4539

4640
<!-- Latest ArDoCo dependencies using snapshot versions -->
4741
<dependency>
@@ -67,32 +61,33 @@
6761
<dependency>
6862
<groupId>org.junit.jupiter</groupId>
6963
<artifactId>junit-jupiter</artifactId>
70-
<version>${junit.version}</version>
7164
<scope>test</scope>
7265
</dependency>
7366
<dependency>
7467
<groupId>org.junit.jupiter</groupId>
7568
<artifactId>junit-jupiter-api</artifactId>
76-
<version>${junit.version}</version>
7769
<scope>test</scope>
7870
</dependency>
7971
<dependency>
8072
<groupId>org.junit.jupiter</groupId>
8173
<artifactId>junit-jupiter-engine</artifactId>
82-
<version>${junit.version}</version>
8374
<scope>test</scope>
8475
</dependency>
8576
<dependency>
8677
<groupId>org.junit.jupiter</groupId>
8778
<artifactId>junit-jupiter-params</artifactId>
88-
<version>${junit.version}</version>
8979
<scope>test</scope>
9080
</dependency>
9181

9282
<dependency>
9383
<groupId>org.springdoc</groupId>
9484
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
95-
<version>2.8.13</version>
85+
<version>3.0.0</version>
86+
</dependency>
87+
<dependency>
88+
<groupId>org.springframework.boot</groupId>
89+
<artifactId>spring-boot-resttestclient</artifactId>
90+
<scope>test</scope>
9691
</dependency>
9792
<dependency>
9893
<groupId>org.springframework.boot</groupId>
@@ -115,21 +110,14 @@
115110
<groupId>org.springframework.boot</groupId>
116111
<artifactId>spring-boot-starter-web</artifactId>
117112
</dependency>
118-
119113
<dependency>
120-
<groupId>org.springframework.boot</groupId>
121-
<artifactId>spring-boot-testcontainers</artifactId>
122-
<scope>test</scope>
114+
<groupId>org.testcontainers</groupId>
115+
<artifactId>testcontainers</artifactId>
123116
</dependency>
124-
125-
<!-- Testcontainers JUnit Jupiter -->
126117
<dependency>
127118
<groupId>org.testcontainers</groupId>
128-
<artifactId>junit-jupiter</artifactId>
129-
<version>1.21.3</version>
130-
<scope>test</scope>
119+
<artifactId>testcontainers-junit-jupiter</artifactId>
131120
</dependency>
132-
133121
<!-- Jedis Redis Client -->
134122
<dependency>
135123
<groupId>redis.clients</groupId>

src/main/java/edu/kit/kastel/mcse/ardoco/tlr/rest/ArDoCoRestApplication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import org.springframework.boot.SpringApplication;
55
import org.springframework.boot.autoconfigure.SpringBootApplication;
6-
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
6+
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
77
import org.springframework.scheduling.annotation.EnableAsync;
88

99
import io.swagger.v3.oas.annotations.OpenAPIDefinition;

src/main/java/edu/kit/kastel/mcse/ardoco/tlr/rest/api/api_response/ArdocoResultResponse.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
import org.springframework.http.HttpStatus;
55

6+
import com.fasterxml.jackson.annotation.JsonIgnore;
7+
import com.fasterxml.jackson.annotation.JsonProperty;
8+
69
/**
710
* Represents the response structure for the ArDoCo API results.
811
*/
@@ -75,6 +78,17 @@ public void setRequestId(String requestId) {
7578
*
7679
* @return the HTTP status of the response
7780
*/
81+
@JsonProperty("status")
82+
public String getStatusName() {
83+
return status != null ? status.name() : null;
84+
}
85+
86+
/**
87+
* Getter for status (returns HttpStatus object).
88+
*
89+
* @return the HTTP status of the response
90+
*/
91+
@JsonIgnore
7892
public HttpStatus getStatus() {
7993
return status;
8094
}

src/main/java/edu/kit/kastel/mcse/ardoco/tlr/rest/api/converter/FileConverter.java

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
/* Licensed under MIT 2025. */
22
package edu.kit.kastel.mcse.ardoco.tlr.rest.api.converter;
33

4-
import java.io.BufferedReader;
54
import java.io.ByteArrayOutputStream;
65
import java.io.File;
76
import java.io.IOException;
8-
import java.io.InputStreamReader;
9-
import java.nio.charset.Charset;
10-
import java.nio.charset.StandardCharsets;
117
import java.nio.file.Files;
128
import java.util.List;
13-
import java.util.regex.Matcher;
14-
import java.util.regex.Pattern;
159

1610
import org.springframework.web.multipart.MultipartFile;
1711

@@ -25,8 +19,6 @@
2519
*/
2620
public final class FileConverter {
2721

28-
private static final Pattern ENCODING_PATTERN = Pattern.compile("encoding=\"([^\"]+)\"");
29-
3022
private FileConverter() {
3123
}
3224

@@ -68,7 +60,7 @@ public static byte[] convertFilesToByte(List<File> files) throws FileConversionE
6860
*/
6961
public static File convertMultipartFileToFile(MultipartFile multipartFile) throws FileNotFoundException, FileConversionException {
7062
if (multipartFile == null) {
71-
throw new FileConversionException("Multipart file with name" + multipartFile.getOriginalFilename() + "is null.");
63+
throw new FileConversionException("Multipart file is null.");
7264
}
7365

7466
if (multipartFile.isEmpty()) {
@@ -88,30 +80,4 @@ public static File convertMultipartFileToFile(MultipartFile multipartFile) throw
8880
throw new FileConversionException("Error occurred while transferring the MultipartFile to File: " + e.getMessage(), e);
8981
}
9082
}
91-
92-
/**
93-
* Detects the encoding from the XML prolog in the MultipartFile.
94-
* If no encoding is specified, UTF-8 is used by default.
95-
* This method reads the first line of the file and attempts to parse the encoding from an XML declaration.
96-
*
97-
* @param multipartFile the multipart file to check for encoding
98-
* @return the detected Charset, or UTF-8 as the default if no encoding is specified
99-
* @throws IOException if an I/O error occurs
100-
*/
101-
private static Charset detectEncodingOfFile(MultipartFile multipartFile) throws IOException {
102-
// Read the first few lines of the file to detect the encoding, since XML files declare the encoding usually there
103-
try (BufferedReader reader = new BufferedReader(new InputStreamReader(multipartFile.getInputStream(), StandardCharsets.UTF_8))) {
104-
String firstLine = reader.readLine();
105-
106-
if (firstLine != null && firstLine.startsWith("<?xml")) {
107-
Matcher matcher = ENCODING_PATTERN.matcher(firstLine);
108-
if (matcher.find()) {
109-
String encoding = matcher.group(1);
110-
return Charset.forName(encoding);
111-
}
112-
}
113-
}
114-
115-
return StandardCharsets.UTF_8;
116-
}
11783
}

src/main/java/edu/kit/kastel/mcse/ardoco/tlr/rest/api/exception/GlobalExceptionHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public GlobalExceptionHandler() {
4444
@ApiResponse(responseCode = "422", description = "When the provided file is empty or doesn't exist", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)))
4545
public ResponseEntity<ErrorResponse> handleFileNotFoundException(FileNotFoundException ex) {
4646
logger.error(ex.getMessage(), ex);
47-
ErrorResponse error = new ErrorResponse(HttpStatus.UNPROCESSABLE_ENTITY, ex.getMessage());
47+
ErrorResponse error = new ErrorResponse(HttpStatus.UNPROCESSABLE_CONTENT, ex.getMessage());
4848
return new ResponseEntity<>(error, error.getStatus());
4949
}
5050

@@ -58,7 +58,7 @@ public ResponseEntity<ErrorResponse> handleFileNotFoundException(FileNotFoundExc
5858
@ApiResponse(responseCode = "422", description = "When the provided file cannot be converted", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)))
5959
public ResponseEntity<ErrorResponse> handleFileConversionException(FileConversionException ex) {
6060
logger.error(ex.getMessage(), ex);
61-
ErrorResponse error = new ErrorResponse(HttpStatus.UNPROCESSABLE_ENTITY, ex.getMessage());
61+
ErrorResponse error = new ErrorResponse(HttpStatus.UNPROCESSABLE_CONTENT, ex.getMessage());
6262
return new ResponseEntity<>(error, error.getStatus());
6363
}
6464

@@ -86,7 +86,7 @@ public ResponseEntity<ErrorResponse> handleArdocoException(ArdocoException ex) {
8686
@ApiResponse(responseCode = "422", description = "One of the Provided Argument is invalid.", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)))
8787
public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex) {
8888
logger.error(ex.getMessage(), ex);
89-
ErrorResponse error = new ErrorResponse(HttpStatus.UNPROCESSABLE_ENTITY, ex.getMessage());
89+
ErrorResponse error = new ErrorResponse(HttpStatus.UNPROCESSABLE_CONTENT, ex.getMessage());
9090
return new ResponseEntity<>(error, error.getStatus());
9191
}
9292

src/test/java/RedisTestContainerTest.java

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

src/test/java/edu/kit/kastel/mcse/ardoco/tlr/rest/api/controller/AbstractTLRControllerTest.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
import org.junit.jupiter.api.Test;
1414
import org.junit.jupiter.api.Timeout;
1515
import org.springframework.beans.factory.annotation.Autowired;
16+
import org.springframework.boot.resttestclient.TestRestTemplate;
1617
import org.springframework.boot.test.context.SpringBootTest;
17-
import org.springframework.boot.test.web.client.TestRestTemplate;
18+
import org.springframework.boot.test.web.server.LocalServerPort;
1819
import org.springframework.http.HttpEntity;
1920
import org.springframework.http.HttpMethod;
2021
import org.springframework.http.HttpStatus;
@@ -42,8 +43,10 @@ public abstract class AbstractTLRControllerTest {
4243
private final String runPipelineAndWaitEndpoint;
4344
private final TraceLinkType traceLinkType;
4445

45-
@Autowired
46-
protected TestRestTemplate restTemplate;
46+
@LocalServerPort
47+
private int port;
48+
49+
protected TestRestTemplate restTemplate = new TestRestTemplate();
4750

4851
@Autowired
4952
protected RedisAccessor redisAccessor;
@@ -79,6 +82,10 @@ public AbstractTLRControllerTest(TraceLinkType traceLinkType) {
7982
this.runPipelineAndWaitEndpoint = String.format("/api/%s/start-and-wait", endpointName);
8083
}
8184

85+
private String getBaseUrl() {
86+
return "http://localhost:" + port;
87+
}
88+
8289
// Common test method for starting pipeline and getting results
8390
@Timeout(value = 6, unit = TimeUnit.MINUTES)
8491
protected void runPipeline_start_and_getResult(HttpEntity<MultiValueMap<String, Object>> requestEntity) throws IOException {
@@ -103,30 +110,33 @@ void testRetrievingResultForInvalidId() {
103110
String invalidId = "invalid-project-id";
104111

105112
// testGetResult
106-
ResponseEntity<ErrorResponse> responseEntity = restTemplate.getForEntity(GET_RESULT_ENDPOINT, ErrorResponse.class, invalidId);
113+
String getUrl = getBaseUrl() + GET_RESULT_ENDPOINT;
114+
ResponseEntity<ErrorResponse> responseEntity = restTemplate.getForEntity(getUrl, ErrorResponse.class, invalidId);
107115
TestUtils.testInvalidRequestId(responseEntity, invalidId);
108116

109117
// testWaitForResult
110-
responseEntity = restTemplate.getForEntity(WAIT_FOR_RESULT_ENDPOINT, ErrorResponse.class, invalidId);
118+
String waitUrl = getBaseUrl() + WAIT_FOR_RESULT_ENDPOINT;
119+
responseEntity = restTemplate.getForEntity(waitUrl, ErrorResponse.class, invalidId);
111120
TestUtils.testInvalidRequestId(responseEntity, invalidId);
112121
}
113122

114123
@Test
115124
void testHandleEmptyFile() {
116125
HttpEntity<MultiValueMap<String, Object>> requestEntity = prepareRequestEntityForEmptyFileTest("emptyFileProject");
117126

118-
ResponseEntity<ErrorResponse> responseEntity = restTemplate.exchange(runPipelineEndpoint, HttpMethod.POST, requestEntity, ErrorResponse.class);
127+
ResponseEntity<ErrorResponse> responseEntity = restTemplate.exchange(getBaseUrl() + runPipelineEndpoint, HttpMethod.POST, requestEntity,
128+
ErrorResponse.class);
119129
TestUtils.testsForHandelingEmptyFiles(responseEntity);
120130

121-
responseEntity = restTemplate.exchange(runPipelineAndWaitEndpoint, HttpMethod.POST, requestEntity, ErrorResponse.class);
131+
responseEntity = restTemplate.exchange(getBaseUrl() + runPipelineAndWaitEndpoint, HttpMethod.POST, requestEntity, ErrorResponse.class);
122132
TestUtils.testsForHandelingEmptyFiles(responseEntity);
123133
}
124134

125135
protected abstract HttpEntity<MultiValueMap<String, Object>> prepareRequestEntityForEmptyFileTest(String projectName);
126136

127137
protected void test_runPipelineAndWaitForResult_helper(HttpEntity<MultiValueMap<String, Object>> requestEntity) throws IOException {
128138
// test whether runPipeLineAndWait() directly has the result
129-
ResponseEntity<String> responseEntity = restTemplate.exchange(runPipelineAndWaitEndpoint, HttpMethod.POST, requestEntity, String.class);
139+
ResponseEntity<String> responseEntity = restTemplate.exchange(getBaseUrl() + runPipelineAndWaitEndpoint, HttpMethod.POST, requestEntity, String.class);
130140
assertNotNull(responseEntity.getBody());
131141
ArdocoResultResponse response = TestUtils.parseResponseEntityToArdocoResponse(responseEntity);
132142

@@ -155,22 +165,24 @@ protected void test_runPipelineAndWaitForResult_helper(HttpEntity<MultiValueMap<
155165

156166
// Helper methods for common test logic
157167
protected ArdocoResultResponse startNewPipeline_test(HttpEntity<MultiValueMap<String, Object>> requestEntity) throws IOException {
158-
ResponseEntity<String> responseEntity = restTemplate.exchange(runPipelineEndpoint, HttpMethod.POST, requestEntity, String.class);
168+
ResponseEntity<String> responseEntity = restTemplate.exchange(getBaseUrl() + runPipelineEndpoint, HttpMethod.POST, requestEntity, String.class);
159169
assertNotNull(responseEntity.getBody());
160170
return TestUtils.parseResponseEntityToArdocoResponse(responseEntity);
161171
}
162172

163173
protected void tryGetResultWhenNotReady_test(String projectId) throws IOException {
164-
ResponseEntity<String> responseEntity = restTemplate.getForEntity(GET_RESULT_ENDPOINT, String.class, projectId);
174+
String url = getBaseUrl() + GET_RESULT_ENDPOINT;
175+
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class, projectId);
165176
ArdocoResultResponse response = TestUtils.parseResponseEntityToArdocoResponse(responseEntity);
166177
TestUtils.testGetResult_notReady(response, responseEntity, traceLinkType);
167178
resultIsNotInDatabase(response.getRequestId());
168179
}
169180

170181
protected void waitForResultUntilReady_test(String projectId) throws IOException {
182+
String url = getBaseUrl() + WAIT_FOR_RESULT_ENDPOINT;
171183
ResponseEntity<String> waitingEntity;
172184
do {
173-
waitingEntity = restTemplate.getForEntity(WAIT_FOR_RESULT_ENDPOINT, String.class, projectId);
185+
waitingEntity = restTemplate.getForEntity(url, String.class, projectId);
174186
ArdocoResultResponse waitingResponse = TestUtils.parseResponseEntityToArdocoResponse(waitingEntity);
175187

176188
if (waitingEntity.getStatusCode() == HttpStatus.ACCEPTED) {
@@ -187,22 +199,23 @@ protected void waitForResultUntilReady_test(String projectId) throws IOException
187199
}
188200

189201
protected void getResult_hasResult_test(String projectId) throws IOException {
190-
ResponseEntity<String> responseEntity = restTemplate.getForEntity(GET_RESULT_ENDPOINT, String.class, projectId);
202+
String url = getBaseUrl() + GET_RESULT_ENDPOINT;
203+
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class, projectId);
191204
ArdocoResultResponse response = TestUtils.parseResponseEntityToArdocoResponse(responseEntity);
192205
TestUtils.testGetResult_ready(response, responseEntity, traceLinkType);
193206
resultIsInDatabase(response.getRequestId());
194207
}
195208

196209
protected void runPipeLineDirectlyHasResult_test(HttpEntity<MultiValueMap<String, Object>> requestEntity) throws IOException {
197-
ResponseEntity<String> responseEntity = restTemplate.exchange(runPipelineEndpoint, HttpMethod.POST, requestEntity, String.class);
210+
ResponseEntity<String> responseEntity = restTemplate.exchange(getBaseUrl() + runPipelineEndpoint, HttpMethod.POST, requestEntity, String.class);
198211
assertNotNull(responseEntity.getBody());
199212
ArdocoResultResponse response = TestUtils.parseResponseEntityToArdocoResponse(responseEntity);
200213
TestUtils.testStartPipeline_resultIsInDatabase(response, responseEntity, traceLinkType);
201214
resultIsInDatabase(response.getRequestId());
202215
}
203216

204217
protected void runPipeLineAndWaitDirectlyHasResult_test(HttpEntity<MultiValueMap<String, Object>> requestEntity) throws IOException {
205-
ResponseEntity<String> responseEntity = restTemplate.exchange(runPipelineAndWaitEndpoint, HttpMethod.POST, requestEntity, String.class);
218+
ResponseEntity<String> responseEntity = restTemplate.exchange(getBaseUrl() + runPipelineAndWaitEndpoint, HttpMethod.POST, requestEntity, String.class);
206219
assertNotNull(responseEntity.getBody());
207220
ArdocoResultResponse response = TestUtils.parseResponseEntityToArdocoResponse(responseEntity);
208221
TestUtils.testStartPipeline_resultIsInDatabase(response, responseEntity, traceLinkType);

src/test/java/edu/kit/kastel/mcse/ardoco/tlr/rest/api/repository/RedisAccessorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void testNonExistentKey() {
7272
void testSaveResultMultipleValues() {
7373
String key = "testKey";
7474
String value = "testValue";
75-
String id = redisAccessor.saveResult(key, value);
75+
redisAccessor.saveResult(key, value);
7676
assertEquals(value, redisAccessor.getResult(key));
7777

7878
String updatedValue = "updatedValue";

0 commit comments

Comments
 (0)