diff --git a/Dockerfile b/Dockerfile index da1039863..3a0664b8b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,8 @@ RUN cp ../target/karnak*.jar application.jar RUN java -Djarmode=layertools -jar application.jar extract # Build the final deployment image -FROM eclipse-temurin:17-jre-jammy +#FROM eclipse-temurin:17-jre-jammy +FROM eclipse-temurin:17-jdk-jammy WORKDIR app COPY --from=builder /app/bin/dependencies/ ./ diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 000000000..d36e59347 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + +
+ + diff --git a/frontend/styles/shared-styles.css b/frontend/styles/shared-styles.css index a36eb7b95..6151b9919 100644 --- a/frontend/styles/shared-styles.css +++ b/frontend/styles/shared-styles.css @@ -58,7 +58,7 @@ label[disabled] { } .menu-link { - margin: 0 auto; + margin: 0 -5%; padding: 10px 37px; } diff --git a/frontend/themes/common-theme/main-layout.css b/frontend/themes/common-theme/main-layout.css new file mode 100644 index 000000000..7a544838e --- /dev/null +++ b/frontend/themes/common-theme/main-layout.css @@ -0,0 +1,233 @@ + +.stroked-button { + border: 1px solid currentColor; +} + +.message-box { + width: 100%; +} + +.message-box-layout { + border-style: solid; + border-width: 1px; + padding: 0px; +} + +.message-box-layout-with-margin { + margin: 0px 16px 0px 16px; +} + +.message-box-layout.info { + border-color: #2196F3; +} + +.message-box-layout.warn { + border-color: #ff9800; +} + +.message-box-layout.error { + border-color: #F44336; +} + +.message-box-title { + color: #ffffff; + margin-left: 16px; + margin-top: 0px; + margin-right: 0px; + margin-bottom: 0px; + padding: 0.8rem; + box-shadow: 0 1px 4px 0 rgba(0, 0, 0, .2); +} + +.message-box-title.info { + background-color: #2196F3; +} + +.message-box-title.warn { + background-color: #ff9800; +} + +.message-box-title.error { + background-color: #F44336; +} + +.message-box-content { + color: #2f4f4f; + background-color: #ffffff; + width: 100%; + margin: 0px; + padding: 12px; +} + + + +/**/ +/**/ +/**/ +/**/ diff --git a/frontend/themes/common-theme/styles.css b/frontend/themes/common-theme/styles.css new file mode 100644 index 000000000..dcf1f1874 --- /dev/null +++ b/frontend/themes/common-theme/styles.css @@ -0,0 +1 @@ +@import url('./main-layout.css'); \ No newline at end of file diff --git a/frontend/themes/common-theme/theme.json b/frontend/themes/common-theme/theme.json new file mode 100644 index 000000000..d8c6397e4 --- /dev/null +++ b/frontend/themes/common-theme/theme.json @@ -0,0 +1,3 @@ +{ + "lumoImports": ["badge"] +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index cafc9211d..cccb200fa 100644 --- a/pom.xml +++ b/pom.xml @@ -28,15 +28,13 @@ [${java.version},) [3.2.0,) 17 - 2.6.6 - 3.0.0 - 1.6.2 - 21.0.9 + 3.1.6 + 24.2.3 5.29.0.2 4.6.0-dcm 1.6.12 - 4.2.0 - 1.4.200 + 5.2.0 + 2.2.224 0.8.7 5.8.2 https://sonarcloud.io @@ -45,10 +43,9 @@ osirix-foundation-1 karnak target/site/jacoco/jacoco.xml - 20220924 - 1.2.9 - 4.3.5 - 5.5.2 + 20230227 + 4.20.0 + 5.7.1 @@ -342,11 +339,9 @@ org.springframework.boot spring-boot-starter-data-redis - - cache-api - javax.cache - 1.1.1 + org.springframework.boot + spring-boot-starter-actuator @@ -391,11 +386,6 @@ org.weasis ${weasis-dicom-tools.version} - - javax.mail - com.sun.mail - ${javax.mail.version} - @@ -439,11 +429,6 @@ hibernate-validator org.hibernate.validator - - javax.el - org.glassfish - ${javax.el.version} - @@ -452,6 +437,18 @@ runtime + + org.apache.httpcomponents + httpclient + 4.5.14 + + + + com.google.guava + guava + 32.1.3-jre + + vaadin @@ -490,46 +487,15 @@ - - iron-icons - com.flowingcode.addons - 2.0.1 - - - multiselect-combo-box-flow - org.vaadin.gatanaso - 3.0.2 - - - - vaadin-checkbox-flow - com.vaadin - ${vaadin.version} - togglebutton com.vaadin.componentfactory - 1.0.1 + 3.0.0 org.vaadin.klaudeta grid-pagination - 2.0.10 - - - - validation-api - javax.validation - - - - jul-to-slf4j - org.slf4j - - - logback-classic - ch.qos.logback - ${logback.version} + 4.0.0 @@ -545,6 +511,10 @@ jackson-module-jaxb-annotations com.fasterxml.jackson.module + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + jackson-dataformat-xml @@ -604,12 +574,6 @@ pom ${springframework.version} - - javax.servlet-api - javax.servlet - provided - 3.1.0 - vaadin-bom com.vaadin diff --git a/src/main/java/org/karnak/StartApplication.java b/src/main/java/org/karnak/KarnakApplication.java similarity index 59% rename from src/main/java/org/karnak/StartApplication.java rename to src/main/java/org/karnak/KarnakApplication.java index 9cb49ac9d..7f8e4f22c 100644 --- a/src/main/java/org/karnak/StartApplication.java +++ b/src/main/java/org/karnak/KarnakApplication.java @@ -32,33 +32,32 @@ @EnableVaadin(value = "org.karnak") @EnableScheduling @EnableAsync -public class StartApplication implements CommandLineRunner { +public class KarnakApplication implements CommandLineRunner { - private static final Logger log = LoggerFactory.getLogger(StartApplication.class); + @Autowired(required = false) + private AppConfig myConfig; - @Autowired(required = false) - private AppConfig myConfig; + private static final Logger log = LoggerFactory.getLogger(KarnakApplication.class); - public static void main(String[] args) { - SpringApplicationBuilder application = new SpringApplicationBuilder(StartApplication.class); + public static void main(String[] args) { + SpringApplicationBuilder application = new SpringApplicationBuilder(KarnakApplication.class); - // If environment variable IDP exists and has value "oidc": activate the profile - // application-oidc.yml - if (System.getenv().containsKey(EnvironmentVariable.IDP.getCode()) - && Objects.equals( - System.getenv().get(EnvironmentVariable.IDP.getCode()), - ApplicationProfile.OIDC.getCode())) { - application.profiles(ApplicationProfile.OIDC.getCode()); - } + // If environment variable IDP exists and has value "oidc": activate the profile + // application-oidc.yml + if (System.getenv().containsKey(EnvironmentVariable.IDP.getCode()) && Objects + .equals(System.getenv().get(EnvironmentVariable.IDP.getCode()), ApplicationProfile.OIDC.getCode())) { + application.profiles(ApplicationProfile.OIDC.getCode()); + } - // Run application - application.run(args); - } + // Run application + application.run(args); + } + + @Override + public void run(String... args) { + log.info("StartApplication"); + log.info("using environment: " + (myConfig != null ? myConfig.getEnvironment() : "")); + log.info("name: " + (myConfig != null ? myConfig.getName() : "")); + } - @Override - public void run(String... args) { - log.info("StartApplication..."); - log.info("using environment: " + (myConfig != null ? myConfig.getEnvironment() : "")); - log.info("name: " + (myConfig != null ? myConfig.getName() : "")); - } } diff --git a/src/main/java/org/karnak/backend/api/EchoServlet.java b/src/main/java/org/karnak/backend/api/EchoServlet.java index 2de282a2c..398da3a39 100644 --- a/src/main/java/org/karnak/backend/api/EchoServlet.java +++ b/src/main/java/org/karnak/backend/api/EchoServlet.java @@ -9,16 +9,16 @@ */ package org.karnak.backend.api; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.io.Serial; import java.util.List; import java.util.Optional; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.karnak.backend.dicom.DicomForwardDestination; import org.karnak.backend.dicom.ForwardDestination; import org.karnak.backend.dicom.ForwardDicomNode; diff --git a/src/main/java/org/karnak/backend/cache/RequestCache.java b/src/main/java/org/karnak/backend/cache/RequestCache.java index 76a3c5100..c943df03d 100644 --- a/src/main/java/org/karnak/backend/cache/RequestCache.java +++ b/src/main/java/org/karnak/backend/cache/RequestCache.java @@ -11,8 +11,8 @@ import com.vaadin.flow.server.VaadinServletRequest; import com.vaadin.flow.server.VaadinServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.karnak.backend.util.SecurityUtil; import org.springframework.security.web.savedrequest.DefaultSavedRequest; import org.springframework.security.web.savedrequest.HttpSessionRequestCache; diff --git a/src/main/java/org/karnak/backend/config/AppConfig.java b/src/main/java/org/karnak/backend/config/AppConfig.java index 144f9bef9..0c535edf4 100644 --- a/src/main/java/org/karnak/backend/config/AppConfig.java +++ b/src/main/java/org/karnak/backend/config/AppConfig.java @@ -9,10 +9,9 @@ */ package org.karnak.backend.config; +import jakarta.annotation.PostConstruct; import java.io.InputStream; import java.net.URL; -import javax.annotation.PostConstruct; -import org.apache.commons.lang3.RandomStringUtils; import org.karnak.backend.cache.ExternalIDCache; import org.karnak.backend.cache.MainzellisteCache; import org.karnak.backend.cache.PatientClient; @@ -50,7 +49,7 @@ public class AppConfig { private String karnakpassword; private final ProfileRepo profileRepo; private final ProfilePipeService profilePipeService; - private String nameInstance; + private final ExternalIDCache externalIDCache; private final MainzellisteCache mainzellisteCache; @@ -69,7 +68,6 @@ public AppConfig( @PostConstruct public void postConstruct() { instance = this; - nameInstance = RandomStringUtils.randomAlphabetic(5); } public static AppConfig getInstance() { @@ -143,7 +141,4 @@ public StandardDICOM getStandardDICOM() { return new StandardDICOM(); } - public String getNameInstance() { - return nameInstance; - } } diff --git a/src/main/java/org/karnak/backend/config/DcmProfileConfig.java b/src/main/java/org/karnak/backend/config/DcmProfileConfig.java index 735306864..5cf69b30d 100644 --- a/src/main/java/org/karnak/backend/config/DcmProfileConfig.java +++ b/src/main/java/org/karnak/backend/config/DcmProfileConfig.java @@ -9,7 +9,7 @@ */ package org.karnak.backend.config; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/karnak/backend/config/GatewayConfig.java b/src/main/java/org/karnak/backend/config/GatewayConfig.java index bf08179c8..b4e5d2470 100644 --- a/src/main/java/org/karnak/backend/config/GatewayConfig.java +++ b/src/main/java/org/karnak/backend/config/GatewayConfig.java @@ -9,9 +9,9 @@ */ package org.karnak.backend.config; +import jakarta.annotation.PostConstruct; import java.util.HashSet; import java.util.Set; -import javax.annotation.PostConstruct; import org.karnak.backend.data.entity.SOPClassUIDEntity; import org.karnak.backend.data.repo.SOPClassUIDRepo; import org.karnak.backend.model.dicominnolitics.StandardSOPS; diff --git a/src/main/java/org/karnak/backend/config/MainzellisteConfig.java b/src/main/java/org/karnak/backend/config/MainzellisteConfig.java index f937b1bb8..e51981d87 100644 --- a/src/main/java/org/karnak/backend/config/MainzellisteConfig.java +++ b/src/main/java/org/karnak/backend/config/MainzellisteConfig.java @@ -9,7 +9,7 @@ */ package org.karnak.backend.config; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.stereotype.Component; diff --git a/src/main/java/org/karnak/backend/config/SecurityInMemoryConfig.java b/src/main/java/org/karnak/backend/config/SecurityInMemoryConfig.java index 5d0b7627c..2d8c17ce5 100644 --- a/src/main/java/org/karnak/backend/config/SecurityInMemoryConfig.java +++ b/src/main/java/org/karnak/backend/config/SecurityInMemoryConfig.java @@ -10,105 +10,109 @@ package org.karnak.backend.config; import org.karnak.backend.cache.RequestCache; +import org.karnak.backend.constant.EndPoint; import org.karnak.backend.enums.SecurityRole; import org.karnak.backend.security.DefaultIdpLoadCondition; import org.karnak.backend.util.SecurityUtil; +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.boot.actuate.context.ShutdownEndpoint; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.info.InfoEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @EnableWebSecurity @Configuration @Conditional(value = DefaultIdpLoadCondition.class) -public class SecurityInMemoryConfig extends WebSecurityConfigurerAdapter { +public class SecurityInMemoryConfig { private static final String LOGIN_FAILURE_URL = "/login?error"; private static final String LOGIN_URL = "/login"; - @Override - protected void configure(HttpSecurity http) throws Exception { - + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http - // Uses RequestCache to track unauthorized requests so that users are redirected - // appropriately after login - .requestCache() - .requestCache(new RequestCache()) - // Disables cross-site request forgery (CSRF) protection for main route and login - .and() - .csrf() - .ignoringAntMatchers("/", LOGIN_URL) - // Turns on authorization - .and() - .authorizeRequests() + // Disables cross-site request forgery (CSRF) protection for main route + .csrf(csrf -> csrf.ignoringRequestMatchers(AntPathRequestMatcher.antMatcher(EndPoint.ALL_REMAINING_PATH))) + // Turns on/off authorizations + .authorizeHttpRequests(authorize -> authorize + // Actuator, health, info + .requestMatchers(AntPathRequestMatcher.antMatcher("/actuator/**")) + .permitAll() + .requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class)) + .permitAll() // Allows all internal traffic from the Vaadin framework .requestMatchers(SecurityUtil::isFrameworkInternalRequest) .permitAll() - // Allow get echo endpoint - .antMatchers(HttpMethod.GET, "/api/echo/destinations") + // Allow endpoints + .requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/echo/destinations")) .permitAll() + // Deny + .requestMatchers(EndpointRequest.to(ShutdownEndpoint.class)) + .denyAll() // Allows all authenticated traffic - .antMatchers("/*") + // Allow admin role + .requestMatchers(AntPathRequestMatcher.antMatcher("/*")) .hasRole(SecurityRole.ADMIN_ROLE.getType()) .anyRequest() - .authenticated() + .authenticated()) // Enables form-based login and permits unauthenticated access to it - .and() - .formLogin() // Configures the login page URLs - .loginPage(LOGIN_URL) + .formLogin(formLogin -> formLogin.loginPage(LOGIN_URL) .permitAll() .loginProcessingUrl(LOGIN_URL) - .failureUrl(LOGIN_FAILURE_URL) + .failureUrl(LOGIN_FAILURE_URL)) // Configures the logout URL - .and() - .logout() - .logoutSuccessUrl(LOGIN_URL) - .and() - .exceptionHandling() - .accessDeniedPage(LOGIN_URL); + .logout(logout -> logout.logoutSuccessUrl(LOGIN_URL)) + .exceptionHandling(exceptionHandling -> exceptionHandling.accessDeniedPage(LOGIN_URL)); + + return http.build(); } - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { + // Access to static resources, bypassing Spring security. + return web -> web.ignoring() + .requestMatchers(AntPathRequestMatcher.antMatcher("/VAADIN/**"), + AntPathRequestMatcher.antMatcher("/img/**"), AntPathRequestMatcher.antMatcher("/icons/**"), + AntPathRequestMatcher.antMatcher("/sw.js"), AntPathRequestMatcher.antMatcher("/favicon.ico"), + AntPathRequestMatcher.antMatcher("/manifest.webmanifest"), + AntPathRequestMatcher.antMatcher("/offline.html"), + AntPathRequestMatcher.antMatcher("/sw-runtime-resources-precache.js")); + } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) + throws Exception { + return authenticationConfiguration.getAuthenticationManager(); + } + + @Bean + public UserDetailsService userDetailsService() { // Configure users and roles in memory - auth.inMemoryAuthentication() - .withUser(AppConfig.getInstance().getKarnakadmin()) + UserDetails userDetails = User.builder() + .username(AppConfig.getInstance().getKarnakadmin()) .password("{noop}" + AppConfig.getInstance().getKarnakpassword()) .roles( SecurityRole.ADMIN_ROLE.getType(), SecurityRole.INVESTIGATOR_ROLE.getType(), - SecurityRole.USER_ROLE.getType()); - } - - @Override - public void configure(WebSecurity web) { - // Access to static resources, bypassing Spring security. - web.ignoring() - .antMatchers( - "/VAADIN/**", - // the standard favicon URI - "/favicon.ico", - // web application manifest - "/manifest.webmanifest", - "/sw.js", - "/offline.html", - "/sw-runtime-resources-precache.js", - // icons and images - "/icons/logo**", - "/img/karnak.png"); - } + SecurityRole.USER_ROLE.getType()) + .build(); - @Bean - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); + return new InMemoryUserDetailsManager(userDetails); } @Bean diff --git a/src/main/java/org/karnak/backend/config/SecurityOpenIdConnectConfig.java b/src/main/java/org/karnak/backend/config/SecurityOpenIdConnectConfig.java index d155170f4..61cda2b6a 100644 --- a/src/main/java/org/karnak/backend/config/SecurityOpenIdConnectConfig.java +++ b/src/main/java/org/karnak/backend/config/SecurityOpenIdConnectConfig.java @@ -9,77 +9,70 @@ */ package org.karnak.backend.config; -import org.karnak.backend.cache.RequestCache; +import org.karnak.backend.constant.EndPoint; import org.karnak.backend.security.OpenIdConnectLogoutHandler; import org.karnak.backend.util.SecurityUtil; +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.boot.actuate.context.ShutdownEndpoint; +import org.springframework.boot.actuate.health.HealthEndpoint; +import org.springframework.boot.actuate.info.InfoEndpoint; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @EnableWebSecurity @Configuration @ConditionalOnProperty(value = "IDP", havingValue = "oidc") -public class SecurityOpenIdConnectConfig extends WebSecurityConfigurerAdapter { +public class SecurityOpenIdConnectConfig { - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http - // Uses RequestCache to track unauthorized requests so that users are redirected - // appropriately after login - .requestCache() - .requestCache(new RequestCache()) // Disables cross-site request forgery (CSRF) protection for main route - .and() - .csrf() - .ignoringAntMatchers("/") - // Turns on authorization - .and() - .authorizeRequests() - // Allows all internal traffic from the Vaadin framework - .requestMatchers(SecurityUtil::isFrameworkInternalRequest) - .permitAll() - // Allow get echo endpoint - .antMatchers(HttpMethod.GET, "/api/echo/destinations") - .permitAll() - // Allows all authenticated traffic - // .antMatchers("/*").hasAuthority(SecurityRole.ADMIN_ROLE.getType()) - .anyRequest() - .authenticated() + .csrf(csrf -> csrf.ignoringRequestMatchers(AntPathRequestMatcher.antMatcher(EndPoint.ALL_REMAINING_PATH))) + // Turns on/off authorizations + .authorizeHttpRequests(authorize -> authorize + // Actuator, health, info + .requestMatchers(AntPathRequestMatcher.antMatcher("/actuator/**")) + .permitAll() + .requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class)) + .permitAll() + // Allows all internal traffic from the Vaadin framework + .requestMatchers(SecurityUtil::isFrameworkInternalRequest) + .permitAll() + // Allow endpoints + .requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/echo/destinations")) + .permitAll() + // Deny + .requestMatchers(EndpointRequest.to(ShutdownEndpoint.class)) + .denyAll() + // Allows all authenticated traffic + .anyRequest() + .authenticated()) // OpenId connect login - .and() - .oauth2Login() + .oauth2Login(Customizer.withDefaults()) // Handle logout - .and() - .logout() - .addLogoutHandler(new OpenIdConnectLogoutHandler()); + .logout(logout -> logout.addLogoutHandler(new OpenIdConnectLogoutHandler())); + + return http.build(); } - @Override - public void configure(WebSecurity web) { + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { // Access to static resources, bypassing Spring security. - web.ignoring() - .antMatchers( - "/VAADIN/**", - // the standard favicon URI - "/favicon.ico", - // web application manifest - "/manifest.webmanifest", - "/sw.js", - "/offline.html", - "/sw-runtime-resources-precache.js", - // icons and images - "/icons/logo**", - "/img/karnak.png" // , - // "/img/**" // , - // "/images/**", - // "/styles/**", - // the robots exclusion standard - // "/robots.txt", - // (development mode) H2 debugging console - /* "/h2-console/**" */ ); + return (web) -> web.ignoring() + .requestMatchers(AntPathRequestMatcher.antMatcher("/VAADIN/**"), + AntPathRequestMatcher.antMatcher("/img/**"), AntPathRequestMatcher.antMatcher("/icons/**"), + AntPathRequestMatcher.antMatcher("/sw.js"), AntPathRequestMatcher.antMatcher("/favicon.ico"), + AntPathRequestMatcher.antMatcher("/manifest.webmanifest"), + AntPathRequestMatcher.antMatcher("/offline.html"), + AntPathRequestMatcher.antMatcher("/sw-runtime-resources-precache.js")); } } diff --git a/src/main/java/org/karnak/backend/constant/EndPoint.java b/src/main/java/org/karnak/backend/constant/EndPoint.java index da82d8e3b..d2e253fc3 100644 --- a/src/main/java/org/karnak/backend/constant/EndPoint.java +++ b/src/main/java/org/karnak/backend/constant/EndPoint.java @@ -25,4 +25,6 @@ public class EndPoint { // public static final String AET_PARAM = "aet"; // public static final String SOP_UID_PARAM = "sopUid"; + public static final String ALL_REMAINING_PATH = "/**"; + } diff --git a/src/main/java/org/karnak/backend/data/converter/ArgumentToMapConverter.java b/src/main/java/org/karnak/backend/data/converter/ArgumentToMapConverter.java index baf645478..16a4859d4 100644 --- a/src/main/java/org/karnak/backend/data/converter/ArgumentToMapConverter.java +++ b/src/main/java/org/karnak/backend/data/converter/ArgumentToMapConverter.java @@ -23,7 +23,7 @@ public Map convert(List argumentEntities) { Map argumentMap = new HashMap<>(); argumentEntities.forEach( argument -> { - argumentMap.put(argument.getKey(), argument.getValue()); + argumentMap.put(argument.getArgumentKey(), argument.getArgumentValue()); }); return argumentMap; } diff --git a/src/main/java/org/karnak/backend/data/converter/RectangleListConverter.java b/src/main/java/org/karnak/backend/data/converter/RectangleListConverter.java index 5ee9c3ab0..ea7c5affa 100644 --- a/src/main/java/org/karnak/backend/data/converter/RectangleListConverter.java +++ b/src/main/java/org/karnak/backend/data/converter/RectangleListConverter.java @@ -9,12 +9,12 @@ */ package org.karnak.backend.data.converter; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; import java.awt.Rectangle; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import javax.persistence.AttributeConverter; -import javax.persistence.Converter; @Converter public class RectangleListConverter implements AttributeConverter, String> { diff --git a/src/main/java/org/karnak/backend/data/entity/ArgumentEntity.java b/src/main/java/org/karnak/backend/data/entity/ArgumentEntity.java index 837032ff6..90fa48760 100644 --- a/src/main/java/org/karnak/backend/data/entity/ArgumentEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/ArgumentEntity.java @@ -10,15 +10,15 @@ package org.karnak.backend.data.entity; import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import java.io.Serializable; import java.util.Objects; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; @Entity(name = "Arguments") @Table(name = "arguments") @@ -30,21 +30,21 @@ public class ArgumentEntity implements Serializable { private ProfileElementEntity profileElementEntity; - private String key; + private String argumentKey; - private String value; + private String argumentValue; public ArgumentEntity() { } - public ArgumentEntity(String key, String value) { - this.key = key; - this.value = value; + public ArgumentEntity(String argumentKey, String argumentValue) { + this.argumentKey = argumentKey; + this.argumentValue = argumentValue; } - public ArgumentEntity(String key, String value, ProfileElementEntity profileElementEntity) { - this.key = key; - this.value = value; + public ArgumentEntity(String argumentKey, String argumentValue, ProfileElementEntity profileElementEntity) { + this.argumentKey = argumentKey; + this.argumentValue = argumentValue; this.profileElementEntity = profileElementEntity; } @@ -59,20 +59,20 @@ public void setId(Long id) { this.id = id; } - public String getKey() { - return key; + public String getArgumentKey() { + return argumentKey; } - public void setKey(String key) { - this.key = key; + public void setArgumentKey(String key) { + this.argumentKey = key; } - public String getValue() { - return value; + public String getArgumentValue() { + return argumentValue; } - public void setValue(String value) { - this.value = value; + public void setArgumentValue(String value) { + this.argumentValue = value; } @ManyToOne() @@ -94,13 +94,12 @@ public boolean equals(Object o) { return false; } ArgumentEntity that = (ArgumentEntity) o; - return Objects.equals(id, that.id) - && Objects.equals(key, that.key) - && Objects.equals(value, that.value); + return Objects.equals(id, that.id) && Objects.equals(argumentKey, that.argumentKey) + && Objects.equals(argumentValue, that.argumentValue); } @Override public int hashCode() { - return Objects.hash(id, key, value); + return Objects.hash(id, argumentKey, argumentValue); } } diff --git a/src/main/java/org/karnak/backend/data/entity/DestinationEntity.java b/src/main/java/org/karnak/backend/data/entity/DestinationEntity.java index 0513b6479..264398595 100644 --- a/src/main/java/org/karnak/backend/data/entity/DestinationEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/DestinationEntity.java @@ -11,30 +11,30 @@ import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonSetter; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import java.io.Serializable; import java.time.LocalDateTime; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.hibernate.validator.group.GroupSequenceProvider; diff --git a/src/main/java/org/karnak/backend/data/entity/DicomSourceNodeEntity.java b/src/main/java/org/karnak/backend/data/entity/DicomSourceNodeEntity.java index 09d862a53..c888e71bd 100644 --- a/src/main/java/org/karnak/backend/data/entity/DicomSourceNodeEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/DicomSourceNodeEntity.java @@ -9,17 +9,17 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import java.io.Serializable; import java.util.Objects; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; @Entity(name = "DicomSourceNode") @Table(name = "dicom_source_node") diff --git a/src/main/java/org/karnak/backend/data/entity/ExcludedTagEntity.java b/src/main/java/org/karnak/backend/data/entity/ExcludedTagEntity.java index ab7fe7bd9..cc69a7c9c 100644 --- a/src/main/java/org/karnak/backend/data/entity/ExcludedTagEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/ExcludedTagEntity.java @@ -9,9 +9,9 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; import java.io.Serializable; -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; @Entity(name = "ExcludedTag") @DiscriminatorValue("ExcludedTag") diff --git a/src/main/java/org/karnak/backend/data/entity/ForwardNodeEntity.java b/src/main/java/org/karnak/backend/data/entity/ForwardNodeEntity.java index 639c03c1f..bc0f1649d 100644 --- a/src/main/java/org/karnak/backend/data/entity/ForwardNodeEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/ForwardNodeEntity.java @@ -9,20 +9,20 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import java.io.Serializable; import java.util.HashSet; import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; @Entity(name = "ForwardNode") @Table(name = "forward_node") diff --git a/src/main/java/org/karnak/backend/data/entity/IncludedTagEntity.java b/src/main/java/org/karnak/backend/data/entity/IncludedTagEntity.java index a48498e78..390f8c741 100644 --- a/src/main/java/org/karnak/backend/data/entity/IncludedTagEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/IncludedTagEntity.java @@ -9,9 +9,9 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; import java.io.Serializable; -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; @Entity(name = "IncludedTag") @DiscriminatorValue("IncludedTag") diff --git a/src/main/java/org/karnak/backend/data/entity/KheopsAlbumsEntity.java b/src/main/java/org/karnak/backend/data/entity/KheopsAlbumsEntity.java index 9470e337a..c849b643e 100644 --- a/src/main/java/org/karnak/backend/data/entity/KheopsAlbumsEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/KheopsAlbumsEntity.java @@ -9,15 +9,15 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import java.io.Serializable; import java.util.Objects; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; @Entity(name = "KheopsAlbums") @Table(name = "kheops_albums") diff --git a/src/main/java/org/karnak/backend/data/entity/MaskEntity.java b/src/main/java/org/karnak/backend/data/entity/MaskEntity.java index 5dd1e0dfe..9d6c984dd 100644 --- a/src/main/java/org/karnak/backend/data/entity/MaskEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/MaskEntity.java @@ -11,19 +11,19 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import java.awt.Rectangle; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.persistence.Convert; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; import org.karnak.backend.data.converter.RectangleListConverter; import org.karnak.backend.data.converter.RectangleListToStringListConverter; diff --git a/src/main/java/org/karnak/backend/data/entity/ProfileElementEntity.java b/src/main/java/org/karnak/backend/data/entity/ProfileElementEntity.java index 6e77926f9..521a342ee 100644 --- a/src/main/java/org/karnak/backend/data/entity/ProfileElementEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/ProfileElementEntity.java @@ -14,20 +14,20 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.karnak.backend.data.converter.ArgumentToMapConverter; diff --git a/src/main/java/org/karnak/backend/data/entity/ProfileEntity.java b/src/main/java/org/karnak/backend/data/entity/ProfileEntity.java index 63da0045d..db7ce41ee 100644 --- a/src/main/java/org/karnak/backend/data/entity/ProfileEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/ProfileEntity.java @@ -14,21 +14,21 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonSetter; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; import java.io.Serializable; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; diff --git a/src/main/java/org/karnak/backend/data/entity/ProjectEntity.java b/src/main/java/org/karnak/backend/data/entity/ProjectEntity.java index 94d9dc152..7fdd4d984 100644 --- a/src/main/java/org/karnak/backend/data/entity/ProjectEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/ProjectEntity.java @@ -9,19 +9,19 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.karnak.backend.model.profilepipe.HMAC; @@ -132,9 +132,7 @@ public void applyActiveSecret(SecretEntity secretEntity) { * @return Label built */ public static String buildLabelSecret(SecretEntity secretEntity) { - return "%s [created: %s]" - .formatted( - HMAC.showHexKey(HMAC.byteToHex(secretEntity.getKey())), + return "%s [created: %s]".formatted(HMAC.showHexKey(HMAC.byteToHex(secretEntity.getSecretKey())), DateFormat.format( secretEntity.getCreationDate(), DateFormat.FORMAT_DDMMYYYY_SLASH_HHMMSS_2POINTS)); } diff --git a/src/main/java/org/karnak/backend/data/entity/SOPClassUIDEntity.java b/src/main/java/org/karnak/backend/data/entity/SOPClassUIDEntity.java index f493099e6..f4e9efa4a 100644 --- a/src/main/java/org/karnak/backend/data/entity/SOPClassUIDEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/SOPClassUIDEntity.java @@ -9,13 +9,13 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import java.io.Serializable; import java.util.Objects; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; @Entity(name = "SOPClassUID") @Table(name = "sop_class_uid") diff --git a/src/main/java/org/karnak/backend/data/entity/SecretEntity.java b/src/main/java/org/karnak/backend/data/entity/SecretEntity.java index 79be59abd..8e8e6a761 100644 --- a/src/main/java/org/karnak/backend/data/entity/SecretEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/SecretEntity.java @@ -9,17 +9,17 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import java.io.Serializable; import java.time.LocalDateTime; import java.util.Arrays; import java.util.Objects; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; @Entity @Table(name = "secret") @@ -29,7 +29,7 @@ public class SecretEntity implements Serializable { private ProjectEntity projectEntity; - private byte[] key; + private byte[] secretKey; private LocalDateTime creationDate; @@ -38,14 +38,14 @@ public class SecretEntity implements Serializable { public SecretEntity() { } - public SecretEntity(byte[] key) { - this.key = key; + public SecretEntity(byte[] secretKey) { + this.secretKey = secretKey; this.creationDate = LocalDateTime.now(); } - public SecretEntity(ProjectEntity projectEntity, byte[] key) { + public SecretEntity(ProjectEntity projectEntity, byte[] secretKey) { this.projectEntity = projectEntity; - this.key = key; + this.secretKey = secretKey; this.creationDate = LocalDateTime.now(); } @@ -69,12 +69,12 @@ public void setProjectEntity(ProjectEntity projectEntity) { this.projectEntity = projectEntity; } - public byte[] getKey() { - return key; + public byte[] getSecretKey() { + return secretKey; } - public void setKey(byte[] key) { - this.key = key; + public void setSecretKey(byte[] key) { + this.secretKey = key; } public LocalDateTime getCreationDate() { @@ -105,14 +105,13 @@ public boolean equals(Object o) { return active == that.active && Objects.equals(id, that.id) && Objects.equals(projectEntity, that.projectEntity) - && Arrays.equals(key, that.key) - && Objects.equals(creationDate, that.creationDate); + && Arrays.equals(secretKey, that.secretKey) && Objects.equals(creationDate, that.creationDate); } @Override public int hashCode() { int result = Objects.hash(id, projectEntity, creationDate, active); - result = 31 * result + Arrays.hashCode(key); + result = 31 * result + Arrays.hashCode(secretKey); return result; } } diff --git a/src/main/java/org/karnak/backend/data/entity/TagEntity.java b/src/main/java/org/karnak/backend/data/entity/TagEntity.java index 1b6b7cd4a..fab3c3503 100644 --- a/src/main/java/org/karnak/backend/data/entity/TagEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/TagEntity.java @@ -9,18 +9,18 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.DiscriminatorColumn; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import java.io.Serializable; import java.util.Objects; -import javax.persistence.DiscriminatorColumn; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; import org.hibernate.annotations.DiscriminatorOptions; /*https://stackoverflow.com/questions/14810287/hibernate-inheritance-and-relationship-mapping-generics/14919535*/ diff --git a/src/main/java/org/karnak/backend/data/entity/TransferStatusEntity.java b/src/main/java/org/karnak/backend/data/entity/TransferStatusEntity.java index f7d0aa328..9f5071379 100644 --- a/src/main/java/org/karnak/backend/data/entity/TransferStatusEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/TransferStatusEntity.java @@ -11,19 +11,19 @@ import com.opencsv.bean.CsvDate; import com.opencsv.bean.CsvRecurse; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; import java.io.Serializable; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Objects; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; import org.dcm4che3.data.Attributes; import org.dcm4che3.data.Tag; import org.dcm4che3.img.util.DateTimeUtils; diff --git a/src/main/java/org/karnak/backend/data/entity/VersionEntity.java b/src/main/java/org/karnak/backend/data/entity/VersionEntity.java index 9b8442eff..9292db503 100644 --- a/src/main/java/org/karnak/backend/data/entity/VersionEntity.java +++ b/src/main/java/org/karnak/backend/data/entity/VersionEntity.java @@ -9,13 +9,13 @@ */ package org.karnak.backend.data.entity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import java.io.Serializable; import java.util.Objects; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; @Entity(name = "Version") @Table(name = "version") diff --git a/src/main/java/org/karnak/backend/data/repo/specification/TransferStatusSpecification.java b/src/main/java/org/karnak/backend/data/repo/specification/TransferStatusSpecification.java index bd877a7b6..9e2d68f4a 100644 --- a/src/main/java/org/karnak/backend/data/repo/specification/TransferStatusSpecification.java +++ b/src/main/java/org/karnak/backend/data/repo/specification/TransferStatusSpecification.java @@ -9,16 +9,16 @@ */ package org.karnak.backend.data.repo.specification; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Path; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; import java.io.Serial; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Path; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; import org.apache.commons.lang3.StringUtils; import org.karnak.backend.data.entity.TransferStatusEntity; import org.karnak.backend.enums.TransferStatusType; diff --git a/src/main/java/org/karnak/backend/dicom/Defacer.java b/src/main/java/org/karnak/backend/dicom/Defacer.java index c98600c65..bf8423d0e 100644 --- a/src/main/java/org/karnak/backend/dicom/Defacer.java +++ b/src/main/java/org/karnak/backend/dicom/Defacer.java @@ -20,6 +20,7 @@ import org.opencv.core.Scalar; import org.opencv.core.Size; import org.opencv.imgproc.Imgproc; +import org.weasis.core.util.MathUtil; import org.weasis.opencv.data.ImageCV; import org.weasis.opencv.data.PlanarImage; import org.weasis.opencv.op.ImageProcessor; @@ -92,7 +93,7 @@ public static PlanarImage faceDetection(Attributes attributes, PlanarImage srcIm for (int x = 0; x < faceDetectionImg.width(); x++) { for (int y = 0; y < faceDetectionImg.height(); y++) { - if (faceDetectionImg.toMat().get(y, x)[0] == 255) { + if (MathUtil.isEqual(faceDetectionImg.toMat().get(y, x)[0], 255)) { Imgproc.line( faceDetectionImg.toImageCV(), new Point(x, y + 1.0), @@ -125,7 +126,7 @@ public static PlanarImage addRandPxlLine( for (int y = faceDetectImg.height() - 1; y > 0; y--) { double faceDetectPixelValue = faceDetectImg.toMat().get(y, x)[0]; - if (faceDetectPixelValue == 255.0) { + if (MathUtil.isEqual(faceDetectPixelValue, 255.0)) { faceDetected = true; yFaceDetected = y; } @@ -155,7 +156,7 @@ public static PlanarImage blurImg(PlanarImage srcImg, PlanarImage faceDetectImg) boolean faceDetected = true; int yNoBlurImg = 0; for (int y = 0; y < faceDetectImg.height(); y++) { - if (faceDetectImg.toMat().get(y, x)[0] != 0.0) { + if (MathUtil.isDifferentFromZero(faceDetectImg.toMat().get(y, x)[0])) { faceDetected = false; yNoBlurImg = y + marginBlurSkin; } @@ -177,7 +178,7 @@ public static PlanarImage mergeImg( for (int x = 0; x < faceDetectImg.width(); x++) { for (int y = faceDetectImg.height() - 1; y > 0; y--) { - if (randPxlLineImg.toMat().get(y, x)[0] != 0.0) { + if (MathUtil.isDifferentFromZero(randPxlLineImg.toMat().get(y, x)[0])) { newImg.toMat().put(y, x, randPxlLineImg.toMat().get(y, x)[0]); } else { newImg.toMat().put(y, x, srcImg.toMat().get(y, x)[0]); diff --git a/src/main/java/org/karnak/backend/exception/ExpressionActionException.java b/src/main/java/org/karnak/backend/exception/ExpressionActionException.java new file mode 100644 index 000000000..cb6f96d3d --- /dev/null +++ b/src/main/java/org/karnak/backend/exception/ExpressionActionException.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020-2021 Karnak Team and other contributors. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which is available at https://www.eclipse.org/legal/epl-2.0, or the Apache + * License, Version 2.0 which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ +package org.karnak.backend.exception; + +import java.io.Serial; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ExpressionActionException extends RuntimeException { + + @Serial + private static final long serialVersionUID = -8468625700663388828L; + + private static final Logger LOGGER = LoggerFactory.getLogger(ExpressionActionException.class); + + public ExpressionActionException(String message) { + super(message); + LOGGER.error(message); + } + +} diff --git a/src/main/java/org/karnak/backend/model/expression/ExprAction.java b/src/main/java/org/karnak/backend/model/expression/ExprAction.java index 4d994e7cc..c0df2d603 100644 --- a/src/main/java/org/karnak/backend/model/expression/ExprAction.java +++ b/src/main/java/org/karnak/backend/model/expression/ExprAction.java @@ -9,9 +9,15 @@ */ package org.karnak.backend.model.expression; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; import java.util.Objects; import org.dcm4che3.data.Attributes; import org.dcm4che3.data.VR; +import org.karnak.backend.exception.ExpressionActionException; import org.karnak.backend.model.action.ActionItem; import org.karnak.backend.model.action.Keep; import org.karnak.backend.model.action.Remove; @@ -94,6 +100,34 @@ public ActionItem Replace(String dummyValue) { return replace; } + public ActionItem ReplaceFromUriPost(String dummyValue) { + String response = null; + + if (stringValue != null) { + try { + // TODO: to improve + HttpResponse httpResponse = HttpClient.newBuilder() + .build() + .send(HttpRequest.newBuilder() + .uri(new URI(dummyValue)) + .POST(HttpRequest.BodyPublishers.ofString(stringValue)) + .build(), BodyHandlers.ofString()); + response = httpResponse.body(); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + catch (Exception e) { + throw new ExpressionActionException( + "Issue when using action ReplaceFromUriPost:%s".formatted(e.getMessage())); + } + } + + ActionItem replace = new Replace("D"); + replace.setDummyValue(response); + return replace; + } + public ActionItem UID() { return new UID("U"); } diff --git a/src/main/java/org/karnak/backend/model/profiles/Expression.java b/src/main/java/org/karnak/backend/model/profiles/Expression.java index 18a43d165..a9d5843e0 100644 --- a/src/main/java/org/karnak/backend/model/profiles/Expression.java +++ b/src/main/java/org/karnak/backend/model/profiles/Expression.java @@ -58,7 +58,7 @@ private void setActionHashMap() throws Exception { @Override public ActionItem getAction(Attributes dcm, Attributes dcmCopy, int tag, HMAC hmac) { if (exceptedTagsAction.get(tag) == null && tagsAction.get(tag) != null) { - final String expr = argumentEntities.get(0).getValue(); + final String expr = argumentEntities.get(0).getArgumentValue(); final ExprAction exprAction = new ExprAction(tag, dcm.getVR(tag), dcm, dcmCopy); return (ActionItem) ExpressionResult.get(expr, exprAction, ActionItem.class); } @@ -66,15 +66,16 @@ public ActionItem getAction(Attributes dcm, Attributes dcmCopy, int tag, HMAC hm } public void profileValidation() throws Exception { - if (!argumentEntities.stream().anyMatch(argument -> argument.getKey().equals("expr"))) { - List args = - argumentEntities.stream().map(ArgumentEntity::getKey).collect(Collectors.toList()); + if (!argumentEntities.stream().anyMatch(argument -> argument.getArgumentKey().equals("expr"))) { + List args = argumentEntities.stream() + .map(ArgumentEntity::getArgumentKey) + .collect(Collectors.toList()); throw new IllegalArgumentException( "Cannot build the expression: Missing argument, the class need [expr] as parameters. Parameters given " + args); } - final String expr = argumentEntities.get(0).getValue(); + final String expr = argumentEntities.get(0).getArgumentValue(); final ExpressionError expressionError = ExpressionResult.isValid( expr, new ExprAction(1, VR.AE, new Attributes(), new Attributes()), ActionItem.class); diff --git a/src/main/java/org/karnak/backend/security/OpenIdConnectLogoutHandler.java b/src/main/java/org/karnak/backend/security/OpenIdConnectLogoutHandler.java index 9c99e6f05..35974bae6 100644 --- a/src/main/java/org/karnak/backend/security/OpenIdConnectLogoutHandler.java +++ b/src/main/java/org/karnak/backend/security/OpenIdConnectLogoutHandler.java @@ -9,8 +9,8 @@ */ package org.karnak.backend.security; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/org/karnak/backend/service/CStoreSCPService.java b/src/main/java/org/karnak/backend/service/CStoreSCPService.java index 352da115e..e863e39fb 100644 --- a/src/main/java/org/karnak/backend/service/CStoreSCPService.java +++ b/src/main/java/org/karnak/backend/service/CStoreSCPService.java @@ -54,13 +54,12 @@ public class CStoreSCPService extends BasicCStoreSCP { private volatile int priority; - private volatile int status = 0; + private volatile int status; // Scheduled service for updating status transfer in progress private ScheduledFuture isDelayOver; - private final ScheduledExecutorService executorService = - Executors.newSingleThreadScheduledExecutor(); + private final ScheduledExecutorService executorService; @Autowired public CStoreSCPService( @@ -68,6 +67,11 @@ public CStoreSCPService( super("*"); this.destinationRepo = destinationRepo; this.forwardService = forwardService; + this.destinations = null; + this.executorService = Executors.newSingleThreadScheduledExecutor(); + this.isDelayOver = null; + this.status = 0; + this.priority = 0; } public void init(Map> destinations) { diff --git a/src/main/java/org/karnak/backend/service/DicomGatewayService.java b/src/main/java/org/karnak/backend/service/DicomGatewayService.java index e38520a9a..38c2a648e 100644 --- a/src/main/java/org/karnak/backend/service/DicomGatewayService.java +++ b/src/main/java/org/karnak/backend/service/DicomGatewayService.java @@ -36,6 +36,7 @@ public class DicomGatewayService { @Autowired public DicomGatewayService(final StoreScpForwardService storeScpForwardService) { this.storeScpForwardService = storeScpForwardService; + this.deviceService = null; } /** diff --git a/src/main/java/org/karnak/backend/service/NotificationService.java b/src/main/java/org/karnak/backend/service/NotificationService.java index 3f4069a87..044b16fcc 100644 --- a/src/main/java/org/karnak/backend/service/NotificationService.java +++ b/src/main/java/org/karnak/backend/service/NotificationService.java @@ -9,6 +9,9 @@ */ package org.karnak.backend.service; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeMessage; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; @@ -17,9 +20,6 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import javax.mail.MessagingException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; import org.karnak.backend.constant.Notification; import org.karnak.backend.data.entity.DestinationEntity; import org.karnak.backend.data.entity.TransferStatusEntity; diff --git a/src/main/java/org/karnak/backend/service/StoreScpForwardService.java b/src/main/java/org/karnak/backend/service/StoreScpForwardService.java index b363fbb4a..92504ca88 100644 --- a/src/main/java/org/karnak/backend/service/StoreScpForwardService.java +++ b/src/main/java/org/karnak/backend/service/StoreScpForwardService.java @@ -41,15 +41,15 @@ public class StoreScpForwardService { private static final Logger LOGGER = LoggerFactory.getLogger(StoreScpForwardService.class); - private final Device device = new Device("storescp"); + private final Device device; - private final ApplicationEntity ae = new ApplicationEntity("*"); + private final ApplicationEntity ae; - private final Connection conn = new Connection(); + private final Connection conn; private volatile int priority; - private volatile int status = 0; + private volatile int status; private Map> destinations; @@ -58,6 +58,12 @@ public class StoreScpForwardService { @Autowired public StoreScpForwardService(final CStoreSCPService cStoreSCPService) { this.cStoreSCPService = cStoreSCPService; + this.destinations = null; + this.status = 0; + this.priority = 0; + this.conn = new Connection(); + this.ae = new ApplicationEntity("*"); + this.device = new Device("storescp"); } /** diff --git a/src/main/java/org/karnak/backend/service/gateway/GatewayService.java b/src/main/java/org/karnak/backend/service/gateway/GatewayService.java index ea5a84934..d40e10562 100644 --- a/src/main/java/org/karnak/backend/service/gateway/GatewayService.java +++ b/src/main/java/org/karnak/backend/service/gateway/GatewayService.java @@ -9,11 +9,11 @@ */ package org.karnak.backend.service.gateway; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.io.File; import java.net.URL; import java.util.List; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import org.karnak.backend.data.entity.DestinationEntity; import org.karnak.backend.data.repo.DestinationRepo; import org.karnak.backend.dicom.GatewayParams; diff --git a/src/main/java/org/karnak/backend/service/gateway/GatewaySetUpService.java b/src/main/java/org/karnak/backend/service/gateway/GatewaySetUpService.java index c13ae4be2..ce3d5a87c 100644 --- a/src/main/java/org/karnak/backend/service/gateway/GatewaySetUpService.java +++ b/src/main/java/org/karnak/backend/service/gateway/GatewaySetUpService.java @@ -70,7 +70,7 @@ public class GatewaySetUpService { private final DestinationRepo destinationRepo; - private final Map> destMap = new HashMap<>(); + private final Map> destMap; private final Path storePath; @@ -104,6 +104,7 @@ public GatewaySetUpService( this.forwardNodeRepo = forwardNodeRepo; this.versionRepo = versionRepo; this.destinationRepo = destinationRepo; + this.destMap = new HashMap<>(); String path = SystemPropertyUtil.retrieveSystemProperty("GATEWAY_ARCHIVE_PATH", null); // Only // Archive diff --git a/src/main/java/org/karnak/backend/service/kheops/SwitchingAlbum.java b/src/main/java/org/karnak/backend/service/kheops/SwitchingAlbum.java index c915843be..20284c805 100644 --- a/src/main/java/org/karnak/backend/service/kheops/SwitchingAlbum.java +++ b/src/main/java/org/karnak/backend/service/kheops/SwitchingAlbum.java @@ -55,7 +55,7 @@ private static HMAC generateHMAC(DestinationEntity destinationEntity) { if (destinationEntity.isDesidentification()) { ProjectEntity projectEntity = destinationEntity.getDeIdentificationProjectEntity(); SecretEntity secretEntity = projectEntity.retrieveActiveSecret(); - return secretEntity != null ? new HMAC(secretEntity.getKey()) : null; + return secretEntity != null ? new HMAC(secretEntity.getSecretKey()) : null; } return null; } diff --git a/src/main/java/org/karnak/backend/service/profilepipe/Profile.java b/src/main/java/org/karnak/backend/service/profilepipe/Profile.java index c0ed2dc38..a140d9038 100644 --- a/src/main/java/org/karnak/backend/service/profilepipe/Profile.java +++ b/src/main/java/org/karnak/backend/service/profilepipe/Profile.java @@ -399,7 +399,7 @@ private HMAC generateHMAC(String patientID, ProjectEntity projectEntity) { } SecretEntity secretEntity = projectEntity.retrieveActiveSecret(); - byte[] secret = secretEntity != null ? secretEntity.getKey() : null; + byte[] secret = secretEntity != null ? secretEntity.getSecretKey() : null; if (secret == null || secret.length != HMAC.KEY_BYTE_LENGTH) { throw new IllegalStateException( "Cannot build the HMAC no secret defined in the project associate at the destination"); diff --git a/src/main/java/org/karnak/backend/util/DateFormat.java b/src/main/java/org/karnak/backend/util/DateFormat.java index bf7af393f..09aaa58ea 100644 --- a/src/main/java/org/karnak/backend/util/DateFormat.java +++ b/src/main/java/org/karnak/backend/util/DateFormat.java @@ -122,8 +122,8 @@ public static String format(Attributes dcm, int tag, List argume String format = ""; for (ArgumentEntity argumentEntity : argumentEntities) { - final String key = argumentEntity.getKey(); - final String value = argumentEntity.getValue(); + final String key = argumentEntity.getArgumentKey(); + final String value = argumentEntity.getArgumentValue(); try { if (key.equals("remove")) { @@ -151,9 +151,8 @@ public static void verifyPatternArguments(List argumentEntities) listValue.add("month_day"); if (argumentEntities.stream() - .noneMatch( - argument -> - argument.getKey().equals("remove") && listValue.contains(argument.getValue()))) { + .noneMatch(argument -> argument.getArgumentKey().equals("remove") + && listValue.contains(argument.getArgumentValue()))) { IllegalArgumentException missingParameters = new IllegalArgumentException( "Cannot build the option date_format, arguments are not correct"); diff --git a/src/main/java/org/karnak/backend/util/SecurityUtil.java b/src/main/java/org/karnak/backend/util/SecurityUtil.java index dc3d9caab..53ca38572 100644 --- a/src/main/java/org/karnak/backend/util/SecurityUtil.java +++ b/src/main/java/org/karnak/backend/util/SecurityUtil.java @@ -12,10 +12,10 @@ import com.vaadin.flow.server.HandlerHelper; import com.vaadin.flow.server.VaadinServletService; import com.vaadin.flow.shared.ApplicationConstants; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; import java.util.Objects; import java.util.stream.Stream; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; import org.karnak.backend.enums.SecurityRole; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/karnak/backend/util/ServletUtil.java b/src/main/java/org/karnak/backend/util/ServletUtil.java index 024e0b541..237da2fba 100644 --- a/src/main/java/org/karnak/backend/util/ServletUtil.java +++ b/src/main/java/org/karnak/backend/util/ServletUtil.java @@ -9,6 +9,8 @@ */ package org.karnak.backend.util; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -16,8 +18,6 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.Properties; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/karnak/backend/util/ShiftByTagDate.java b/src/main/java/org/karnak/backend/util/ShiftByTagDate.java index 6f93c935e..14db275ee 100644 --- a/src/main/java/org/karnak/backend/util/ShiftByTagDate.java +++ b/src/main/java/org/karnak/backend/util/ShiftByTagDate.java @@ -9,6 +9,7 @@ */ package org.karnak.backend.util; +import java.util.List; import org.dcm4che3.data.Attributes; import org.karnak.backend.data.entity.ArgumentEntity; import org.karnak.backend.model.expression.ExprCondition; @@ -16,8 +17,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; - public class ShiftByTagDate { private static final Logger LOGGER = LoggerFactory.getLogger(ShiftByTagDate.class); @@ -40,8 +39,8 @@ public static String shift(Attributes dcm, int tag, List argumen String shiftSecondsTag = ""; for (ArgumentEntity argumentEntity : argumentEntities) { - final String key = argumentEntity.getKey(); - final String value = argumentEntity.getValue(); + final String key = argumentEntity.getArgumentKey(); + final String value = argumentEntity.getArgumentValue(); try { if (key.equals("days_tag")) { diff --git a/src/main/java/org/karnak/backend/util/ShiftDate.java b/src/main/java/org/karnak/backend/util/ShiftDate.java index 8af7fabe3..6feaaa698 100644 --- a/src/main/java/org/karnak/backend/util/ShiftDate.java +++ b/src/main/java/org/karnak/backend/util/ShiftDate.java @@ -84,8 +84,8 @@ public static String shift(Attributes dcm, int tag, List argumen int shiftSeconds = -1; for (ArgumentEntity argumentEntity : argumentEntities) { - final String key = argumentEntity.getKey(); - final String value = argumentEntity.getValue(); + final String key = argumentEntity.getArgumentKey(); + final String value = argumentEntity.getArgumentValue(); try { if (key.equals("seconds")) { @@ -118,10 +118,11 @@ public static String shiftValue(Attributes dcm, int tag, String dcmElValue, int public static void verifyShiftArguments(List argumentEntities) throws IllegalArgumentException { - if (argumentEntities.stream().noneMatch(argument -> argument.getKey().equals("seconds")) - || argumentEntities.stream().noneMatch(argument -> argument.getKey().equals("days"))) { - List args = - argumentEntities.stream().map(ArgumentEntity::getKey).collect(Collectors.toList()); + if (argumentEntities.stream().noneMatch(argument -> argument.getArgumentKey().equals("seconds")) + || argumentEntities.stream().noneMatch(argument -> argument.getArgumentKey().equals("days"))) { + List args = argumentEntities.stream() + .map(ArgumentEntity::getArgumentKey) + .collect(Collectors.toList()); IllegalArgumentException missingParameters = new IllegalArgumentException( "Cannot build the option ShiftDate: Missing argument, the class need [seconds, days] as parameters. Parameters given " diff --git a/src/main/java/org/karnak/backend/util/ShiftRangeDate.java b/src/main/java/org/karnak/backend/util/ShiftRangeDate.java index 3aea83d85..15727a7ce 100644 --- a/src/main/java/org/karnak/backend/util/ShiftRangeDate.java +++ b/src/main/java/org/karnak/backend/util/ShiftRangeDate.java @@ -27,10 +27,11 @@ private ShiftRangeDate() { public static void verifyShiftArguments(List argumentEntities) throws IllegalArgumentException { - if (argumentEntities.stream().noneMatch(argument -> argument.getKey().equals("max_seconds")) - || argumentEntities.stream().noneMatch(argument -> argument.getKey().equals("max_days"))) { - List args = - argumentEntities.stream().map(ArgumentEntity::getKey).collect(Collectors.toList()); + if (argumentEntities.stream().noneMatch(argument -> argument.getArgumentKey().equals("max_seconds")) + || argumentEntities.stream().noneMatch(argument -> argument.getArgumentKey().equals("max_days"))) { + List args = argumentEntities.stream() + .map(ArgumentEntity::getArgumentKey) + .collect(Collectors.toList()); String text = "Cannot build the option ShiftRangeDate: Missing argument, the class minimum need [max_seconds, max_days] as parameters. Parameters given " + args; @@ -54,8 +55,8 @@ public static String shift( int shiftMinDays = 0; int shiftMinSeconds = 0; for (ArgumentEntity argumentEntity : argumentEntities) { - final String key = argumentEntity.getKey(); - final String value = argumentEntity.getValue(); + final String key = argumentEntity.getArgumentKey(); + final String value = argumentEntity.getArgumentValue(); try { if (key.equals("max_seconds")) { diff --git a/src/main/java/org/karnak/frontend/AppShell.java b/src/main/java/org/karnak/frontend/AppShell.java index 0a27ff145..831a8ce71 100644 --- a/src/main/java/org/karnak/frontend/AppShell.java +++ b/src/main/java/org/karnak/frontend/AppShell.java @@ -12,6 +12,7 @@ import com.vaadin.flow.component.page.AppShellConfigurator; import com.vaadin.flow.component.page.Push; import com.vaadin.flow.server.PWA; +import com.vaadin.flow.theme.Theme; /** * Use the @PWA annotation make the application installable on phones, tablets and some desktop @@ -19,6 +20,7 @@ */ @PWA(name = "Karnak Gateway", shortName = "karnak", iconPath = "icons/logo.png") @Push +@Theme("common-theme") public class AppShell implements AppShellConfigurator { } diff --git a/src/main/java/org/karnak/frontend/ErrorView.java b/src/main/java/org/karnak/frontend/ErrorView.java index a685e1598..303e10313 100644 --- a/src/main/java/org/karnak/frontend/ErrorView.java +++ b/src/main/java/org/karnak/frontend/ErrorView.java @@ -17,7 +17,7 @@ import com.vaadin.flow.router.HasErrorParameter; import com.vaadin.flow.router.NotFoundException; import com.vaadin.flow.router.ParentLayout; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; /** * View shown when trying to navigate to a view that does not exist using diff --git a/src/main/java/org/karnak/frontend/MainLayout.java b/src/main/java/org/karnak/frontend/MainLayout.java index df5b50605..7110e1108 100644 --- a/src/main/java/org/karnak/frontend/MainLayout.java +++ b/src/main/java/org/karnak/frontend/MainLayout.java @@ -14,9 +14,8 @@ import com.vaadin.flow.component.Key; import com.vaadin.flow.component.KeyModifier; import com.vaadin.flow.component.dependency.CssImport; -import com.vaadin.flow.component.dependency.JsModule; -import com.vaadin.flow.component.dependency.NpmPackage; -import com.vaadin.flow.component.icon.IronIcon; +import com.vaadin.flow.component.icon.Icon; +import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.orderedlayout.FlexLayout; import com.vaadin.flow.router.Route; import com.vaadin.flow.router.RouterLayout; @@ -35,11 +34,7 @@ /** * The main layout. Contains the navigation menu. */ -@NpmPackage(value = "@polymer/iron-icons", version = "3.0.1") -@JsModule("@polymer/iron-icons/iron-icons.js") -@JsModule("@vaadin/vaadin-lumo-styles/badge.js") @CssImport(value = "./styles/shared-styles.css") -@CssImport(value = "./styles/empty.css", include = "lumo-badge") @Route(value = "mainLayout") @Secured({"ROLE_admin"}) @SuppressWarnings("serial") @@ -53,25 +48,18 @@ public MainLayout() { menu = new Menu(); - // Add secured Menu - addSecuredMenu( - ForwardNodeView.class, ForwardNodeView.VIEW_NAME, new IronIcon("icons", "settings")); - addSecuredMenu(ProfileView.class, ProfileView.VIEW_NAME, new IronIcon("icons", "assignment")); - addSecuredMenu(ProjectView.class, ProjectView.VIEW_NAME, new IronIcon("icons", "class")); - addSecuredMenu( - ExternalIDView.class, ExternalIDView.VIEW_NAME, new IronIcon("icons", "perm-identity")); - addSecuredMenu( - MainzellisteView.class, MainzellisteView.VIEW_NAME, new IronIcon("icons", "perm-identity")); - addSecuredMenu( - PseudonymMappingView.class, - PseudonymMappingView.VIEW_NAME, - new IronIcon("icons", "perm-identity")); - addSecuredMenu( - MonitoringView.class, MonitoringView.VIEW_NAME, new IronIcon("icons", "history")); - addSecuredMenu(DicomMainView.class, DicomMainView.VIEW_NAME, new IronIcon("icons", "build")); - addSecuredMenu(HelpView.class, HelpView.VIEW_NAME, new IronIcon("icons", "help")); - // menu.addView(AboutView.class, AboutView.VIEW_NAME, new IronIcon("icons", - // "info")); + // Add secured Menu + addSecuredMenu(ForwardNodeView.class, ForwardNodeView.VIEW_NAME, VaadinIcon.COG_O.create()); + addSecuredMenu(ProfileView.class, ProfileView.VIEW_NAME, VaadinIcon.CLIPBOARD_TEXT.create()); + addSecuredMenu(ProjectView.class, ProjectView.VIEW_NAME, VaadinIcon.FOLDER_OPEN_O.create()); + addSecuredMenu(ExternalIDView.class, ExternalIDView.VIEW_NAME, VaadinIcon.CLIPBOARD_USER.create()); + addSecuredMenu(MainzellisteView.class, MainzellisteView.VIEW_NAME, VaadinIcon.CLIPBOARD_USER.create()); + addSecuredMenu(PseudonymMappingView.class, PseudonymMappingView.VIEW_NAME, VaadinIcon.SITEMAP.create()); + addSecuredMenu(MonitoringView.class, MonitoringView.VIEW_NAME, VaadinIcon.PIE_BAR_CHART.create()); + addSecuredMenu(DicomMainView.class, DicomMainView.VIEW_NAME, VaadinIcon.TOOLS.create()); + addSecuredMenu(HelpView.class, HelpView.VIEW_NAME, VaadinIcon.QUESTION_CIRCLE.create()); + // menu.addView(AboutView.class, AboutView.VIEW_NAME, + // VaadinIcon.INFO_CIRCLE.create()); // Add menu to the layout add(menu); @@ -84,17 +72,17 @@ protected void onAttach(AttachEvent attachEvent) { attachEvent.getUI().addShortcutListener(SecurityUtil::signOut, Key.KEY_L, KeyModifier.CONTROL); } - /** - * Build and add secured menus - * - * @param securedClass View to secure - * @param viewName Name of the view - * @param icon Icon to apply to the menu - */ - private void addSecuredMenu( - Class securedClass, String viewName, IronIcon icon) { - if (SecurityUtil.isAccessGranted(securedClass)) { - menu.addView(securedClass, viewName, icon); - } - } + /** + * Build and add secured menus + * @param securedClass View to secure + * @param viewName Name of the view + * @param icon Icon to apply to the menu + */ + private void addSecuredMenu(Class securedClass, String viewName, Icon icon) { + if (SecurityUtil.isAccessGranted(securedClass)) { + icon.getStyle().setMargin("2%"); + menu.addView(securedClass, viewName, icon); + } + } + } diff --git a/src/main/java/org/karnak/frontend/Menu.java b/src/main/java/org/karnak/frontend/Menu.java index 47149b01d..7e4b9d4b3 100644 --- a/src/main/java/org/karnak/frontend/Menu.java +++ b/src/main/java/org/karnak/frontend/Menu.java @@ -12,11 +12,8 @@ import com.vaadin.flow.component.Component; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.dependency.JsModule; -import com.vaadin.flow.component.dependency.NpmPackage; import com.vaadin.flow.component.html.Span; import com.vaadin.flow.component.icon.Icon; -import com.vaadin.flow.component.icon.IronIcon; import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.orderedlayout.FlexLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; @@ -27,8 +24,6 @@ import org.karnak.backend.util.SecurityUtil; import org.karnak.frontend.util.ToggleButtonTheme; -@NpmPackage(value = "@polymer/iron-icons", version = "3.0.1") -@JsModule("@polymer/iron-icons/iron-icons.js") @SuppressWarnings("serial") public class Menu extends FlexLayout { @@ -79,20 +74,20 @@ public Menu() { add(logoutButton); } - /** - * Add a view to the navigation menu - * - * @param viewClass that has a {@code Route} annotation - * @param caption view caption in the menu - * @param icon view icon in the menu - */ - public void addView(Class viewClass, String caption, IronIcon icon) { - Tab tab = new Tab(); - RouterLink routerLink = new RouterLink(null, viewClass); - routerLink.setClassName("menu-link"); - routerLink.add(icon); - routerLink.add(new Span(caption)); - tab.add(routerLink); - tabs.add(tab); - } + /** + * Add a view to the navigation menu + * @param viewClass that has a {@code Route} annotation + * @param caption view caption in the menu + * @param icon view icon in the menu + */ + public void addView(Class viewClass, String caption, Icon icon) { + Tab tab = new Tab(); + RouterLink routerLink = new RouterLink(viewClass); + routerLink.setClassName("menu-link"); + routerLink.add(icon); + routerLink.add(new Span(caption)); + tab.add(routerLink); + tabs.add(tab); + } + } diff --git a/src/main/java/org/karnak/frontend/authentication/LoginScreen.java b/src/main/java/org/karnak/frontend/authentication/LoginScreen.java index 6702f23cd..b8035bc9d 100644 --- a/src/main/java/org/karnak/frontend/authentication/LoginScreen.java +++ b/src/main/java/org/karnak/frontend/authentication/LoginScreen.java @@ -100,9 +100,7 @@ private void buildUI() { // It's ugly but it works. @see // https://github.com/vaadin/vaadin-login-flow/issues/53 - UI.getCurrent() - .getPage() - .executeJavaScript("document.getElementById(\"vaadinLoginUsername\").focus();"); + UI.getCurrent().getPage().executeJs("document.getElementById(\"vaadinLoginUsername\").focus();"); } /** diff --git a/src/main/java/org/karnak/frontend/component/MessageBox.java b/src/main/java/org/karnak/frontend/component/MessageBox.java index 0fb87fd99..443381665 100644 --- a/src/main/java/org/karnak/frontend/component/MessageBox.java +++ b/src/main/java/org/karnak/frontend/component/MessageBox.java @@ -12,13 +12,12 @@ import com.vaadin.flow.component.Composite; import com.vaadin.flow.component.Html; import com.vaadin.flow.component.html.Div; -import com.vaadin.flow.component.icon.IronIcon; +import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import org.karnak.backend.enums.MessageLevel; import org.karnak.backend.enums.MessageType; import org.karnak.backend.model.dicom.Message; -// @JsModule("@polymer/iron-icons/iron-icons.js") public class MessageBox extends Composite
{ private static final long serialVersionUID = 1L; @@ -30,7 +29,7 @@ public class MessageBox extends Composite
{ private Div contentDiv; - private IronIcon icon; + private Icon icon; // DATA private Message message; @@ -134,11 +133,13 @@ private void createContentDiv() { private void createIcon() { if (message != null) { if (MessageLevel.INFO == message.getLevel()) { - icon = new IronIcon("icons", "info-outline"); - } else if (MessageLevel.WARN == message.getLevel()) { - icon = new IronIcon("icons", "warning"); - } else if (MessageLevel.ERROR == message.getLevel()) { - icon = new IronIcon("icons", "error-outline"); + icon = new Icon("icons", "info-outline"); + } + else if (MessageLevel.WARN == message.getLevel()) { + icon = new Icon("icons", "warning"); + } + else if (MessageLevel.ERROR == message.getLevel()) { + icon = new Icon("icons", "error-outline"); } } } diff --git a/src/main/java/org/karnak/frontend/dicom/echo/DicomEchoSelectionDialog.java b/src/main/java/org/karnak/frontend/dicom/echo/DicomEchoSelectionDialog.java index b098a1e3a..317972294 100644 --- a/src/main/java/org/karnak/frontend/dicom/echo/DicomEchoSelectionDialog.java +++ b/src/main/java/org/karnak/frontend/dicom/echo/DicomEchoSelectionDialog.java @@ -194,7 +194,7 @@ private void buildDicomNodeSelector() { dicomNodeSelector = new ComboBox<>(); dicomNodeSelector.setLabel("Dicom Node"); dicomNodeSelector.setClearButtonVisible(true); - dicomNodeSelector.setDataProvider(dataProviderForDicomNodes); + dicomNodeSelector.setItems(dataProviderForDicomNodes); dicomNodeSelector.setItemLabelGenerator( item -> item.getName() diff --git a/src/main/java/org/karnak/frontend/extid/CSVDialog.java b/src/main/java/org/karnak/frontend/extid/CSVDialog.java index 43b06c5cf..8d1bf8f8d 100644 --- a/src/main/java/org/karnak/frontend/extid/CSVDialog.java +++ b/src/main/java/org/karnak/frontend/extid/CSVDialog.java @@ -9,6 +9,10 @@ */ package org.karnak.frontend.extid; +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import com.opencsv.exceptions.CsvException; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.dialog.Dialog; @@ -27,7 +31,6 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import liquibase.util.csv.opencsv.CSVReader; import org.karnak.backend.cache.Patient; import org.karnak.backend.data.entity.ProjectEntity; import org.slf4j.Logger; @@ -87,10 +90,13 @@ public CSVDialog(InputStream inputStream, char separator, ProjectEntity projectE this.projectEntity = projectEntity; patientsList = new ArrayList<>(); allRows = null; - try { - CSVReader csvReader = new CSVReader(new InputStreamReader(inputStream), separator); + + try (CSVReader csvReader = new CSVReaderBuilder(new InputStreamReader(inputStream)) + .withCSVParser(new CSVParserBuilder().withSeparator(separator).build()) + .build()) { allRows = csvReader.readAll(); - } catch (IOException e) { + } + catch (IOException | CsvException e) { LOGGER.error("Error while reading the CSV", e); } @@ -122,7 +128,7 @@ private void setElement() { fromLineField = new NumberField("From line "); fromLineField.setValue(1d); - fromLineField.setHasControls(true); + fromLineField.setStepButtonsVisible(true); fromLineField.setMin(1); fromLineField.setMax((double) allRows.size() + 1); diff --git a/src/main/java/org/karnak/frontend/extid/ExternalIDGrid.java b/src/main/java/org/karnak/frontend/extid/ExternalIDGrid.java index b209d6ad0..b50eff2e9 100644 --- a/src/main/java/org/karnak/frontend/extid/ExternalIDGrid.java +++ b/src/main/java/org/karnak/frontend/extid/ExternalIDGrid.java @@ -34,7 +34,7 @@ import org.karnak.backend.util.PatientClientUtil; import org.vaadin.klaudeta.PaginatedGrid; -public class ExternalIDGrid extends PaginatedGrid { +public class ExternalIDGrid extends PaginatedGrid { private static final String ERROR_MESSAGE_PATIENT = "Length must be between 1 and 50."; @@ -98,10 +98,13 @@ public class ExternalIDGrid extends PaginatedGrid { private transient Collection duplicatePatientsList = new ArrayList<>(); + private PatientFilter patientFilter; + public ExternalIDGrid() { binder = new Binder<>(Patient.class); patientList = new ArrayList<>(); this.externalIDCache = AppConfig.getInstance().getExternalIDCache(); + this.patientFilter = new PatientFilter(); setPageSize(10); setPaginatorSize(2); @@ -110,7 +113,7 @@ public ExternalIDGrid() { getElement() .addEventListener("keyup", event -> editor.cancel()) .setFilter("event.key === 'Escape' || event.key === 'Esc'"); - setHeightByRows(true); + setItems(patientList); setElements(); setBinder(); diff --git a/src/main/java/org/karnak/frontend/extid/ExternalIDLogic.java b/src/main/java/org/karnak/frontend/extid/ExternalIDLogic.java index 42bff05fb..1536969b5 100644 --- a/src/main/java/org/karnak/frontend/extid/ExternalIDLogic.java +++ b/src/main/java/org/karnak/frontend/extid/ExternalIDLogic.java @@ -25,6 +25,7 @@ public class ExternalIDLogic { @Autowired public ExternalIDLogic(final ProjectService projectService) { this.projectService = projectService; + this.externalIDView = null; } public void setExternalIDView(ExternalIDView externalIDView) { diff --git a/src/main/java/org/karnak/frontend/extid/PatientFilter.java b/src/main/java/org/karnak/frontend/extid/PatientFilter.java new file mode 100644 index 000000000..a51f401ff --- /dev/null +++ b/src/main/java/org/karnak/frontend/extid/PatientFilter.java @@ -0,0 +1,56 @@ +package org.karnak.frontend.extid; + +// TODO: currently not used but should be used to replace filters in ExternalIDGrid +public class PatientFilter { + + private String extidFilter; + + private String patientIdFilter; + + private String patientFirstNameFilter; + + private String patientLastNameFilter; + + private String issuerOfPatientIDFilter; + + public String getExtidFilter() { + return extidFilter; + } + + public void setExtidFilter(String extidFilter) { + this.extidFilter = extidFilter; + } + + public String getPatientIdFilter() { + return patientIdFilter; + } + + public void setPatientIdFilter(String patientIdFilter) { + this.patientIdFilter = patientIdFilter; + } + + public String getPatientFirstNameFilter() { + return patientFirstNameFilter; + } + + public void setPatientFirstNameFilter(String patientFirstNameFilter) { + this.patientFirstNameFilter = patientFirstNameFilter; + } + + public String getPatientLastNameFilter() { + return patientLastNameFilter; + } + + public void setPatientLastNameFilter(String patientLastNameFilter) { + this.patientLastNameFilter = patientLastNameFilter; + } + + public String getIssuerOfPatientIDFilter() { + return issuerOfPatientIDFilter; + } + + public void setIssuerOfPatientIDFilter(String issuerOfPatientIDFilter) { + this.issuerOfPatientIDFilter = issuerOfPatientIDFilter; + } + +} diff --git a/src/main/java/org/karnak/frontend/forwardnode/ForwardNodeLogic.java b/src/main/java/org/karnak/frontend/forwardnode/ForwardNodeLogic.java index b0aa05a42..5a82d5688 100644 --- a/src/main/java/org/karnak/frontend/forwardnode/ForwardNodeLogic.java +++ b/src/main/java/org/karnak/frontend/forwardnode/ForwardNodeLogic.java @@ -52,7 +52,7 @@ public class ForwardNodeLogic extends ListDataProvider { /** * Text filter that can be changed separately. */ - private String filterText = ""; + private String filterText; @Autowired public ForwardNodeLogic( @@ -69,6 +69,8 @@ public ForwardNodeLogic( this.sopClassUIDService = sopClassUIDService; this.sourceLogic = sourceLogic; this.destinationLogic = destinationLogic; + this.filterText = ""; + this.forwardNodeView = null; initDataProvider(); } diff --git a/src/main/java/org/karnak/frontend/forwardnode/edit/component/ButtonSaveDeleteCancel.java b/src/main/java/org/karnak/frontend/forwardnode/edit/component/ButtonSaveDeleteCancel.java index f906a800b..f09799647 100644 --- a/src/main/java/org/karnak/frontend/forwardnode/edit/component/ButtonSaveDeleteCancel.java +++ b/src/main/java/org/karnak/frontend/forwardnode/edit/component/ButtonSaveDeleteCancel.java @@ -39,16 +39,16 @@ public ButtonSaveDeleteCancel() { } private void setButtonSave() { - save.setWidth("100%"); + save.setWidth("33%"); save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); } private void setButtonCancel() { - cancel.setWidth("100%"); + cancel.setWidth("33%"); } private void setButtonDelete() { - delete.setWidth("100%"); + delete.setWidth("33%"); delete.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_PRIMARY); } diff --git a/src/main/java/org/karnak/frontend/forwardnode/edit/destination/DestinationLogic.java b/src/main/java/org/karnak/frontend/forwardnode/edit/destination/DestinationLogic.java index 2b940d090..96c5fe762 100644 --- a/src/main/java/org/karnak/frontend/forwardnode/edit/destination/DestinationLogic.java +++ b/src/main/java/org/karnak/frontend/forwardnode/edit/destination/DestinationLogic.java @@ -50,7 +50,7 @@ public class DestinationLogic extends ListDataProvider { /** * Text filter that can be changed separately. */ - private String filterText = ""; + private String filterText; private ForwardNodeEntity forwardNodeEntity; // Current forward node @@ -63,6 +63,9 @@ public class DestinationLogic extends ListDataProvider { public DestinationLogic(final DestinationService destinationService) { super(new HashSet<>()); this.destinationService = destinationService; + this.forwardNodeEntity = null; + this.filterText = ""; + this.destinationView = null; } @Override @@ -322,6 +325,6 @@ public void deleteDestination(DestinationEntity destinationEntity) { public DestinationEntity retrieveDestinationEntity(Long id) { List destinationEntities = destinationService.retrieveDestinationsFromIds(List.of(id)); - return destinationEntities.stream().findFirst().orElse(null); + return destinationEntities.isEmpty() ? null : destinationEntities.stream().findFirst().orElse(null); } } diff --git a/src/main/java/org/karnak/frontend/forwardnode/edit/destination/component/FilterBySOPClassesForm.java b/src/main/java/org/karnak/frontend/forwardnode/edit/destination/component/FilterBySOPClassesForm.java index 741108336..2f0ba388c 100644 --- a/src/main/java/org/karnak/frontend/forwardnode/edit/destination/component/FilterBySOPClassesForm.java +++ b/src/main/java/org/karnak/frontend/forwardnode/edit/destination/component/FilterBySOPClassesForm.java @@ -10,14 +10,14 @@ package org.karnak.frontend.forwardnode.edit.destination.component; import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.combobox.MultiSelectComboBox; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.data.binder.Binder; import org.karnak.backend.data.entity.DestinationEntity; -import org.vaadin.gatanaso.MultiselectComboBox; public class FilterBySOPClassesForm extends HorizontalLayout { - private final MultiselectComboBox sopFilter; + private final MultiSelectComboBox sopFilter; private final Checkbox filterBySOPClassesCheckbox; @@ -25,7 +25,7 @@ public class FilterBySOPClassesForm extends HorizontalLayout { public FilterBySOPClassesForm() { this.filterBySOPClassesCheckbox = new Checkbox("Authorized SOPs"); - this.sopFilter = new MultiselectComboBox<>(); + this.sopFilter = new MultiSelectComboBox<>(); } public void init(Binder binder) { @@ -48,7 +48,7 @@ private void setElements() { sopFilter.onEnabledStateChanged(checkboxBooleanComponentValueChangeEvent.getValue())); } - public MultiselectComboBox getSopFilter() { + public MultiSelectComboBox getSopFilter() { return sopFilter; } diff --git a/src/main/java/org/karnak/frontend/forwardnode/edit/destination/component/PseudonymInDicomTagComponent.java b/src/main/java/org/karnak/frontend/forwardnode/edit/destination/component/PseudonymInDicomTagComponent.java index be1987085..0ebf68565 100644 --- a/src/main/java/org/karnak/frontend/forwardnode/edit/destination/component/PseudonymInDicomTagComponent.java +++ b/src/main/java/org/karnak/frontend/forwardnode/edit/destination/component/PseudonymInDicomTagComponent.java @@ -41,7 +41,7 @@ public void setElements() { delimiter = new TextField("Delimiter"); tag = new TextField("Tag"); position = new NumberField("Position"); - position.setHasControls(true); + position.setStepButtonsVisible(true); position.setMin(0); position.setStep(1); savePseudonym = new Checkbox("Save pseudonym in Mainzelliste"); diff --git a/src/main/java/org/karnak/frontend/forwardnode/edit/source/SourceLogic.java b/src/main/java/org/karnak/frontend/forwardnode/edit/source/SourceLogic.java index 171bf5891..820dbb77a 100644 --- a/src/main/java/org/karnak/frontend/forwardnode/edit/source/SourceLogic.java +++ b/src/main/java/org/karnak/frontend/forwardnode/edit/source/SourceLogic.java @@ -34,7 +34,7 @@ public class SourceLogic extends ListDataProvider { /** * Text filter that can be changed separately. */ - private String filterText = ""; + private String filterText; private ForwardNodeEntity forwardNodeEntity; // Current forward node @@ -47,6 +47,9 @@ public class SourceLogic extends ListDataProvider { public SourceLogic(final SourceNodeService sourceNodeService) { super(new HashSet<>()); this.sourceNodeService = sourceNodeService; + this.sourceView = null; + this.forwardNodeEntity = null; + this.filterText = ""; } @Override diff --git a/src/main/java/org/karnak/frontend/kheops/GridSwitchingAlbums.java b/src/main/java/org/karnak/frontend/kheops/GridSwitchingAlbums.java index a2a85a5c8..19941ac20 100644 --- a/src/main/java/org/karnak/frontend/kheops/GridSwitchingAlbums.java +++ b/src/main/java/org/karnak/frontend/kheops/GridSwitchingAlbums.java @@ -46,7 +46,7 @@ public class GridSwitchingAlbums extends Grid { public GridSwitchingAlbums() { setWidthFull(); - setHeightByRows(true); + setItems(new ArrayList<>()); dataProvider = (ListDataProvider) getDataProvider(); diff --git a/src/main/java/org/karnak/frontend/mainzelliste/MainzellisteAddPatient.java b/src/main/java/org/karnak/frontend/mainzelliste/MainzellisteAddPatient.java index db1bab153..e8d345c54 100644 --- a/src/main/java/org/karnak/frontend/mainzelliste/MainzellisteAddPatient.java +++ b/src/main/java/org/karnak/frontend/mainzelliste/MainzellisteAddPatient.java @@ -12,7 +12,7 @@ import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.datepicker.DatePicker; -import com.vaadin.flow.component.icon.IronIcon; +import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.select.Select; @@ -115,7 +115,7 @@ private void setElements() { saveInMainzellisteButton = new Button("Save patient in Mainzelliste"); saveInMainzellisteButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - saveInMainzellisteButton.setIcon(new IronIcon("icons", "icons:send")); + saveInMainzellisteButton.setIcon(new Icon("icons", "icons:send")); horizontalLayoutAddClear = new HorizontalLayout(); horizontalLayoutAddClear.getStyle().set("margin-left", "auto"); diff --git a/src/main/java/org/karnak/frontend/monitoring/MonitoringLogic.java b/src/main/java/org/karnak/frontend/monitoring/MonitoringLogic.java index f0dcbb9b9..b3ae8094a 100644 --- a/src/main/java/org/karnak/frontend/monitoring/MonitoringLogic.java +++ b/src/main/java/org/karnak/frontend/monitoring/MonitoringLogic.java @@ -43,6 +43,7 @@ public class MonitoringLogic { @Autowired public MonitoringLogic(final TransferMonitoringService transferMonitoringService) { this.transferMonitoringService = transferMonitoringService; + this.monitoringView = null; } public MonitoringView getMonitoringView() { diff --git a/src/main/java/org/karnak/frontend/monitoring/MonitoringView.java b/src/main/java/org/karnak/frontend/monitoring/MonitoringView.java index 31e954476..d07a8ebae 100644 --- a/src/main/java/org/karnak/frontend/monitoring/MonitoringView.java +++ b/src/main/java/org/karnak/frontend/monitoring/MonitoringView.java @@ -23,7 +23,6 @@ import org.karnak.frontend.MainLayout; import org.karnak.frontend.monitoring.component.ExportSettingsDialog; import org.karnak.frontend.monitoring.component.TransferStatusGrid; -import org.karnak.frontend.util.UIS; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; @@ -91,25 +90,21 @@ private void buildComponents() { // Refresh button refreshGridButton = new Button("Refresh", new Icon(VaadinIcon.REFRESH)); refreshGridButton.addClickListener(buttonClickEvent -> transferStatusDataProvider.refreshAll()); - refreshGridButton.setWidthFull(); + refreshGridButton.setWidth("33%"); // Export Settings Dialog exportSettingsDialog = new ExportSettingsDialog(); // Export Settings Button exportSettingsButton = new Button("Export Settings", new Icon(VaadinIcon.COGS)); - exportSettingsButton.setWidthFull(); + exportSettingsButton.setWidth("33%"); exportSettingsButton.addClickListener(buttonClickEvent -> exportSettingsDialog.open()); // Export button - StreamResource streamResource = - new StreamResource( - "export.csv", - () -> - new ByteArrayInputStream( - monitoringLogic.buildCsv(exportSettingsDialog.getExportSettings()))); + StreamResource streamResource = new StreamResource("export.csv", + () -> new ByteArrayInputStream(monitoringLogic.buildCsv(exportSettingsDialog.getExportSettings()))); exportAnchor = new Anchor(streamResource, ""); - exportAnchor.setWidthFull(); + exportAnchor.setWidth("33%"); Button exportButton = new Button("Export", new Icon(VaadinIcon.DOWNLOAD_ALT)); exportButton.setWidthFull(); exportAnchor.getElement().setAttribute("download", true); @@ -121,9 +116,9 @@ private void buildComponents() { */ private void addComponentsView() { add(transferStatusGrid); - HorizontalLayout buttonLayout = - new HorizontalLayout(exportSettingsButton, exportAnchor, refreshGridButton); - add(UIS.setWidthFull(buttonLayout)); + HorizontalLayout buttonLayout = new HorizontalLayout(exportSettingsButton, exportAnchor, refreshGridButton); + buttonLayout.setWidthFull(); + add(buttonLayout); setSizeFull(); setWidthFull(); } diff --git a/src/main/java/org/karnak/frontend/monitoring/TransferStatusDataProvider.java b/src/main/java/org/karnak/frontend/monitoring/TransferStatusDataProvider.java index 51c5c1fdd..ceecf95c7 100644 --- a/src/main/java/org/karnak/frontend/monitoring/TransferStatusDataProvider.java +++ b/src/main/java/org/karnak/frontend/monitoring/TransferStatusDataProvider.java @@ -35,7 +35,9 @@ public TransferStatusDataProvider(MonitoringLogic monitoringLogic) { this.monitoringLogic = monitoringLogic; // Default sort order - setSortOrders(); + QuerySortOrderBuilder builder = new QuerySortOrderBuilder(); + builder.thenDesc("transferDate"); + this.defaultSortOrders = builder.build(); } @Override @@ -55,12 +57,4 @@ protected int sizeInBackEnd(Query query) { return monitoringLogic.countTransferStatus(filter); } - /** - * Default sort order - */ - private void setSortOrders() { - QuerySortOrderBuilder builder = new QuerySortOrderBuilder(); - builder.thenDesc("transferDate"); - defaultSortOrders = builder.build(); - } } diff --git a/src/main/java/org/karnak/frontend/monitoring/component/TransferStatusGrid.java b/src/main/java/org/karnak/frontend/monitoring/component/TransferStatusGrid.java index 306e8d0e0..9e250b24c 100644 --- a/src/main/java/org/karnak/frontend/monitoring/component/TransferStatusGrid.java +++ b/src/main/java/org/karnak/frontend/monitoring/component/TransferStatusGrid.java @@ -34,7 +34,7 @@ /** * Grid for the monitoring view */ -public class TransferStatusGrid extends PaginatedGrid { +public class TransferStatusGrid extends PaginatedGrid { // Tooltips public static final String TOOLTIP_FILTER_BY_ORIGINAL_OR_DEIDENTIFIED_VALUE = diff --git a/src/main/java/org/karnak/frontend/profile/ProfileLogic.java b/src/main/java/org/karnak/frontend/profile/ProfileLogic.java index 5884c0609..93de27380 100644 --- a/src/main/java/org/karnak/frontend/profile/ProfileLogic.java +++ b/src/main/java/org/karnak/frontend/profile/ProfileLogic.java @@ -49,6 +49,7 @@ public class ProfileLogic extends ListDataProvider { public ProfileLogic(final ProfilePipeService profilePipeService) { super(new ArrayList<>()); this.profilePipeService = profilePipeService; + this.profileView = null; initDataProvider(); } diff --git a/src/main/java/org/karnak/frontend/profile/component/editprofile/ProfileComponent.java b/src/main/java/org/karnak/frontend/profile/component/editprofile/ProfileComponent.java index 97e5ac73d..32bfe2291 100644 --- a/src/main/java/org/karnak/frontend/profile/component/editprofile/ProfileComponent.java +++ b/src/main/java/org/karnak/frontend/profile/component/editprofile/ProfileComponent.java @@ -161,14 +161,11 @@ public void createDownloadButton(ProfileEntity profileEntity) { download = new Anchor(profileStreamResource, ""); download.getElement().setAttribute("download", true); download.add(new Button(new Icon(VaadinIcon.DOWNLOAD_ALT))); - download.getStyle().set("margin-top", "30px"); } private void createDeleteButton(ProfileEntity profileEntity) { deleteButton = new Button((new Icon(VaadinIcon.TRASH))); - deleteButton.setWidth("100%"); deleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_PRIMARY); - deleteButton.getStyle().set("margin-top", "34px"); deleteButton.addClickListener( buttonClickEvent -> { if (profileEntity.getProjectEntities() != null diff --git a/src/main/java/org/karnak/frontend/profile/component/editprofile/ProfileElementView.java b/src/main/java/org/karnak/frontend/profile/component/editprofile/ProfileElementView.java index 1c82361e3..fd21b7993 100644 --- a/src/main/java/org/karnak/frontend/profile/component/editprofile/ProfileElementView.java +++ b/src/main/java/org/karnak/frontend/profile/component/editprofile/ProfileElementView.java @@ -84,7 +84,7 @@ private VerticalLayout setProfileArguments(List argumentEntities verticalLayout.getStyle().set("margin-top", "0px"); for (ArgumentEntity argumentEntity : argumentEntities) { Div tagDiv = new Div(); - tagDiv.add(new Text(argumentEntity.getKey() + " : " + argumentEntity.getValue())); + tagDiv.add(new Text(argumentEntity.getArgumentKey() + " : " + argumentEntity.getArgumentValue())); tagDiv.getStyle().set("color", "grey").set("padding-left", "15px").set("margin-top", "2px"); verticalLayout.add(tagDiv); } diff --git a/src/main/java/org/karnak/frontend/profile/component/errorprofile/ProfileErrorView.java b/src/main/java/org/karnak/frontend/profile/component/errorprofile/ProfileErrorView.java index 78265b713..59ec6c2ca 100644 --- a/src/main/java/org/karnak/frontend/profile/component/errorprofile/ProfileErrorView.java +++ b/src/main/java/org/karnak/frontend/profile/component/errorprofile/ProfileErrorView.java @@ -12,7 +12,7 @@ import com.vaadin.flow.component.Text; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.H2; -import com.vaadin.flow.component.icon.IronIcon; +import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import java.util.ArrayList; import org.karnak.backend.data.entity.ProfileElementEntity; @@ -60,15 +60,15 @@ public void setProfileShowHide(ProfileElementEntity profileElementEntity) { profileShowHide.setView(); } - private IronIcon setErrorIcon() { - IronIcon errorIcon = new IronIcon("icons", "error"); + private Icon setErrorIcon() { + Icon errorIcon = new Icon("icons", "error"); errorIcon.setColor("red"); errorIcon.getStyle().set("padding-left", "5px"); return errorIcon; } - private IronIcon setSuccessIcon() { - IronIcon errorIcon = new IronIcon("icons", "check"); + private Icon setSuccessIcon() { + Icon errorIcon = new Icon("icons", "check"); errorIcon.setColor("green"); errorIcon.getStyle().set("padding-left", "5px"); return errorIcon; diff --git a/src/main/java/org/karnak/frontend/project/ProjectLogic.java b/src/main/java/org/karnak/frontend/project/ProjectLogic.java index f4c01f8e7..4a7fac349 100644 --- a/src/main/java/org/karnak/frontend/project/ProjectLogic.java +++ b/src/main/java/org/karnak/frontend/project/ProjectLogic.java @@ -61,6 +61,7 @@ public ProjectLogic( this.projectService = projectService; this.profilePipeService = profilePipeService; this.secretService = secretService; + this.projectView = null; initDataProvider(); } diff --git a/src/main/java/org/karnak/frontend/project/component/GridProject.java b/src/main/java/org/karnak/frontend/project/component/GridProject.java index 50d74b553..78ca16639 100644 --- a/src/main/java/org/karnak/frontend/project/component/GridProject.java +++ b/src/main/java/org/karnak/frontend/project/component/GridProject.java @@ -19,7 +19,6 @@ public class GridProject extends Grid { public GridProject() { setWidthFull(); - setHeightByRows(true); Column projectNameColumn = addColumn(ProjectEntity::getName) diff --git a/src/main/java/org/karnak/frontend/project/component/ProjectSecret.java b/src/main/java/org/karnak/frontend/project/component/ProjectSecret.java index fe029fa12..00f50d507 100644 --- a/src/main/java/org/karnak/frontend/project/component/ProjectSecret.java +++ b/src/main/java/org/karnak/frontend/project/component/ProjectSecret.java @@ -104,7 +104,7 @@ private void eventImportSecret() { boolean alreadyExisting = valid && items.stream() - .map(secretEntity -> HMAC.showHexKey(HMAC.byteToHex(secretEntity.getKey()))) + .map(secretEntity -> HMAC.showHexKey(HMAC.byteToHex(secretEntity.getSecretKey()))) .anyMatch(secretValue -> Objects.equals(secretValue, customValue)); // Already existing diff --git a/src/main/java/org/karnak/frontend/project/component/TextFieldsBindProject.java b/src/main/java/org/karnak/frontend/project/component/TextFieldsBindProject.java index 7eba883a7..aad281cde 100644 --- a/src/main/java/org/karnak/frontend/project/component/TextFieldsBindProject.java +++ b/src/main/java/org/karnak/frontend/project/component/TextFieldsBindProject.java @@ -66,7 +66,7 @@ private Binder setBinder() { */ private Validator secretValidValidator() { return (secretEntity, valueContext) -> { - if (HMAC.validateKey(HMAC.byteToHex(secretEntity.getKey()))) { + if (HMAC.validateKey(HMAC.byteToHex(secretEntity.getSecretKey()))) { return ValidationResult.ok(); } else { return ValidationResult.error("Secret is not valid"); @@ -81,9 +81,8 @@ private Validator secretValidValidator() { */ private Validator secretMandatoryValidator() { return (secretEntity, valueContext) -> { - if (secretComboBox.getValue() != null - && secretEntity.getKey() != null - && secretEntity.getKey().length > 0) { + if (secretComboBox.getValue() != null && secretEntity.getSecretKey() != null + && secretEntity.getSecretKey().length > 0) { return ValidationResult.ok(); } else { return ValidationResult.error("Secret is mandatory"); diff --git a/src/main/java/org/karnak/frontend/pseudonym/mapping/PseudonymMappingLogic.java b/src/main/java/org/karnak/frontend/pseudonym/mapping/PseudonymMappingLogic.java index afc58701b..5016ce52b 100644 --- a/src/main/java/org/karnak/frontend/pseudonym/mapping/PseudonymMappingLogic.java +++ b/src/main/java/org/karnak/frontend/pseudonym/mapping/PseudonymMappingLogic.java @@ -25,8 +25,8 @@ import org.springframework.stereotype.Service; /** - * Mapping logic service use to make calls to backend and implement logic linked to the mapping - * view + * Mapping logic service use to make calls to backend and implement logic linked to the + * mapping view */ @Service public class PseudonymMappingLogic { @@ -46,7 +46,6 @@ public class PseudonymMappingLogic { /** * Autowired constructor - * * @param pseudonymMappingService Pseudonym mapping backend service * @param externalIDCache External ID Cache * @param projectService Project service @@ -59,11 +58,11 @@ public PseudonymMappingLogic( this.pseudonymMappingService = pseudonymMappingService; this.externalIDCache = externalIDCache; this.projectService = projectService; + this.pseudonymMappingView = null; } /** * Retrieve a patient stored in mainzelliste by its pseudonym - * * @param pseudonym Pseudonym * @return Patient found */ @@ -72,9 +71,8 @@ public Patient retrieveMainzellistePatient(String pseudonym) { } /** - * Retrieve a map of patients by project stored in external id cache which have the pseudonym in - * parameter - * + * Retrieve a map of patients by project stored in external id cache which have the + * pseudonym in parameter * @param pseudonym Pseudonym * @return Map of patients by project */ diff --git a/src/main/java/org/karnak/frontend/pseudonym/mapping/component/MappingResultComponent.java b/src/main/java/org/karnak/frontend/pseudonym/mapping/component/MappingResultComponent.java index b228c96f6..3935fe4dd 100644 --- a/src/main/java/org/karnak/frontend/pseudonym/mapping/component/MappingResultComponent.java +++ b/src/main/java/org/karnak/frontend/pseudonym/mapping/component/MappingResultComponent.java @@ -45,15 +45,13 @@ public MappingResultComponent() { /** * Handle result when Find is clicked - * * @param patientFound patient found/not found by the backend * @param inputValue Input value entered by the user * @param location from where the mapping has been taken from */ public void handleResultFindPatient(Patient patientFound, String inputValue, String location) { // Reset details - getPatientFoundDetails().setContent(null); - getPatientFoundDetails().setSummary(null); + getPatientFoundDetails().removeAll(); // If found set patient data if (patientFound != null) { @@ -66,7 +64,6 @@ public void handleResultFindPatient(Patient patientFound, String inputValue, Str /** * Handle Result of Find Patient when Patient Not Found - * * @param inputValue Input value entered by the user * @param location from where the mapping has been taken from */ @@ -81,7 +78,6 @@ public static void handleResultFindPatientPatientNotFound(String inputValue, Str /** * Handle Result of Find Patient when Patient Found - * * @param patientFound Patient found * @param location Where the patient has been stored */ @@ -115,7 +111,6 @@ private void handleResultFindPatientPatientFound(Patient patientFound, String lo /** * Add information of the patient found in badge title components - * * @param patientFoundDetailLayout Layout * @param title Title * @param value Value of the patient found @@ -129,7 +124,6 @@ private void addDetailPatientFound( /** * Build badge title - * * @param title Title * @return BoxShadowComponent designed with the title */ diff --git a/src/main/resources/application-oidc.yml b/src/main/resources/application-oidc.yml index 668786b8f..d60e909c6 100644 --- a/src/main/resources/application-oidc.yml +++ b/src/main/resources/application-oidc.yml @@ -1,3 +1,7 @@ +# -------------------------------------------------------- +# Karnak OIDC Application properties +# -------------------------------------------------------- +#Keycloak OIDC spring: security: oauth2: @@ -12,4 +16,5 @@ spring: - openid provider: keycloak: - issuer-uri: '${OIDC_ISSUER_URI:undefined}' \ No newline at end of file + issuer-uri: '${OIDC_ISSUER_URI:undefined}' + jwk-set-uri: '${OIDC_ISSUER_URI:undefined}/protocol/openid-connect/certs' diff --git a/src/main/resources/application-redis.yml b/src/main/resources/application-redis.yml index 1453fdd97..1b9036d21 100644 --- a/src/main/resources/application-redis.yml +++ b/src/main/resources/application-redis.yml @@ -1,8 +1,11 @@ spring: - redis: - host: ${REDIS_HOST:localhost} - port: ${REDIS_PORT:6379} + data: + redis: + host: ${REDIS_HOST:localhost} + port: ${REDIS_PORT:6379} cache: type: REDIS redis: - cache-null-values: false \ No newline at end of file + cache-null-values: false + + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7201c94ca..8d165e7c3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -55,9 +55,13 @@ spring: generate-ddl: false show-sql: false open-in-view: false - database-platform: org.hibernate.dialect.PostgreSQL9Dialect + database-platform: org.hibernate.dialect.PostgreSQLDialect properties: hibernate: + # In order to still use the unique hibernate_sequence, otherwise we should create a sequence table_name_seq for + # each tables + id: + db_structure_naming_strategy: legacy temp: use_jdbc_metadata_defaults: false jdbc: diff --git a/src/main/resources/db/changelog/changes/db.changelog-1.3.xml b/src/main/resources/db/changelog/changes/db.changelog-1.3.xml index c3fbeb713..4f3a13510 100644 --- a/src/main/resources/db/changelog/changes/db.changelog-1.3.xml +++ b/src/main/resources/db/changelog/changes/db.changelog-1.3.xml @@ -362,4 +362,25 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 259f1dfea..9920caca4 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -23,7 +23,7 @@ WARN - %black(%d{ISO8601}) %highlight(%-5level) %marker %highlight(%X{SOPInstanceUID}) %highlight(%X{issuerOfPatientID}) %highlight(%X{PatientID}) [%yellow(%t)] %yellow(%C{1.}): %msg%n%throwable + %black(%d{ISO8601}) %highlight(%-5level) %marker %highlight(%X{SOPInstanceUID}) %highlight(%X{issuerOfPatientID}) %highlight(%X{PatientID}) [%yellow(%t)] %yellow(%C{1}): %msg%n%throwable