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'
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'
}
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;
}
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<PreferencesDto, String> {
+public interface PreferencesRepository extends JpaRepository<PreferencesDto, String> {
}
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<Preferences> getPreferences(String userId){
- return repository
+ return Mono.just(repository
.findById(userId)
- .switchIfEmpty(defaultPreferences())
+ .orElse(defaultPreferences()))
.map(this::toPreferences);
}
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);
private Preferences toPreferences(PreferencesDto preferencesDto) {
var preferences = new Preferences();
preferences.setProperties(preferencesDto.getProperties());
- return preferences;
+ return preferences;
}
/**
* b) for security reasons
* @return PreferencesDto
*/
- private Mono<PreferencesDto> defaultPreferences() {
+ private PreferencesDto defaultPreferences() {
var preferencesDto = new PreferencesDto();
- preferencesDto.setProperties("");
- return Mono.just(preferencesDto);
+ preferencesDto.setProperties(null);
+ return preferencesDto;
}
}
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
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}
traceIdHeaderName: "X-Request-Id"
enabled: true
excludePaths:
- - "/actuator/**"
\ No newline at end of file
+ - "/actuator/**"
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<databaseChangeLog
+ xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
+ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
+ http://www.liquibase.org/xml/ns/dbchangelog-ext
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
+
+ <include file="changelog/v001_create_schema.xml" relativeToChangelogFile="true"/>
+</databaseChangeLog>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<databaseChangeLog
+ xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
+ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
+ http://www.liquibase.org/xml/ns/dbchangelog-ext
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
+
+ <changeSet id="1" author="benzelleroehr" dbms="postgresql">
+ <createTable tableName="preferences">
+ <column name="user_id" type="text">
+ <constraints primaryKey="true"/>
+ </column>
+ <column name="properties" type="jsonb"> </column>
+ </createTable>
+ </changeSet>
+</databaseChangeLog>
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();
assertThat(actualResponse).isNotNull();
assertThat(actualResponse.getProperties()).isEqualTo(expectedResponse.getProperties());
}
-
+
@Test
void thatUserPreferencesCanNotBeRetrieved() {
unauthenticatedRequestSpecification()
.as(Preferences.class);
assertThat(actualResponse).isNotNull();
- assertThat(actualResponse.getProperties()).isEqualTo("");
+ assertThat(actualResponse.getProperties()).isNull();
}
@Test
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
traceIdHeaderName: "X-Request-Id"
enabled: true
excludePaths:
- - "/actuator/**"
\ No newline at end of file
+ - "/actuator/**"