From 31302ceea5edd59dba8129eedb737d56b35e19a3 Mon Sep 17 00:00:00 2001 From: teetangh Date: Sun, 24 Aug 2025 15:24:57 +0530 Subject: [PATCH 1/3] Update project configuration and dependencies - Added .env and .DS_Store to .gitignore. - Updated Gradle wrapper to version 9.0. - Changed base.archivesName in build.gradle for consistency. - Added dotenv-java dependency for environment variable loading. - Refactored Couchbase configuration to use updated property names. - Modified AirportController and AirportRepository to use Slice instead of Page for direct connections. - Updated integration tests to reflect changes in response types and improved error logging. These changes enhance the project's configuration and improve the handling of Couchbase connections. --- .env.example | 12 +++++ .github/workflows/tests.yaml | 9 +++- .gitignore | 4 ++ build.gradle | 5 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../config/CouchbaseConfiguration.java | 10 ++-- .../config/DotEnvConfiguration.java | 48 +++++++++++++++++++ .../controller/AirportController.java | 7 +-- .../springdata/models/RestResponseSlice.java | 27 +++++++++++ .../repository/AirportRepository.java | 5 +- .../springdata/services/AirportService.java | 3 +- src/main/resources/META-INF/spring.factories | 1 + src/main/resources/application.properties | 21 +++++--- .../controllers/AirlineIntegrationTest.java | 3 +- .../controllers/AirportIntegrationTest.java | 14 +++--- .../controllers/RouteIntegrationTest.java | 3 +- 16 files changed, 144 insertions(+), 30 deletions(-) create mode 100644 .env.example create mode 100644 src/main/java/org/couchbase/quickstart/springdata/config/DotEnvConfiguration.java create mode 100644 src/main/java/org/couchbase/quickstart/springdata/models/RestResponseSlice.java create mode 100644 src/main/resources/META-INF/spring.factories diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..6f9b3a5 --- /dev/null +++ b/.env.example @@ -0,0 +1,12 @@ +# Copy this file to .env and update with your actual values +# DO NOT commit .env file to git - it's already in .gitignore +# +# These environment variables are used for database connection +# and correspond to the Spring Boot 3.5+ Couchbase properties: +# - spring.couchbase.connection-string +# - spring.couchbase.username +# - spring.couchbase.password + +DB_CONN_STR=couchbases://your-cluster-url.cloud.couchbase.com +DB_USERNAME=your-username +DB_PASSWORD=your-password \ No newline at end of file diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index ad359cd..f58297c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,14 +31,19 @@ jobs: uses: actions/setup-java@v4 with: java-version: ${{ matrix.java-version }} - distribution: "adopt" + distribution: "temurin" cache: "gradle" + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + with: + gradle-home-cache-cleanup: true + - name: Run Gradle Tests id: run run: | chmod +x gradlew - ./gradlew clean test --info --stacktrace + ./gradlew clean test --info --stacktrace --configuration-cache - name: Report Status if: always() diff --git a/.gitignore b/.gitignore index ff5af65..a39d3af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ +.env + +.DS_Store *.iml +logs/ .gradle build/ diff --git a/build.gradle b/build.gradle index 62cd758..27c73a1 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { group = 'org.couchbase.quickstart.springdata' version = '0.0.1-SNAPSHOT' -archivesBaseName = 'java-springdata-quickstart' +base.archivesName = 'java-springdata-quickstart' repositories { mavenCentral() @@ -26,6 +26,9 @@ dependencies { implementation 'jakarta.persistence:jakarta.persistence-api' implementation 'jakarta.servlet:jakarta.servlet-api' + + // Environment variable loading from .env file + implementation 'io.github.cdimascio:dotenv-java:3.0.2' // lombok compileOnly 'org.projectlombok:lombok' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a80b22c..2dcec85 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/org/couchbase/quickstart/springdata/config/CouchbaseConfiguration.java b/src/main/java/org/couchbase/quickstart/springdata/config/CouchbaseConfiguration.java index 9048297..6ef1516 100644 --- a/src/main/java/org/couchbase/quickstart/springdata/config/CouchbaseConfiguration.java +++ b/src/main/java/org/couchbase/quickstart/springdata/config/CouchbaseConfiguration.java @@ -18,17 +18,17 @@ @EnableCouchbaseRepositories public class CouchbaseConfiguration extends AbstractCouchbaseConfiguration { - @Value("#{systemEnvironment['DB_CONN_STR'] ?: '${spring.couchbase.bootstrap-hosts:localhost}'}") + @Value("#{systemEnvironment['DB_CONN_STR'] ?: '${spring.couchbase.connection-string:localhost}'}") private String host; - @Value("#{systemEnvironment['DB_USERNAME'] ?: '${spring.couchbase.bucket.user:Administrator}'}") + @Value("#{systemEnvironment['DB_USERNAME'] ?: '${spring.couchbase.username:Administrator}'}") private String username; - @Value("#{systemEnvironment['DB_PASSWORD'] ?: '${spring.couchbase.bucket.password:password}'}") + @Value("#{systemEnvironment['DB_PASSWORD'] ?: '${spring.couchbase.password:password}'}") private String password; - @Value("${spring.couchbase.bucket.name:travel-sample}") - private String bucketName; + // Since bucket auto-configuration is removed, we'll hardcode the travel-sample bucket name + private String bucketName = "travel-sample"; @Override public String getConnectionString() { diff --git a/src/main/java/org/couchbase/quickstart/springdata/config/DotEnvConfiguration.java b/src/main/java/org/couchbase/quickstart/springdata/config/DotEnvConfiguration.java new file mode 100644 index 0000000..2a0bf69 --- /dev/null +++ b/src/main/java/org/couchbase/quickstart/springdata/config/DotEnvConfiguration.java @@ -0,0 +1,48 @@ +package org.couchbase.quickstart.springdata.config; + +import io.github.cdimascio.dotenv.Dotenv; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; + +import java.util.HashMap; +import java.util.Map; + +public class DotEnvConfiguration implements ApplicationContextInitializer { + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + ConfigurableEnvironment environment = applicationContext.getEnvironment(); + + try { + // Load .env file if it exists + Dotenv dotenv = Dotenv.configure() + .directory(".") + .ignoreIfMalformed() + .ignoreIfMissing() + .load(); + + // Create a property source from .env entries + Map envMap = new HashMap<>(); + dotenv.entries().forEach(entry -> { + String key = entry.getKey(); + String value = entry.getValue(); + + // Only add if not already set by system environment + if (System.getenv(key) == null) { + envMap.put(key, value); + System.out.println("Loaded from .env: " + key); + } + }); + + if (!envMap.isEmpty()) { + environment.getPropertySources().addFirst(new MapPropertySource("dotenv", envMap)); + System.out.println("Environment variables loaded from .env file: " + envMap.keySet()); + } + + } catch (Exception e) { + System.err.println("Could not load .env file: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/couchbase/quickstart/springdata/controller/AirportController.java b/src/main/java/org/couchbase/quickstart/springdata/controller/AirportController.java index 7c2c9c7..be84f2a 100644 --- a/src/main/java/org/couchbase/quickstart/springdata/controller/AirportController.java +++ b/src/main/java/org/couchbase/quickstart/springdata/controller/AirportController.java @@ -8,6 +8,7 @@ import org.springframework.dao.DataRetrievalFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -162,13 +163,13 @@ public ResponseEntity> listAirports(@RequestParam(defaultValue = " @ApiResponse(responseCode = "500", description = "Internal server error") }) @Parameter(name = "airportCode", description = "The airport code to list direct connections", required = true, example = "SFO") - public ResponseEntity> listDirectConnections( + public ResponseEntity> listDirectConnections( @RequestParam(required = true) String airportCode, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { try { - Page airports = airportService.getDirectConnections(airportCode, PageRequest.of(page, size)); - Page directConnections = airports.map(Route::getDestinationAirport); + Slice airports = airportService.getDirectConnections(airportCode, PageRequest.of(page, size)); + Slice directConnections = airports.map(Route::getDestinationAirport); return new ResponseEntity<>(directConnections, HttpStatus.OK); } catch (Exception e) { diff --git a/src/main/java/org/couchbase/quickstart/springdata/models/RestResponseSlice.java b/src/main/java/org/couchbase/quickstart/springdata/models/RestResponseSlice.java new file mode 100644 index 0000000..e758a1b --- /dev/null +++ b/src/main/java/org/couchbase/quickstart/springdata/models/RestResponseSlice.java @@ -0,0 +1,27 @@ +package org.couchbase.quickstart.springdata.models; + +import java.util.List; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.SliceImpl; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; + +public class RestResponseSlice extends SliceImpl { + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public RestResponseSlice(@JsonProperty("content") List content, + @JsonProperty("number") int number, + @JsonProperty("size") int size, + @JsonProperty("pageable") JsonNode pageable, + @JsonProperty("last") boolean last, + @JsonProperty("sort") JsonNode sort, + @JsonProperty("first") boolean first, + @JsonProperty("numberOfElements") int numberOfElements, + @JsonProperty("hasNext") boolean hasNext) { + + super(content, PageRequest.of(number, size), hasNext); + } + +} \ No newline at end of file diff --git a/src/main/java/org/couchbase/quickstart/springdata/repository/AirportRepository.java b/src/main/java/org/couchbase/quickstart/springdata/repository/AirportRepository.java index b552463..d871e9e 100644 --- a/src/main/java/org/couchbase/quickstart/springdata/repository/AirportRepository.java +++ b/src/main/java/org/couchbase/quickstart/springdata/repository/AirportRepository.java @@ -9,6 +9,7 @@ import org.springframework.data.couchbase.repository.Scope; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.stereotype.Repository; import com.couchbase.client.java.query.QueryScanConsistency; @@ -22,10 +23,10 @@ public interface AirportRepository extends CouchbaseRepository @Query("SELECT META(airport).id as __id,airport.* FROM airport") Page findAll(Pageable pageable); - @Query("SELECT DISTINCT META(route).id as __id,route.* " + + @Query("SELECT META(route).id as __id,route.* " + "FROM airport as airport " + "JOIN route as route ON airport.faa = route.sourceairport " + "WHERE airport.faa = $1 AND route.stops = 0") - Page getDirectConnections(String targetAirportCode, Pageable pageable); + Slice getDirectConnections(String targetAirportCode, Pageable pageable); } \ No newline at end of file diff --git a/src/main/java/org/couchbase/quickstart/springdata/services/AirportService.java b/src/main/java/org/couchbase/quickstart/springdata/services/AirportService.java index a00482c..aba4d52 100644 --- a/src/main/java/org/couchbase/quickstart/springdata/services/AirportService.java +++ b/src/main/java/org/couchbase/quickstart/springdata/services/AirportService.java @@ -7,6 +7,7 @@ import org.couchbase.quickstart.springdata.repository.AirportRepository; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; @Service @@ -43,7 +44,7 @@ public Airport updateAirport(String id, Airport airport) { return airportRepository.save(airport); } - public Page getDirectConnections(String id, Pageable pageable) { + public Slice getDirectConnections(String id, Pageable pageable) { return airportRepository.getDirectConnections(id, pageable); } diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..9820932 --- /dev/null +++ b/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.context.ApplicationContextInitializer=org.couchbase.quickstart.springdata.config.DotEnvConfiguration \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 62c63db..f54c49d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,8 +1,15 @@ -server.use-forward-headers=true +# Server configuration server.forward-headers-strategy=framework -spring.couchbase.bootstrap-hosts=DB_CONN_STR -spring.couchbase.bucket.name=travel-sample -spring.couchbase.bucket.user=DB_USERNAME -spring.couchbase.bucket.password=DB_PASSWORD -spring.couchbase.scope.name=inventory -spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER \ No newline at end of file + +# Modern Couchbase configuration (Spring Boot 3.5+) +spring.couchbase.connection-string=${DB_CONN_STR} +spring.couchbase.username=${DB_USERNAME} +spring.couchbase.password=${DB_PASSWORD} + +# Couchbase connection and query optimizations +spring.couchbase.env.timeouts.query=30000ms +spring.couchbase.env.timeouts.key-value=5000ms +spring.couchbase.env.timeouts.connect=10000ms + +# Spring MVC configuration +spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER diff --git a/src/test/java/org/couchbase/quickstart/springdata/controllers/AirlineIntegrationTest.java b/src/test/java/org/couchbase/quickstart/springdata/controllers/AirlineIntegrationTest.java index 985ee67..154832d 100644 --- a/src/test/java/org/couchbase/quickstart/springdata/controllers/AirlineIntegrationTest.java +++ b/src/test/java/org/couchbase/quickstart/springdata/controllers/AirlineIntegrationTest.java @@ -47,7 +47,8 @@ private void deleteAirline(String baseUri, String airlineId) { } catch (DocumentNotFoundException | DataRetrievalFailureException | ResourceAccessException e) { log.warn("Document " + airlineId + " not present prior to test"); } catch (Exception e) { - log.error("Error deleting test data", e.getMessage()); + log.error("Error deleting test data for airline {}: {}", airlineId, e.getMessage()); + // Continue with cleanup even if one deletion fails } } diff --git a/src/test/java/org/couchbase/quickstart/springdata/controllers/AirportIntegrationTest.java b/src/test/java/org/couchbase/quickstart/springdata/controllers/AirportIntegrationTest.java index 901c739..032d1e5 100644 --- a/src/test/java/org/couchbase/quickstart/springdata/controllers/AirportIntegrationTest.java +++ b/src/test/java/org/couchbase/quickstart/springdata/controllers/AirportIntegrationTest.java @@ -5,6 +5,7 @@ import org.couchbase.quickstart.springdata.models.Airport; import org.couchbase.quickstart.springdata.models.Airport.Geo; import org.couchbase.quickstart.springdata.models.RestResponsePage; +import org.couchbase.quickstart.springdata.models.RestResponseSlice; import org.couchbase.quickstart.springdata.services.AirportService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -46,9 +47,10 @@ private void deleteAirport(String baseUri, String airportId) { restTemplate.delete(baseUri + "/api/v1/airport/" + airportId); } } catch (DocumentNotFoundException | DataRetrievalFailureException | ResourceAccessException e) { - log.warn("Document " + airportId + " not present prior to test"); + log.warn("Document {} not present prior to test", airportId); } catch (Exception e) { - log.error("Error deleting test data", e.getMessage()); + log.error("Error deleting test data for airport {}: {}", airportId, e.getMessage()); + // Continue with cleanup even if one deletion fails } } @@ -168,14 +170,14 @@ void testListAirports() { @Test void testListDirectConnections() { String airportCode = "LAX"; - ResponseEntity> response = restTemplate.exchange( + ResponseEntity> response = restTemplate.exchange( "/api/v1/airport/direct-connections?airportCode=" + airportCode + "&page=0&size=10", - HttpMethod.GET, null, new ParameterizedTypeReference>() { + HttpMethod.GET, null, new ParameterizedTypeReference>() { }); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - RestResponsePage directConnections = response.getBody(); + RestResponseSlice directConnections = response.getBody(); assertThat(directConnections).isNotNull().hasSize(10); assertThat(directConnections).contains("NRT", "CUN", "GDL", "HMO", "MEX", "MZT", "PVR", "SJD", "ZIH", @@ -184,7 +186,7 @@ void testListDirectConnections() { airportCode = "JFK"; response = restTemplate.exchange( "/api/v1/airport/direct-connections?airportCode=" + airportCode + "&page=0&size=10", - HttpMethod.GET, null, new ParameterizedTypeReference>() { + HttpMethod.GET, null, new ParameterizedTypeReference>() { }); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); diff --git a/src/test/java/org/couchbase/quickstart/springdata/controllers/RouteIntegrationTest.java b/src/test/java/org/couchbase/quickstart/springdata/controllers/RouteIntegrationTest.java index a5cf34c..c18b0e8 100644 --- a/src/test/java/org/couchbase/quickstart/springdata/controllers/RouteIntegrationTest.java +++ b/src/test/java/org/couchbase/quickstart/springdata/controllers/RouteIntegrationTest.java @@ -49,7 +49,8 @@ private void deleteRoute(String baseUri, String routeId) { } catch (DocumentNotFoundException | DataRetrievalFailureException | ResourceAccessException e) { log.warn("Document " + routeId + " not present prior to test"); } catch (Exception e) { - log.error("Error deleting test data", e.getMessage()); + log.error("Error deleting test data for route {}: {}", routeId, e.getMessage()); + // Continue with cleanup even if one deletion fails } } From 0d51a471efe4f6d533a2911e61e4e3a9927c9a6f Mon Sep 17 00:00:00 2001 From: teetangh Date: Sun, 24 Aug 2025 15:45:05 +0530 Subject: [PATCH 2/3] Update Gradle wrapper and enhance logging in DotEnvConfiguration - Updated Gradle wrapper distribution URL to version 9.0.0. - Replaced System.out logging with SLF4J logging in DotEnvConfiguration for better logging practices. - Added @JsonIgnoreProperties annotation to RestResponseSlice to ignore unknown properties during JSON deserialization. These changes improve project configuration and logging consistency. --- gradle/wrapper/gradle-wrapper.properties | 2 +- .../springdata/config/DotEnvConfiguration.java | 10 +++++++--- .../springdata/models/RestResponseSlice.java | 4 ++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2dcec85..2a84e18 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/org/couchbase/quickstart/springdata/config/DotEnvConfiguration.java b/src/main/java/org/couchbase/quickstart/springdata/config/DotEnvConfiguration.java index 2a0bf69..2ca650d 100644 --- a/src/main/java/org/couchbase/quickstart/springdata/config/DotEnvConfiguration.java +++ b/src/main/java/org/couchbase/quickstart/springdata/config/DotEnvConfiguration.java @@ -1,6 +1,8 @@ package org.couchbase.quickstart.springdata.config; import io.github.cdimascio.dotenv.Dotenv; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; @@ -11,6 +13,8 @@ public class DotEnvConfiguration implements ApplicationContextInitializer { + private static final Logger log = LoggerFactory.getLogger(DotEnvConfiguration.class); + @Override public void initialize(ConfigurableApplicationContext applicationContext) { ConfigurableEnvironment environment = applicationContext.getEnvironment(); @@ -32,17 +36,17 @@ public void initialize(ConfigurableApplicationContext applicationContext) { // Only add if not already set by system environment if (System.getenv(key) == null) { envMap.put(key, value); - System.out.println("Loaded from .env: " + key); + log.debug("Loaded from .env: {}", key); } }); if (!envMap.isEmpty()) { environment.getPropertySources().addFirst(new MapPropertySource("dotenv", envMap)); - System.out.println("Environment variables loaded from .env file: " + envMap.keySet()); + log.info("Environment variables loaded from .env file: {}", envMap.keySet()); } } catch (Exception e) { - System.err.println("Could not load .env file: " + e.getMessage()); + log.error("Could not load .env file", e); } } } \ No newline at end of file diff --git a/src/main/java/org/couchbase/quickstart/springdata/models/RestResponseSlice.java b/src/main/java/org/couchbase/quickstart/springdata/models/RestResponseSlice.java index e758a1b..6068798 100644 --- a/src/main/java/org/couchbase/quickstart/springdata/models/RestResponseSlice.java +++ b/src/main/java/org/couchbase/quickstart/springdata/models/RestResponseSlice.java @@ -6,9 +6,11 @@ import org.springframework.data.domain.SliceImpl; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; +@JsonIgnoreProperties(ignoreUnknown = true) public class RestResponseSlice extends SliceImpl { @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) public RestResponseSlice(@JsonProperty("content") List content, @@ -21,6 +23,8 @@ public RestResponseSlice(@JsonProperty("content") List content, @JsonProperty("numberOfElements") int numberOfElements, @JsonProperty("hasNext") boolean hasNext) { + // Calculate hasNext from the available information + // For Slice, hasNext is typically determined by whether we have more content super(content, PageRequest.of(number, size), hasNext); } From c5f14169fe9be8be68f44b3673d450055b1a115f Mon Sep 17 00:00:00 2001 From: teetangh Date: Sun, 24 Aug 2025 16:03:41 +0530 Subject: [PATCH 3/3] Refactor logging in integration tests and remove unused dependency - Removed the unused 'jakarta.persistence:jakarta.persistence-api' dependency from build.gradle. - Updated error logging in AirlineIntegrationTest, AirportIntegrationTest, and RouteIntegrationTest to use debug level for expected cleanup failures. These changes streamline the project by eliminating unnecessary dependencies and improving logging clarity during test cleanup. --- build.gradle | 1 - .../controllers/AirlineIntegrationTest.java | 2 +- .../controllers/AirportIntegrationTest.java | 2 +- .../controllers/RouteIntegrationTest.java | 2 +- src/test/resources/logback-test.xml | 48 +++++++++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/test/resources/logback-test.xml diff --git a/build.gradle b/build.gradle index 27c73a1..6619ee5 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,6 @@ dependencies { implementation 'org.springframework.data:spring-data-couchbase' implementation 'org.springframework.boot:spring-boot-devtools' - implementation 'jakarta.persistence:jakarta.persistence-api' implementation 'jakarta.servlet:jakarta.servlet-api' // Environment variable loading from .env file diff --git a/src/test/java/org/couchbase/quickstart/springdata/controllers/AirlineIntegrationTest.java b/src/test/java/org/couchbase/quickstart/springdata/controllers/AirlineIntegrationTest.java index 154832d..0ad1e2e 100644 --- a/src/test/java/org/couchbase/quickstart/springdata/controllers/AirlineIntegrationTest.java +++ b/src/test/java/org/couchbase/quickstart/springdata/controllers/AirlineIntegrationTest.java @@ -47,7 +47,7 @@ private void deleteAirline(String baseUri, String airlineId) { } catch (DocumentNotFoundException | DataRetrievalFailureException | ResourceAccessException e) { log.warn("Document " + airlineId + " not present prior to test"); } catch (Exception e) { - log.error("Error deleting test data for airline {}: {}", airlineId, e.getMessage()); + log.debug("Cleanup: Could not delete test airline {}: {} (this is expected during test cleanup)", airlineId, e.getMessage()); // Continue with cleanup even if one deletion fails } } diff --git a/src/test/java/org/couchbase/quickstart/springdata/controllers/AirportIntegrationTest.java b/src/test/java/org/couchbase/quickstart/springdata/controllers/AirportIntegrationTest.java index 032d1e5..a9227ec 100644 --- a/src/test/java/org/couchbase/quickstart/springdata/controllers/AirportIntegrationTest.java +++ b/src/test/java/org/couchbase/quickstart/springdata/controllers/AirportIntegrationTest.java @@ -49,7 +49,7 @@ private void deleteAirport(String baseUri, String airportId) { } catch (DocumentNotFoundException | DataRetrievalFailureException | ResourceAccessException e) { log.warn("Document {} not present prior to test", airportId); } catch (Exception e) { - log.error("Error deleting test data for airport {}: {}", airportId, e.getMessage()); + log.debug("Cleanup: Could not delete test airport {}: {} (this is expected during test cleanup)", airportId, e.getMessage()); // Continue with cleanup even if one deletion fails } } diff --git a/src/test/java/org/couchbase/quickstart/springdata/controllers/RouteIntegrationTest.java b/src/test/java/org/couchbase/quickstart/springdata/controllers/RouteIntegrationTest.java index c18b0e8..cdd9fcb 100644 --- a/src/test/java/org/couchbase/quickstart/springdata/controllers/RouteIntegrationTest.java +++ b/src/test/java/org/couchbase/quickstart/springdata/controllers/RouteIntegrationTest.java @@ -49,7 +49,7 @@ private void deleteRoute(String baseUri, String routeId) { } catch (DocumentNotFoundException | DataRetrievalFailureException | ResourceAccessException e) { log.warn("Document " + routeId + " not present prior to test"); } catch (Exception e) { - log.error("Error deleting test data for route {}: {}", routeId, e.getMessage()); + log.debug("Cleanup: Could not delete test route {}: {} (this is expected during test cleanup)", routeId, e.getMessage()); // Continue with cleanup even if one deletion fails } } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..079dd21 --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,48 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file