From: benzelleroehr Date: Thu, 13 Feb 2025 15:20:29 +0000 (+0100) Subject: migrate from mongodb to postgresql X-Git-Tag: 0.2.0^0 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F19%2F140219%2F7;p=portal-ng%2Fpreferences.git migrate from mongodb to postgresql - add liquibase for schema definition - add testcontainers - remove embedMongo Change-Id: Ie56c8312011ead0d50d4b67d9b31d49a42526d8a Issue-ID: PORTALNG-133 Signed-off-by: benzelleroehr --- diff --git a/app/build.gradle b/app/build.gradle index 6b91426..9df2f3f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,27 +45,30 @@ repositories { ext { problemVersion = '0.27.1' logstashLogbackVersion = '7.2' - embedMongoVersion = '4.7.0' - embedMongoIntegrationVersion = '4.7.0' springCloudWiremockVersion = '4.0.3' - micrometerVersion = '1.0.0' + micrometerVersion = '1.0.0' + liquibaseCoreVersion = '4.31.0' } dependencies { implementation project(':openapi') implementation 'org.springframework.boot:spring-boot-starter-actuator' - implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive' implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-webflux' implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation "org.zalando:problem:$problemVersion" implementation "net.logstash.logback:logstash-logback-encoder:$logstashLogbackVersion" + implementation "org.liquibase:liquibase-core:$liquibaseCoreVersion" + implementation 'org.postgresql:postgresql' + implementation 'io.micrometer:micrometer-tracing' implementation 'io.micrometer:micrometer-tracing-bridge-otel' implementation 'io.opentelemetry:opentelemetry-exporter-zipkin' implementation 'io.micrometer:micrometer-registry-prometheus' + implementation 'org.apache.commons:commons-lang3:3.15.0' compileOnly 'org.projectlombok:lombok' @@ -78,8 +81,7 @@ dependencies { testImplementation 'io.projectreactor:reactor-test' testImplementation 'io.rest-assured:rest-assured' testImplementation "org.springframework.cloud:spring-cloud-contract-wiremock:$springCloudWiremockVersion" - testImplementation "de.flapdoodle.embed:de.flapdoodle.embed.mongo:$embedMongoVersion" - testImplementation "de.flapdoodle.embed:de.flapdoodle.embed.mongo.spring30x:$embedMongoIntegrationVersion" + testImplementation "org.testcontainers:postgresql" testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' } diff --git a/app/src/main/java/org/onap/portalng/preferences/entities/PreferencesDto.java b/app/src/main/java/org/onap/portalng/preferences/entities/PreferencesDto.java index a86c229..390a720 100644 --- a/app/src/main/java/org/onap/portalng/preferences/entities/PreferencesDto.java +++ b/app/src/main/java/org/onap/portalng/preferences/entities/PreferencesDto.java @@ -23,17 +23,28 @@ package org.onap.portalng.preferences.entities; import lombok.Getter; import lombok.Setter; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Document; -@Document +import java.util.Map; + +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +import com.fasterxml.jackson.databind.JsonNode; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity @Getter @Setter +@Table(name = "preferences") public class PreferencesDto { @Id private String userId; - private Object properties; + @JdbcTypeCode(SqlTypes.JSON) + private JsonNode properties; } diff --git a/app/src/main/java/org/onap/portalng/preferences/repository/PreferencesRepository.java b/app/src/main/java/org/onap/portalng/preferences/repository/PreferencesRepository.java index 264cdf5..537ee7e 100644 --- a/app/src/main/java/org/onap/portalng/preferences/repository/PreferencesRepository.java +++ b/app/src/main/java/org/onap/portalng/preferences/repository/PreferencesRepository.java @@ -22,7 +22,7 @@ package org.onap.portalng.preferences.repository; import org.onap.portalng.preferences.entities.PreferencesDto; -import org.springframework.data.mongodb.repository.ReactiveMongoRepository; +import org.springframework.data.jpa.repository.JpaRepository; -public interface PreferencesRepository extends ReactiveMongoRepository { +public interface PreferencesRepository extends JpaRepository { } diff --git a/app/src/main/java/org/onap/portalng/preferences/services/PreferencesService.java b/app/src/main/java/org/onap/portalng/preferences/services/PreferencesService.java index 4e7dfb3..df2ad1b 100644 --- a/app/src/main/java/org/onap/portalng/preferences/services/PreferencesService.java +++ b/app/src/main/java/org/onap/portalng/preferences/services/PreferencesService.java @@ -29,18 +29,23 @@ import org.onap.portalng.preferences.util.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.RequiredArgsConstructor; import reactor.core.publisher.Mono; +@RequiredArgsConstructor @Service public class PreferencesService { - @Autowired - private PreferencesRepository repository; + private final PreferencesRepository repository; + + private final ObjectMapper objectMapper; public Mono getPreferences(String userId){ - return repository + return Mono.just(repository .findById(userId) - .switchIfEmpty(defaultPreferences()) + .orElse(defaultPreferences())) .map(this::toPreferences); } @@ -48,11 +53,10 @@ public class PreferencesService { var preferencesDto = new PreferencesDto(); preferencesDto.setUserId(userId); - preferencesDto.setProperties(preferences.getProperties()); + preferencesDto.setProperties(objectMapper.valueToTree(preferences.getProperties())); - return repository - .save(preferencesDto) - .map(this::toPreferences) + return Mono.just(repository.save(preferencesDto)) + .map(this::toPreferences) .onErrorResume(ProblemException.class, ex -> { Logger.errorLog(xRequestId,"user prefrences", userId, "preferences" ); return Mono.error(ex); @@ -63,7 +67,7 @@ public class PreferencesService { private Preferences toPreferences(PreferencesDto preferencesDto) { var preferences = new Preferences(); preferences.setProperties(preferencesDto.getProperties()); - return preferences; + return preferences; } /** @@ -72,9 +76,9 @@ public class PreferencesService { * b) for security reasons * @return PreferencesDto */ - private Mono defaultPreferences() { + private PreferencesDto defaultPreferences() { var preferencesDto = new PreferencesDto(); - preferencesDto.setProperties(""); - return Mono.just(preferencesDto); + preferencesDto.setProperties(null); + return preferencesDto; } } diff --git a/app/src/main/resources/application-local.yml b/app/src/main/resources/application-local.yml index 5d7376c..d5a196a 100644 --- a/app/src/main/resources/application-local.yml +++ b/app/src/main/resources/application-local.yml @@ -12,13 +12,12 @@ spring: resourceserver: jwt: jwk-set-uri: http://localhost:8080/realms/ONAP/protocol/openid-connect/certs #Keycloak Endpoint - data: - mongodb: - database: portal_preferences - host: localhost - port: 27017 - username: root - password: password + datasource: + url: jdbc:postgresql://localhost:5441/preferences + username: postgres + password: postgres + jpa: + show-sql: true preferences: realm: ONAP diff --git a/app/src/main/resources/application.yml b/app/src/main/resources/application.yml index 85156b1..e4688c0 100644 --- a/app/src/main/resources/application.yml +++ b/app/src/main/resources/application.yml @@ -14,13 +14,24 @@ spring: resourceserver: jwt: jwk-set-uri: ${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/certs #Keycloak Endpoint - data: - mongodb: - database: ${MONGO_DATABASE} - host: ${MONGO_HOST} - port: ${MONGO_PORT} - username: ${MONGO_USERNAME} - password: ${MONGO_PASSWORD} + datasource: + url: jdbc:postgresql://${PREFERENCES_DB_HOST}:${PREFERENCES_DB_PORT}/${PREFERENCES_DB} + username: ${PREFERENCES_DB_USERNAME} + password: ${PREFERENCES_DB_PASSWORD} + jpa: + database: postgresql + properties: + hibernate: + session: + events: + log: + LOG_QUERIES_SLOWER_THAN_MS: 100 + jdbc: + lob: + non_contextual_creation: true + dialect: org.hibernate.dialect.PostgreSQLDialect + liquibase: + change-log: "classpath:/db/changelog.xml" preferences: realm: ${KEYCLOAK_REALM} @@ -50,4 +61,4 @@ logger: traceIdHeaderName: "X-Request-Id" enabled: true excludePaths: - - "/actuator/**" \ No newline at end of file + - "/actuator/**" diff --git a/app/src/main/resources/db/changelog.xml b/app/src/main/resources/db/changelog.xml new file mode 100644 index 0000000..bdb8c10 --- /dev/null +++ b/app/src/main/resources/db/changelog.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/resources/db/changelog/v001_create_schema.xml b/app/src/main/resources/db/changelog/v001_create_schema.xml new file mode 100644 index 0000000..3f568c4 --- /dev/null +++ b/app/src/main/resources/db/changelog/v001_create_schema.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + diff --git a/app/src/test/java/org/onap/portalng/preferences/preferences/PreferencesControllerIntegrationTest.java b/app/src/test/java/org/onap/portalng/preferences/preferences/PreferencesControllerIntegrationTest.java index 6eb1148..f446a9a 100644 --- a/app/src/test/java/org/onap/portalng/preferences/preferences/PreferencesControllerIntegrationTest.java +++ b/app/src/test/java/org/onap/portalng/preferences/preferences/PreferencesControllerIntegrationTest.java @@ -45,11 +45,7 @@ class PreferencesControllerIntegrationTest extends BaseIntegrationTest { void thatUserPreferencesCanBeRetrieved() { // First save a user preference before a GET can run Preferences expectedResponse = new Preferences() - .properties("{\n" + - " \"properties\": { \"appStarter\": \"value1\",\n" + - " \"dashboard\": {\"key1:\" : \"value2\"}\n" + - " } \n" + - "}"); + .properties("{\"properties\": {\"dashboard\": {\"key1:\": \"value2\"}, \"appStarter\": \"value1\"}}"); preferencesService .savePreferences(X_REQUEST_ID,"test-user", expectedResponse) .block(); @@ -69,7 +65,7 @@ class PreferencesControllerIntegrationTest extends BaseIntegrationTest { assertThat(actualResponse).isNotNull(); assertThat(actualResponse.getProperties()).isEqualTo(expectedResponse.getProperties()); } - + @Test void thatUserPreferencesCanNotBeRetrieved() { unauthenticatedRequestSpecification() @@ -162,7 +158,7 @@ class PreferencesControllerIntegrationTest extends BaseIntegrationTest { .as(Preferences.class); assertThat(actualResponse).isNotNull(); - assertThat(actualResponse.getProperties()).isEqualTo(""); + assertThat(actualResponse.getProperties()).isNull(); } @Test diff --git a/app/src/test/resources/application.yml b/app/src/test/resources/application.yml index 499b8e4..2eecc93 100644 --- a/app/src/test/resources/application.yml +++ b/app/src/test/resources/application.yml @@ -18,6 +18,25 @@ spring: resourceserver: jwt: jwk-set-uri: http://localhost:${wiremock.server.port}/realms/ONAP/protocol/openid-connect/certs #Keycloak Endpoint + datasource: + url: jdbc:tc:postgresql:16:///preferences + username: postgres + password: postgres + jpa: + show-sql: true + database: postgresql + properties: + hibernate: + session: + events: + log: + LOG_QUERIES_SLOWER_THAN_MS: 100 + jdbc: + lob: + non_contextual_creation: true + dialect: org.hibernate.dialect.PostgreSQLDialect + liquibase: + change-log: "classpath:/db/changelog.xml" preferences: realm: ONAP @@ -41,4 +60,4 @@ logger: traceIdHeaderName: "X-Request-Id" enabled: true excludePaths: - - "/actuator/**" \ No newline at end of file + - "/actuator/**"