From d673f0c4bacf77fbf37340512e4e7e9d7a6076f2 Mon Sep 17 00:00:00 2001 From: Jakob Frank Date: Tue, 16 Jul 2024 14:54:27 +0200 Subject: [PATCH 1/2] chore: streamline security-config & api-generation * fix deprecation-warnings in the security-config * consolidated api-generation * use Instant for date-time * add @RequestMapping to interfaces --- studymanager/pom.xml | 58 ++++++++--------- .../WebSecurityConfiguration.java | 65 ++++++++++++------- .../studymanager/CalendarApiV1Controller.java | 4 +- .../ConfigurationApiV1Controller.java | 22 +++++-- .../studymanager/DataApiV1Controller.java | 6 +- .../model/transformer/Transformers.java | 9 ++- .../studymanager/service/CalendarService.java | 5 +- .../service/DataProcessingService.java | 28 ++++---- .../studymanager/CalendarControllerTest.java | 16 ++--- .../InterventionControllerTest.java | 22 +++---- .../ObservationControllerTest.java | 24 ++++--- .../service/CalendarServiceTest.java | 13 ++-- 12 files changed, 153 insertions(+), 119 deletions(-) diff --git a/studymanager/pom.xml b/studymanager/pom.xml index 021a90bc..988386cf 100644 --- a/studymanager/pom.xml +++ b/studymanager/pom.xml @@ -235,15 +235,26 @@ generate - - true - + spring + spring-boot + ${project.basedir}/src/main/resources/openapi/StudyManagerAPI.yaml ${project.build.directory}/generated-sources/study-manager + + io.redlink.more.studymanager.api.v1 + true io.redlink.more.studymanager.api.v1.webservices + true io.redlink.more.studymanager.api.v1.model + DTO + + false + true + false + false + - + string+date-time=Instant string+time=LocalTime @@ -254,37 +265,20 @@ Instant=java.time.Instant LocalTime=java.time.LocalTime + + + true + src + source + true + true + false + true + api_interface + - - spring - spring-boot - - io.redlink.more.studymanager.api.v1 - - true - io.redlink.more.studymanager.api.v1.webservices - - true - io.redlink.more.studymanager.api.v1.model - DTO - - false - true - false - false - - - true - src - source - true - false - false - true - - diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/configuration/WebSecurityConfiguration.java b/studymanager/src/main/java/io/redlink/more/studymanager/configuration/WebSecurityConfiguration.java index 5aa7bc21..cdf54107 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/configuration/WebSecurityConfiguration.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/configuration/WebSecurityConfiguration.java @@ -11,19 +11,24 @@ import io.redlink.more.studymanager.properties.MoreAuthProperties; import io.redlink.more.studymanager.repository.UserRepository; import io.redlink.more.studymanager.service.OAuth2AuthenticationService; -import org.springframework.boot.context.properties.EnableConfigurationProperties; - import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.crypto.argon2.Argon2PasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.DelegatingPasswordEncoder; @@ -32,9 +37,6 @@ import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.core.oidc.OidcIdToken; @@ -50,6 +52,7 @@ import org.springframework.security.web.util.matcher.AndRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.IpAddressMatcher; +import org.springframework.security.web.util.matcher.NegatedRequestMatcher; @Configuration @EnableWebSecurity @@ -71,20 +74,24 @@ protected SecurityFilterChain filterChain(HttpSecurity http, OAuth2AuthorizedClientService oAuth2AuthorizedClientService, UserRepository userRepository) throws Exception { // Basics - http.csrf() + http.csrf(csrf -> csrf .ignoringRequestMatchers("/kibana/**") - .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); - http.cors().disable(); + .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) + ); + http.cors(AbstractHttpConfigurer::disable); // Restricted Paths - http.authorizeHttpRequests() - .requestMatchers("/api", "/api/v1/me").permitAll() + http.authorizeHttpRequests(auth -> auth + .requestMatchers(HttpMethod.GET, "/api", "/api/v1/me").permitAll() // Allow unauthenticated access to the ui-/auth-settings .requestMatchers(HttpMethod.GET, "/api/v1/config/ui").permitAll() + // Allow unauthenticated access to the build-info + .requestMatchers(HttpMethod.GET, "/api/v1/config/buildInfo").permitAll() //TODO specific handling of temporary sidecar .requestMatchers("/api/v1/components/observation/lime-survey-observation/end.html").permitAll() - .requestMatchers("/api/v1/studies/*/export/studydata/*").permitAll() - .requestMatchers("/api/v1/studies/*/calendar.ics").permitAll() + // Study-Data-Export is authenticated internally using individual access-tokens + .requestMatchers(HttpMethod.GET, "/api/v1/studies/*/export/studydata/*").permitAll() + .requestMatchers(HttpMethod.GET, "/api/v1/studies/*/calendar.ics").permitAll() .requestMatchers("/api/v1/**").authenticated() .requestMatchers("/kibana/**").authenticated() .requestMatchers("/login/init").authenticated() @@ -96,30 +103,44 @@ protected SecurityFilterChain filterChain(HttpSecurity http, ) ).permitAll() .requestMatchers("/error").authenticated() - .anyRequest().denyAll(); + .anyRequest().denyAll() + ); // API-Calls should not be redirected to the login page, but answered with a 401 - http.exceptionHandling() - .defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), new AntPathRequestMatcher("/api/**")); + http.exceptionHandling(exHandling -> exHandling + .defaultAuthenticationEntryPointFor( + new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), + new AndRequestMatcher( + new AntPathRequestMatcher("/api/**"), + new NegatedRequestMatcher( + new AntPathRequestMatcher("/api/v1/studies/*/export/studydata/*") + ) + ) + ) + ); // Logout Config - http.logout() + http.logout(logout -> logout .logoutSuccessHandler(oidcLogoutSuccessHandler()) - .logoutSuccessUrl("/"); + .logoutSuccessUrl("/") + ); // Enable OAuth2 - http.oauth2Login() + http.oauth2Login(oauth -> oauth // register oauth2-provider under this baseurl to simplify routing - .authorizationEndpoint().baseUri("/login/oauth").and() + .authorizationEndpoint(ep -> ep.baseUri("/login/oauth")) .authorizedClientService( new UserSyncingOAuth2AuthorizedClientService(oAuth2AuthorizedClientService, oAuth2AuthenticationService, userRepository) - ); + ) + ); // Enable OAuth2 client_credentials flow (insomnia) - http.oauth2ResourceServer().jwt(); + http.oauth2ResourceServer(oauth -> oauth.jwt(Customizer.withDefaults())); //TODO maybe disable in production - http.headers().frameOptions().disable(); + http.headers(headers -> headers + .frameOptions(HeadersConfigurer.FrameOptionsConfig::disable) + ); return http.build(); } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/CalendarApiV1Controller.java b/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/CalendarApiV1Controller.java index 308e6b70..31d1d4ff 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/CalendarApiV1Controller.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/CalendarApiV1Controller.java @@ -15,8 +15,8 @@ import io.redlink.more.studymanager.model.transformer.TimelineTransformer; import io.redlink.more.studymanager.properties.GatewayProperties; import io.redlink.more.studymanager.service.CalendarService; +import java.time.Instant; import java.time.LocalDate; -import java.time.OffsetDateTime; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -46,7 +46,7 @@ public ResponseEntity getStudyCalendar(Long studyId) { @Override @RequiresStudyRole({StudyRole.STUDY_ADMIN, StudyRole.STUDY_OPERATOR}) - public ResponseEntity getStudyTimeline(Long studyId, Integer participant, Integer studyGroup, OffsetDateTime referenceDate, LocalDate from, LocalDate to) { + public ResponseEntity getStudyTimeline(Long studyId, Integer participant, Integer studyGroup, Instant referenceDate, LocalDate from, LocalDate to) { return ResponseEntity.ok( TimelineTransformer.toStudyTimelineDTO( service.getTimeline(studyId, participant, studyGroup, referenceDate, from, to) diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/ConfigurationApiV1Controller.java b/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/ConfigurationApiV1Controller.java index 0b284133..64e1da35 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/ConfigurationApiV1Controller.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/ConfigurationApiV1Controller.java @@ -13,6 +13,7 @@ import io.redlink.more.studymanager.api.v1.model.KeycloakSettingsDTO; import io.redlink.more.studymanager.api.v1.webservices.ConfigurationApi; import io.redlink.more.studymanager.properties.FrontendConfigurationProperties; +import java.time.Instant; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -32,7 +33,14 @@ public ConfigurationApiV1Controller(FrontendConfigurationProperties uiConfig) { @Override public ResponseEntity getBuildInfo() { - return null; + return ResponseEntity.ok( + new BuildInfoDTO( + "null", + Instant.MIN + ) + .branch("undefined") + .rev("*dirty") + ); } @Override @@ -43,13 +51,13 @@ public ResponseEntity getFrontendConfig() { } private static FrontendConfigurationDTO transform(FrontendConfigurationProperties uiConfig) { - return new FrontendConfigurationDTO() + return new FrontendConfigurationDTO( + new KeycloakSettingsDTO( + uiConfig.keycloak().server(), + uiConfig.keycloak().realm(), + uiConfig.keycloak().clientId() + )) .title(uiConfig.title()) - .auth(new KeycloakSettingsDTO() - .server(uiConfig.keycloak().server()) - .realm(uiConfig.keycloak().realm()) - .clientId(uiConfig.keycloak().clientId()) - ) ; } } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/DataApiV1Controller.java b/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/DataApiV1Controller.java index b7b7b60d..b1d0dfc2 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/DataApiV1Controller.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/controller/studymanager/DataApiV1Controller.java @@ -17,7 +17,7 @@ import io.redlink.more.studymanager.model.StudyRole; import io.redlink.more.studymanager.model.transformer.StudyDataTransformer; import io.redlink.more.studymanager.service.DataProcessingService; -import java.time.OffsetDateTime; +import java.time.Instant; import java.util.Arrays; import java.util.List; import org.springframework.http.MediaType; @@ -36,7 +36,7 @@ public class DataApiV1Controller implements DataApi { @Override @RequiresStudyRole({StudyRole.STUDY_ADMIN, StudyRole.STUDY_VIEWER}) public ResponseEntity> getDataPoints( - Long studyId, Integer size, Integer observationId, Integer participantId, OffsetDateTime date + Long studyId, Integer size, Integer observationId, Integer participantId, Instant date ) { return ResponseEntity.ok().body( dataProcessingService.getDataPoints(studyId, size, observationId, participantId, date) @@ -55,7 +55,7 @@ public ResponseEntity> getParticipationData(Long stud @Override @RequiresStudyRole({StudyRole.STUDY_ADMIN, StudyRole.STUDY_VIEWER}) - public ResponseEntity getObservationViewData(Long studyId, Integer observationId, String viewName, Integer studyGroupId, Integer participantId, OffsetDateTime from, OffsetDateTime to) { + public ResponseEntity getObservationViewData(Long studyId, Integer observationId, String viewName, Integer studyGroupId, Integer participantId, Instant from, Instant to) { return ResponseEntity.ok().body( StudyDataTransformer.toObservationDataViewDataDTO( dataProcessingService.getDataView(studyId, observationId, viewName, studyGroupId, participantId, from, to) diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/Transformers.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/Transformers.java index bc2b7bff..02049026 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/Transformers.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/Transformers.java @@ -9,7 +9,6 @@ package io.redlink.more.studymanager.model.transformer; import java.time.Instant; -import java.time.OffsetDateTime; import java.time.ZoneId; import java.util.function.Function; @@ -23,12 +22,12 @@ public final class Transformers { private Transformers() { } - public static OffsetDateTime toOffsetDateTime(Instant instant) { - return transform(instant, i -> i.atZone(HOME).toOffsetDateTime()); + public static Instant toOffsetDateTime(Instant instant) { + return instant; } - public static Instant toInstant(OffsetDateTime offsetDateTime) { - return transform(offsetDateTime, OffsetDateTime::toInstant); + public static Instant toInstant(Instant offsetDateTime) { + return offsetDateTime; } /** diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/service/CalendarService.java b/studymanager/src/main/java/io/redlink/more/studymanager/service/CalendarService.java index 7c37151c..e621261a 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/service/CalendarService.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/service/CalendarService.java @@ -22,7 +22,6 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; -import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.util.List; @@ -49,7 +48,7 @@ public CalendarService(StudyService studyService, ObservationService observation this.participantService = participantService; } - public StudyTimeline getTimeline(Long studyId, Integer participantId, Integer studyGroupId, OffsetDateTime referenceDate, LocalDate from, LocalDate to) { + public StudyTimeline getTimeline(Long studyId, Integer participantId, Integer studyGroupId, Instant referenceDate, LocalDate from, LocalDate to) { final Study study = studyService.getStudy(studyId, null) .orElseThrow(() -> NotFoundException.Study(studyId)); final Range studyRange = Range.of( @@ -74,7 +73,7 @@ public StudyTimeline getTimeline(Long studyId, Integer participantId, Integer st */ final Instant participantStart; if (referenceDate != null) { - participantStart = referenceDate.toInstant(); + participantStart = referenceDate; } else if (participant != null && participant.getStart() != null) { participantStart = participant.getStart(); } else { diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/service/DataProcessingService.java b/studymanager/src/main/java/io/redlink/more/studymanager/service/DataProcessingService.java index aa9b1239..1645ed84 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/service/DataProcessingService.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/service/DataProcessingService.java @@ -16,13 +16,17 @@ import io.redlink.more.studymanager.model.Participant; import io.redlink.more.studymanager.model.StudyGroup; import io.redlink.more.studymanager.model.data.ParticipationData; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; - import java.io.IOException; -import java.time.OffsetDateTime; +import java.time.Instant; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; @Service public class DataProcessingService { @@ -119,16 +123,16 @@ public DataViewInfo[] listDataViews(Long studyId, Integer observationId) { return observationService.listDataViews(studyId, observationId); } - public DataView getDataView(Long studyId, Integer observationId, String viewName, Integer studyGroupId, Integer participantId, OffsetDateTime from, OffsetDateTime to) { + public DataView getDataView(Long studyId, Integer observationId, String viewName, Integer studyGroupId, Integer participantId, Instant from, Instant to) { if (participantId != null) { - return observationService.queryData(studyId, observationId, viewName, null, participantId, from != null && to != null ? new Timeframe(from.toInstant(), to.toInstant()) : null); + return observationService.queryData(studyId, observationId, viewName, null, participantId, from != null && to != null ? new Timeframe(from, to) : null); } else if (studyGroupId != null) { - return observationService.queryData(studyId, observationId, viewName, studyGroupId, null, from != null && to != null ? new Timeframe(from.toInstant(), to.toInstant()) : null); + return observationService.queryData(studyId, observationId, viewName, studyGroupId, null, from != null && to != null ? new Timeframe(from, to) : null); } - return observationService.queryData(studyId, observationId, viewName, studyGroupId, participantId, from != null && to != null ? new Timeframe(from.toInstant(), to.toInstant()) : null); + return observationService.queryData(studyId, observationId, viewName, studyGroupId, participantId, from != null && to != null ? new Timeframe(from, to) : null); } - public List getDataPoints(Long studyId, Integer size, Integer observationId, Integer participantId, OffsetDateTime date) { + public List getDataPoints(Long studyId, Integer size, Integer observationId, Integer participantId, Instant date) { try { return elasticService.listDataPoints(studyId, participantId, observationId, toIsoString(date), size).stream() .map(dp -> new DataPointDTO() @@ -145,8 +149,8 @@ public List getDataPoints(Long studyId, Integer size, Integer obse } } - private String toIsoString(OffsetDateTime date) { - return date != null ? date.format(DateTimeFormatter.ISO_INSTANT) : null; + private String toIsoString(Instant date) { + return date != null ? DateTimeFormatter.ISO_INSTANT.format(date) : null; } @Cacheable("participants") diff --git a/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/CalendarControllerTest.java b/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/CalendarControllerTest.java index 0908610c..fdcd3b7e 100644 --- a/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/CalendarControllerTest.java +++ b/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/CalendarControllerTest.java @@ -10,6 +10,13 @@ import io.redlink.more.studymanager.model.timeline.StudyTimeline; import io.redlink.more.studymanager.service.CalendarService; import io.redlink.more.studymanager.service.OAuth2AuthenticationService; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; import org.apache.commons.lang3.Range; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -21,13 +28,6 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import java.time.Instant; -import java.time.LocalDate; -import java.time.OffsetDateTime; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.util.*; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -69,7 +69,7 @@ void testGetStudyTimeline() throws Exception { LocalDate from = LocalDate.of(2024, 2, 1); LocalDate to = LocalDate.of(2024, 5, 1); - when(service.getTimeline(any(), any(), any(), any(OffsetDateTime.class), any(LocalDate.class), any(LocalDate.class))) + when(service.getTimeline(any(), any(), any(), any(Instant.class), any(LocalDate.class), any(LocalDate.class))) .thenAnswer(invocationOnMock -> { return new StudyTimeline( referenceDate, diff --git a/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/InterventionControllerTest.java b/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/InterventionControllerTest.java index 0be3b95c..13754225 100644 --- a/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/InterventionControllerTest.java +++ b/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/InterventionControllerTest.java @@ -16,14 +16,17 @@ import io.redlink.more.studymanager.core.properties.TriggerProperties; import io.redlink.more.studymanager.model.Action; import io.redlink.more.studymanager.model.AuthenticatedUser; -import io.redlink.more.studymanager.model.scheduler.Event; import io.redlink.more.studymanager.model.Intervention; import io.redlink.more.studymanager.model.PlatformRole; import io.redlink.more.studymanager.model.Trigger; +import io.redlink.more.studymanager.model.scheduler.Event; import io.redlink.more.studymanager.service.InterventionService; import io.redlink.more.studymanager.service.OAuth2AuthenticationService; import io.redlink.more.studymanager.utils.MapperUtils; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.EnumSet; +import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -36,17 +39,14 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import java.time.Instant; -import java.time.ZoneOffset; -import java.time.temporal.ChronoUnit; -import java.util.Map; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest({InterventionsApiV1Controller.class}) @AutoConfigureMockMvc(addFilters = false) @@ -102,8 +102,8 @@ void testAddIntervention() throws Exception { .purpose("some purpose") .studyGroupId(1) .schedule(new EventDTO() - .dtstart(dateStart.atOffset(ZoneOffset.UTC)) - .dtend(dateEnd.atOffset(ZoneOffset.UTC))); + .dtstart(dateStart) + .dtend(dateEnd)); mvc.perform(post("/api/v1/studies/1/interventions") .content(mapper.writeValueAsString(interventionRequest)) @@ -142,8 +142,8 @@ void testUpdateIntervention() throws Exception { .purpose("some purpose") .title("a title") .schedule(new EventDTO() - .dtstart(dateStart.atOffset(ZoneOffset.UTC)) - .dtend(dateEnd.atOffset(ZoneOffset.UTC))); + .dtstart(dateStart) + .dtend(dateEnd)); mvc.perform(put("/api/v1/studies/1/interventions/1") .content(mapper.writeValueAsString(interventionRequest)) diff --git a/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/ObservationControllerTest.java b/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/ObservationControllerTest.java index a1b91d5d..925a6cf6 100644 --- a/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/ObservationControllerTest.java +++ b/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/ObservationControllerTest.java @@ -12,13 +12,21 @@ import io.redlink.more.studymanager.api.v1.model.EndpointTokenDTO; import io.redlink.more.studymanager.api.v1.model.ObservationDTO; import io.redlink.more.studymanager.api.v1.model.ObservationScheduleDTO; -import io.redlink.more.studymanager.model.*; +import io.redlink.more.studymanager.model.AuthenticatedUser; +import io.redlink.more.studymanager.model.EndpointToken; +import io.redlink.more.studymanager.model.Observation; +import io.redlink.more.studymanager.model.PlatformRole; import io.redlink.more.studymanager.model.scheduler.Event; import io.redlink.more.studymanager.service.IntegrationService; import io.redlink.more.studymanager.service.OAuth2AuthenticationService; import io.redlink.more.studymanager.service.ObservationService; import io.redlink.more.studymanager.utils.MapperUtils; -import java.time.OffsetDateTime; +import java.time.Instant; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -29,14 +37,14 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import java.time.Instant; -import java.util.*; - -import static org.mockito.ArgumentMatchers.*; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -168,7 +176,7 @@ void testAddToken() throws Exception{ EndpointTokenDTO token = new EndpointTokenDTO( 1, "testLabel", - OffsetDateTime.now(), + Instant.now(), "test"); when(integrationService.addToken(anyLong(), anyInt(), anyString())) .thenAnswer(invocationOnMock -> Optional.of(new EndpointToken( diff --git a/studymanager/src/test/java/io/redlink/more/studymanager/service/CalendarServiceTest.java b/studymanager/src/test/java/io/redlink/more/studymanager/service/CalendarServiceTest.java index 49119379..4762d820 100644 --- a/studymanager/src/test/java/io/redlink/more/studymanager/service/CalendarServiceTest.java +++ b/studymanager/src/test/java/io/redlink/more/studymanager/service/CalendarServiceTest.java @@ -14,9 +14,10 @@ import io.redlink.more.studymanager.model.scheduler.RelativeEvent; import io.redlink.more.studymanager.model.scheduler.RelativeRecurrenceRule; import io.redlink.more.studymanager.model.timeline.StudyTimeline; +import java.time.Instant; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; -import java.time.OffsetDateTime; import java.time.ZoneId; import java.util.List; import java.util.Optional; @@ -52,7 +53,7 @@ class CalendarServiceTest { @Test void testStudyNotFound() { when(studyService.getStudy(any(), any())).thenReturn(Optional.empty()); - assertThrows(NotFoundException.class, () -> calendarService.getTimeline(1L, 1, 1, OffsetDateTime.now(), LocalDate.now(), LocalDate.now())); + assertThrows(NotFoundException.class, () -> calendarService.getTimeline(1L, 1, 1, Instant.now(), LocalDate.now(), LocalDate.now())); } @Test @@ -65,7 +66,7 @@ void testParticipantNotFound() { .setPlannedStartDate(LocalDate.now()) .setPlannedEndDate(LocalDate.now().plusDays(3)) )); - assertThrows(NotFoundException.class, () -> calendarService.getTimeline(1L, 1,1, OffsetDateTime.now(), LocalDate.now(), LocalDate.now())); + assertThrows(NotFoundException.class, () -> calendarService.getTimeline(1L, 1,1, Instant.now(), LocalDate.now(), LocalDate.now())); } @Test @@ -176,10 +177,10 @@ void testGetTimeline() { 1L, 1, 2, - OffsetDateTime.of( + LocalDateTime.of( LocalDate.of(2024, 5, 11), - LocalTime.of(10,10,10), - OffsetDateTime.now().getOffset()), + LocalTime.of(10,10,10) + ).atZone(ZoneId.systemDefault()).toInstant(), LocalDate.of(2024, 5, 9), LocalDate.of(2024,5,17) ); From a88d3806f0f32a0da762d63c25ddc125616011ac Mon Sep 17 00:00:00 2001 From: Jakob Frank Date: Tue, 16 Jul 2024 14:57:02 +0200 Subject: [PATCH 2/2] chore: remove unnecessary transformation --- .../model/transformer/ActionTransformer.java | 7 ++- .../transformer/EndpointTokenTransformer.java | 9 ++-- .../model/transformer/EventTransformer.java | 43 ++++++++++++++----- .../transformer/InterventionTransformer.java | 7 ++- .../transformer/ObservationTransformer.java | 7 ++- .../transformer/ParticipantTransformer.java | 12 ++++-- .../transformer/StudyDataTransformer.java | 11 +++-- .../transformer/StudyGroupTransformer.java | 7 ++- .../model/transformer/StudyTransformer.java | 9 ++-- .../transformer/TimelineTransformer.java | 10 ++--- .../model/transformer/Transformers.java | 12 ------ .../model/transformer/TriggerTransformer.java | 7 ++- .../transformer/UserInfoTransformer.java | 2 +- .../studymanager/CalendarControllerTest.java | 2 +- 14 files changed, 91 insertions(+), 54 deletions(-) diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ActionTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ActionTransformer.java index e8996162..b9f7f265 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ActionTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ActionTransformer.java @@ -12,6 +12,7 @@ import io.redlink.more.studymanager.core.properties.ActionProperties; import io.redlink.more.studymanager.model.Action; import io.redlink.more.studymanager.utils.MapperUtils; +import java.time.Instant; public final class ActionTransformer { @@ -26,12 +27,14 @@ public static Action fromActionDTO_V1(ActionDTO dto) { } public static ActionDTO toActionDTO_V1(Action action) { + Instant instant = action.getModified(); + Instant instant1 = action.getCreated(); return new ActionDTO() .actionId(action.getActionId()) .type(action.getType()) .properties(action.getProperties()) - .created(Transformers.toOffsetDateTime(action.getCreated())) - .modified(Transformers.toOffsetDateTime(action.getModified())); + .created(instant1) + .modified(instant); } } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/EndpointTokenTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/EndpointTokenTransformer.java index fd5a79d4..14b0aa54 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/EndpointTokenTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/EndpointTokenTransformer.java @@ -10,20 +10,21 @@ import io.redlink.more.studymanager.api.v1.model.EndpointTokenDTO; import io.redlink.more.studymanager.model.EndpointToken; - +import java.time.Instant; import java.util.Collection; import java.util.List; import java.util.Objects; -public class EndpointTokenTransformer { +public final class EndpointTokenTransformer { private EndpointTokenTransformer() {} public static EndpointToken fromEndpointTokenDTO(EndpointTokenDTO dto) { + Instant offsetDateTime = dto.getCreated(); return new EndpointToken( dto.getTokenId(), dto.getTokenLabel(), - Transformers.toInstant(dto.getCreated()), + offsetDateTime, dto.getToken() ); } @@ -42,7 +43,7 @@ public static EndpointTokenDTO toEndpointTokenDTO(EndpointToken token) { return new EndpointTokenDTO() .tokenId(token.tokenId()) .tokenLabel(token.tokenLabel()) - .created(Transformers.toOffsetDateTime(token.created())) + .created(token.created()) .token(token.token()); } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/EventTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/EventTransformer.java index e653a0b3..f7246864 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/EventTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/EventTransformer.java @@ -8,8 +8,23 @@ */ package io.redlink.more.studymanager.model.transformer; -import io.redlink.more.studymanager.api.v1.model.*; -import io.redlink.more.studymanager.model.scheduler.*; +import io.redlink.more.studymanager.api.v1.model.DurationDTO; +import io.redlink.more.studymanager.api.v1.model.EventDTO; +import io.redlink.more.studymanager.api.v1.model.FrequencyDTO; +import io.redlink.more.studymanager.api.v1.model.ObservationScheduleDTO; +import io.redlink.more.studymanager.api.v1.model.RecurrenceRuleDTO; +import io.redlink.more.studymanager.api.v1.model.RelativeDateDTO; +import io.redlink.more.studymanager.api.v1.model.RelativeEventDTO; +import io.redlink.more.studymanager.api.v1.model.RelativeRecurrenceRuleDTO; +import io.redlink.more.studymanager.api.v1.model.WeekdayDTO; +import io.redlink.more.studymanager.model.scheduler.Duration; +import io.redlink.more.studymanager.model.scheduler.Event; +import io.redlink.more.studymanager.model.scheduler.RecurrenceRule; +import io.redlink.more.studymanager.model.scheduler.RelativeDate; +import io.redlink.more.studymanager.model.scheduler.RelativeEvent; +import io.redlink.more.studymanager.model.scheduler.RelativeRecurrenceRule; +import io.redlink.more.studymanager.model.scheduler.ScheduleEvent; +import java.time.Instant; public final class EventTransformer { @@ -20,9 +35,11 @@ public static ScheduleEvent fromObservationScheduleDTO_V1(ObservationScheduleDTO if (genericDto != null) { if(genericDto.getType() == null || Event.TYPE.equals(genericDto.getType())) { EventDTO dto = (EventDTO) genericDto; + Instant offsetDateTime = dto.getDtend(); + Instant offsetDateTime1 = dto.getDtstart(); return new Event() - .setDateStart(Transformers.toInstant(dto.getDtstart())) - .setDateEnd(Transformers.toInstant(dto.getDtend())) + .setDateStart(offsetDateTime1) + .setDateEnd(offsetDateTime) .setRRule(fromRecurrenceRuleDTO(dto.getRrule())); } else if(RelativeEvent.TYPE.equals(genericDto.getType())) { RelativeEventDTO dto = (RelativeEventDTO) genericDto; @@ -46,10 +63,12 @@ public static ObservationScheduleDTO toObservationScheduleDTO_V1(ScheduleEvent e if (event != null) if(event.getType() == null || Event.TYPE.equals(event.getType())) { Event e = (Event) event; + Instant instant = e.getDateEnd(); + Instant instant1 = e.getDateStart(); return new EventDTO() .type(Event.TYPE) - .dtstart(Transformers.toOffsetDateTime(e.getDateStart())) - .dtend(Transformers.toOffsetDateTime(e.getDateEnd())) + .dtstart(instant1) + .dtend(instant) .rrule(toRecurrenceRuleDTO(e.getRRule())); } else if(RelativeEvent.TYPE.equals(event.getType())) { RelativeEvent e = (RelativeEvent) event; @@ -69,30 +88,34 @@ public static ObservationScheduleDTO toObservationScheduleDTO_V1(ScheduleEvent e } private static RecurrenceRule fromRecurrenceRuleDTO(RecurrenceRuleDTO dto) { - if (dto != null) + if (dto != null) { + Instant offsetDateTime = dto.getUntil(); return new RecurrenceRule() .setFreq(dto.getFreq().getValue()) .setInterval(dto.getInterval()) .setCount(dto.getCount()) - .setUntil(Transformers.toInstant(dto.getUntil())) + .setUntil(offsetDateTime) .setByDay(dto.getByday() != null ? dto.getByday().stream().map(WeekdayDTO::getValue).toList() : null) .setByMonth(dto.getBymonth()) .setByMonthDay(dto.getBymonthday()) .setBySetPos(dto.getBysetpos()); + } else return null; } private static RecurrenceRuleDTO toRecurrenceRuleDTO(RecurrenceRule recurrenceRule) { - if (recurrenceRule != null) + if (recurrenceRule != null) { + Instant instant = recurrenceRule.getUntil(); return new RecurrenceRuleDTO() .freq(recurrenceRule.getFreq() != null ? FrequencyDTO.fromValue(recurrenceRule.getFreq()) : null) .interval(recurrenceRule.getInterval()) .count(recurrenceRule.getCount()) - .until(Transformers.toOffsetDateTime(recurrenceRule.getUntil())) + .until(instant) .byday(recurrenceRule.getByDay() != null ? recurrenceRule.getByDay().stream().map(WeekdayDTO::fromValue).toList() : null) .bymonth(recurrenceRule.getByMonth()) .bymonthday(recurrenceRule.getByMonthDay()) .bysetpos(recurrenceRule.getBySetPos()); + } else return null; } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/InterventionTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/InterventionTransformer.java index ef1e726f..7595dfb7 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/InterventionTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/InterventionTransformer.java @@ -10,6 +10,7 @@ import io.redlink.more.studymanager.api.v1.model.InterventionDTO; import io.redlink.more.studymanager.model.Intervention; +import java.time.Instant; public final class InterventionTransformer { @@ -27,6 +28,8 @@ public static Intervention fromInterventionDTO_V1(InterventionDTO dto) { } public static InterventionDTO toInterventionDTO_V1(Intervention intervention) { + Instant instant = intervention.getModified(); + Instant instant1 = intervention.getCreated(); return new InterventionDTO() .studyId(intervention.getStudyId()) .interventionId(intervention.getInterventionId()) @@ -34,8 +37,8 @@ public static InterventionDTO toInterventionDTO_V1(Intervention intervention) { .purpose(intervention.getPurpose()) .studyGroupId(intervention.getStudyGroupId()) .schedule(EventTransformer.toObservationScheduleDTO_V1(intervention.getSchedule())) - .created(Transformers.toOffsetDateTime(intervention.getCreated())) - .modified(Transformers.toOffsetDateTime(intervention.getModified())); + .created(instant1) + .modified(instant); } } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ObservationTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ObservationTransformer.java index 077ac44f..56baf62a 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ObservationTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ObservationTransformer.java @@ -12,6 +12,7 @@ import io.redlink.more.studymanager.core.properties.ObservationProperties; import io.redlink.more.studymanager.model.Observation; import io.redlink.more.studymanager.utils.MapperUtils; +import java.time.Instant; public final class ObservationTransformer { @@ -34,6 +35,8 @@ public static Observation fromObservationDTO_V1(ObservationDTO dto) { } public static ObservationDTO toObservationDTO_V1(Observation observation) { + Instant instant = observation.getModified(); + Instant instant1 = observation.getCreated(); return new ObservationDTO() .studyId(observation.getStudyId()) .observationId(observation.getObservationId()) @@ -44,8 +47,8 @@ public static ObservationDTO toObservationDTO_V1(Observation observation) { .studyGroupId(observation.getStudyGroupId()) .properties(observation.getProperties()) .schedule(EventTransformer.toObservationScheduleDTO_V1(observation.getSchedule())) - .created(Transformers.toOffsetDateTime(observation.getCreated())) - .modified(Transformers.toOffsetDateTime(observation.getModified())) + .created(instant1) + .modified(instant) .hidden(observation.getHidden()) .noSchedule(observation.getNoSchedule()); } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ParticipantTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ParticipantTransformer.java index 098774e0..751940e7 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ParticipantTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/ParticipantTransformer.java @@ -11,8 +11,9 @@ import io.redlink.more.studymanager.api.v1.model.ParticipantDTO; import io.redlink.more.studymanager.api.v1.model.ParticipantStatusDTO; import io.redlink.more.studymanager.model.Participant; +import java.time.Instant; -public class ParticipantTransformer { +public final class ParticipantTransformer { private ParticipantTransformer() { @@ -27,6 +28,9 @@ public static Participant fromParticipantDTO_V1(ParticipantDTO participantDTO) { } public static ParticipantDTO toParticipantDTO_V1(Participant participant) { + Instant instant = participant.getCreated(); + Instant instant1 = participant.getModified(); + Instant instant2 = participant.getStart(); return new ParticipantDTO() .studyId(participant.getStudyId()) .participantId(participant.getParticipantId()) @@ -34,9 +38,9 @@ public static ParticipantDTO toParticipantDTO_V1(Participant participant) { .studyGroupId(participant.getStudyGroupId()) .registrationToken(participant.getRegistrationToken()) .status(ParticipantStatusDTO.fromValue(participant.getStatus().getValue())) - .start(Transformers.toOffsetDateTime(participant.getStart())) - .modified(Transformers.toOffsetDateTime(participant.getModified())) - .created(Transformers.toOffsetDateTime(participant.getCreated())); + .start(instant2) + .modified(instant1) + .created(instant); } } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyDataTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyDataTransformer.java index d0693399..e6b654f2 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyDataTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyDataTransformer.java @@ -8,16 +8,19 @@ */ package io.redlink.more.studymanager.model.transformer; -import io.redlink.more.studymanager.api.v1.model.*; +import io.redlink.more.studymanager.api.v1.model.IdTitleDTO; +import io.redlink.more.studymanager.api.v1.model.ObservationDataViewDTO; +import io.redlink.more.studymanager.api.v1.model.ObservationDataViewDataDTO; +import io.redlink.more.studymanager.api.v1.model.ObservationDataViewDataRowDTO; +import io.redlink.more.studymanager.api.v1.model.ParticipationDataDTO; import io.redlink.more.studymanager.core.ui.DataView; import io.redlink.more.studymanager.core.ui.DataViewInfo; import io.redlink.more.studymanager.core.ui.DataViewRow; import io.redlink.more.studymanager.model.data.ParticipationData; - import java.util.List; import java.util.stream.Collectors; -public class StudyDataTransformer { +public final class StudyDataTransformer { private StudyDataTransformer(){} @@ -28,7 +31,7 @@ public static ParticipationDataDTO toParticipationDataDTO_V1(ParticipationData p .participantNamedId(toIdTitleDTO_V1(participationData.participantNamedId())) .studyGroupNamedId(toIdTitleDTO_V1(participationData.studyGroupNamedId())) .dataReceived(participationData.dataReceived()) - .lastDataReceived(Transformers.toOffsetDateTime(participationData.lastDataReceived())); + .lastDataReceived(participationData.lastDataReceived()); } public static IdTitleDTO toIdTitleDTO_V1(ParticipationData.NamedId idTitle){ if(idTitle == null) diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyGroupTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyGroupTransformer.java index 7ad8a436..0ab946d4 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyGroupTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyGroupTransformer.java @@ -11,6 +11,7 @@ import io.redlink.more.studymanager.api.v1.model.StudyGroupDTO; import io.redlink.more.studymanager.model.StudyGroup; import io.redlink.more.studymanager.model.scheduler.Duration; +import java.time.Instant; public final class StudyGroupTransformer { @@ -27,13 +28,15 @@ public static StudyGroup fromStudyGroupDTO_V1(StudyGroupDTO studyGroupDTO) { } public static StudyGroupDTO toStudyGroupDTO_V1(StudyGroup studyGroup) { + Instant instant = studyGroup.getModified(); + Instant instant1 = studyGroup.getCreated(); return new StudyGroupDTO() .studyId(studyGroup.getStudyId()) .studyGroupId(studyGroup.getStudyGroupId()) .title(studyGroup.getTitle()) .purpose(studyGroup.getPurpose()) .duration(Duration.toStudyDurationDTO(studyGroup.getDuration())) - .created(Transformers.toOffsetDateTime(studyGroup.getCreated())) - .modified(Transformers.toOffsetDateTime(studyGroup.getModified())); + .created(instant1) + .modified(instant); } } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyTransformer.java index 24ac7edd..6afb87bf 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/StudyTransformer.java @@ -15,8 +15,9 @@ import io.redlink.more.studymanager.model.Contact; import io.redlink.more.studymanager.model.Study; import io.redlink.more.studymanager.model.scheduler.Duration; +import java.time.Instant; -public class StudyTransformer { +public final class StudyTransformer { private StudyTransformer() {} @@ -41,6 +42,8 @@ public static Study fromStudyDTO_V1(StudyDTO studyDTO) { public static StudyDTO toStudyDTO_V1(Study study) { if(study.getContact() == null) study.setContact(new Contact()); + Instant instant = study.getModified(); + Instant instant1 = study.getCreated(); return new StudyDTO() .studyId(study.getStudyId()) .title(study.getTitle()) @@ -54,8 +57,8 @@ public static StudyDTO toStudyDTO_V1(Study study) { .end(study.getEndDate()) .plannedStart(study.getPlannedStartDate()) .plannedEnd(study.getPlannedEndDate()) - .created(Transformers.toOffsetDateTime(study.getCreated())) - .modified(Transformers.toOffsetDateTime(study.getModified())) + .created(instant1) + .modified(instant) .userRoles(RoleTransformer.toStudyRolesDTO(study.getUserRoles())) .contact(ContactTransformer.toContactDTO_V1(study.getContact())); } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/TimelineTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/TimelineTransformer.java index f63ad8f4..9aa090d5 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/TimelineTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/TimelineTransformer.java @@ -18,12 +18,12 @@ import io.redlink.more.studymanager.model.timeline.StudyTimeline; -public class TimelineTransformer { +public final class TimelineTransformer { private TimelineTransformer() {} public static StudyTimelineDTO toStudyTimelineDTO(StudyTimeline studyTimeline) { return new StudyTimelineDTO() - .participantSignup(Transformers.toOffsetDateTime(studyTimeline.signup())) + .participantSignup(studyTimeline.signup()) .studyDuration( new StudyTimelineStudyDurationDTO() .from(studyTimeline.participationRange().getMinimum()) @@ -44,8 +44,8 @@ public static ObservationTimelineEventDTO toObservationTimelineDTO(ObservationTi .title(observationTimelineEvent.title()) .purpose(observationTimelineEvent.purpose()) .type(observationTimelineEvent.type()) - .start(Transformers.toOffsetDateTime(observationTimelineEvent.start())) - .end(Transformers.toOffsetDateTime(observationTimelineEvent.end())) + .start(observationTimelineEvent.start()) + .end(observationTimelineEvent.end()) .hidden(observationTimelineEvent.hidden()) .scheduleType(observationTimelineEvent.scheduleType()); } @@ -56,7 +56,7 @@ public static InterventionTimelineEventDTO toInterventionTimelineEventDTO(Interv .studyGroupId(interventionTimelineEvent.studyGroupId()) .title(interventionTimelineEvent.title()) .purpose(interventionTimelineEvent.purpose()) - .start(Transformers.toOffsetDateTime(interventionTimelineEvent.start())) + .start(interventionTimelineEvent.start()) .scheduleType(interventionTimelineEvent.scheduleType()); } } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/Transformers.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/Transformers.java index 02049026..454b2e92 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/Transformers.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/Transformers.java @@ -8,8 +8,6 @@ */ package io.redlink.more.studymanager.model.transformer; -import java.time.Instant; -import java.time.ZoneId; import java.util.function.Function; /** @@ -17,19 +15,9 @@ */ public final class Transformers { - private static final ZoneId HOME = ZoneId.of("Europe/Vienna"); - private Transformers() { } - public static Instant toOffsetDateTime(Instant instant) { - return instant; - } - - public static Instant toInstant(Instant offsetDateTime) { - return offsetDateTime; - } - /** * Performs a null-safe conversion of {@code t} using the {@code transformer}. * @param t the value to transform. diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/TriggerTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/TriggerTransformer.java index df6e7e22..9e0f771c 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/TriggerTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/TriggerTransformer.java @@ -12,6 +12,7 @@ import io.redlink.more.studymanager.core.properties.TriggerProperties; import io.redlink.more.studymanager.model.Trigger; import io.redlink.more.studymanager.utils.MapperUtils; +import java.time.Instant; public final class TriggerTransformer { @@ -25,10 +26,12 @@ public static Trigger fromTriggerDTO_V1(TriggerDTO dto) { } public static TriggerDTO toTriggerDTO_V1(Trigger trigger) { + Instant instant = trigger.getModified(); + Instant instant1 = trigger.getCreated(); return new TriggerDTO() .type(trigger.getType()) .properties(trigger.getProperties()) - .created(Transformers.toOffsetDateTime(trigger.getCreated())) - .modified(Transformers.toOffsetDateTime(trigger.getModified())); + .created(instant1) + .modified(instant); } } diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/UserInfoTransformer.java b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/UserInfoTransformer.java index 406bb459..a177885b 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/UserInfoTransformer.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/model/transformer/UserInfoTransformer.java @@ -81,7 +81,7 @@ private static CollaboratorRoleDetailsDTO toCollaboratorRoleDetailsDTO(StudyUser return new CollaboratorRoleDetailsDTO() .role(RoleTransformer.toStudyRoleDTO(role.role())) .assignedBy(toUserInfoDTO(role.creator())) - .assignedAt(Transformers.toOffsetDateTime(role.created())) + .assignedAt(role.created()) ; } diff --git a/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/CalendarControllerTest.java b/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/CalendarControllerTest.java index fdcd3b7e..1945e85d 100644 --- a/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/CalendarControllerTest.java +++ b/studymanager/src/test/java/io/redlink/more/studymanager/controller/studymanager/CalendarControllerTest.java @@ -73,7 +73,7 @@ void testGetStudyTimeline() throws Exception { .thenAnswer(invocationOnMock -> { return new StudyTimeline( referenceDate, - Range.between(from, to, LocalDate::compareTo), + Range.of(from, to, LocalDate::compareTo), List.of( ObservationTimelineEvent.fromObservation( new Observation()