diff --git a/.github/workflows/ci-rc.yml b/.github/workflows/ci-rc.yml new file mode 100644 index 00000000..522be3aa --- /dev/null +++ b/.github/workflows/ci-rc.yml @@ -0,0 +1,89 @@ +name: ci-rc +on: + push: + branches: [develop] + pull_request: + branches: [develop] +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 21 + - name: Build with Maven + run: mvn -B clean package + - name: Upload jar + uses: actions/upload-artifact@v3 + with: + name: jar + path: target/*.jar + + get_version: + needs: build + if: | + github.event_name == 'push' + runs-on: ubuntu-latest + outputs: + version: ${{steps.version.outputs.version}} + steps: + - name: Checkout current branch + uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} + - name: Get current version + id: version + run: echo "version=$(mvn -f pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout)" >> "$GITHUB_OUTPUT" + - run: echo ${{steps.version.outputs.version}} + + release: + needs: get_version + runs-on: ubuntu-latest + steps: + - name: Checkout current branch + uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} + - uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{needs.get_version.outputs.version}}-rc + target_commitish: ${{ github.head_ref || github.ref }} + name: Release ${{needs.get_version.outputs.version}}-rc + draft: false + generate_release_notes: true + prerelease: false + + + docker: + needs: get_version + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} + - name: Download jar + id: download + uses: actions/download-artifact@v3 + with: + name: jar + path: target + - uses: docker/setup-qemu-action@v2 + - uses: docker/setup-buildx-action@v2 + - uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - uses: docker/build-push-action@v4 + with: + platforms: linux/amd64,linux/arm64 + context: . + push: true + tags: | + inseefr/platine-management-back-office:${{ needs.get_version.outputs.version }}-rc + inseefr/platine-management-back-office:latest diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1e5bd95..b1045841 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,11 +10,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: distribution: temurin - java-version: 17 + java-version: 21 - name: Build with Maven run: mvn -B clean package - name: Upload jar diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 2c638d81..00000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,76 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [main] - pull_request: - # The branches below must be a subset of the branches above - branches: [main] - schedule: - - cron: "31 19 * * 2" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: ["java"] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: actions/setup-java@v3 - with: - java-version: "17" - distribution: "temurin" - - name: Build with Maven - run: mvn -DskipTests package - - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml new file mode 100644 index 00000000..96fafd5a --- /dev/null +++ b/.github/workflows/sonar.yml @@ -0,0 +1,39 @@ +name: Sonar Analysis + +on: + push: + branches: + - main + - develop + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + name: Build and analyze + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: 21 + distribution: 'temurin' + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache Maven packages + uses: actions/cache@v3 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: mvn clean verify -Pcoverage sonar:sonar -Dsonar.projectKey=InseeFr_Platine-Management-Back-Office --no-transfer-progress \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6fea1f22..830567ce 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/ +*.log.* ### STS ### .apt_generated diff --git a/Dockerfile b/Dockerfile index fb89e2e3..1e044d0a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,14 @@ -FROM eclipse-temurin:17.0.7_7-jre -WORKDIR /application -RUN rm -rf /application -ADD target/*.jar /application/app.jar -ENTRYPOINT ["java", "-jar", "/application/app.jar"] \ No newline at end of file +FROM eclipse-temurin:21.0.2_13-jre-alpine + +WORKDIR /opt/app/ +COPY ./target/*.jar /opt/app/app.jar + +# Setup a non-root user context (security) +RUN addgroup -g 1000 tomcatgroup +RUN adduser -D -s / -u 1000 tomcatuser -G tomcatgroup +RUN mkdir /opt/app/temp-files +RUN chown -R 1000:1000 /opt/app + +USER 1000 + +ENTRYPOINT ["java", "-jar", "/opt/app/app.jar"] diff --git a/README.md b/README.md index c1892a72..db3044ff 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ REST API for communication between DB and Platine-Management UI and Platine-My-S For building and running the application you need: -- JDK 11 +- JDK 21 - Maven 3 ## Install and excute unit tests diff --git a/pom.xml b/pom.xml index 9b2349ac..ffa8293c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,26 +1,28 @@ - + 4.0.0 org.springframework.boot spring-boot-starter-parent - 2.7.13 + 3.2.3 fr.insee.survey platine-management - 1.0.30 + 2.1.3 platine-management REST API for communication between DB and Platine-Management UI and Platine-My-Surveys UI - 17 - 1.6.8 + 21 + 2.2.0 3.1.0 - 2.9.7 - 4.0.0 + 3.1.0 + 5.0.0 1.0.2 - 1.15.3 - 20230227 + inseefr + https://sonarcloud.io @@ -31,11 +33,14 @@ org.springframework.boot spring-boot-starter-tomcat - org.springframework.boot spring-boot-starter-data-jpa + + org.springframework.boot + spring-boot-starter-validation + org.modelmapper modelmapper @@ -58,14 +63,15 @@ org.springdoc - springdoc-openapi-ui + springdoc-openapi-starter-webmvc-ui ${springdoc-version} - org.springdoc - springdoc-openapi-data-rest - ${springdoc-version} + jakarta.ws.rs + jakarta.ws.rs-api + ${jakarta-version} + org.postgresql postgresql @@ -84,18 +90,6 @@ org.springframework.security spring-security-oauth2-client - - - org.json - json - ${orgjson-version} - - - - com.vladmihalcea - hibernate-types-52 - ${vladmihalcea-version} - @@ -108,15 +102,15 @@ com.github.javafaker javafaker ${javafaker-version} + + + org.yaml + snakeyaml + + - - org.testcontainers - junit-jupiter - ${testcontainers-version} - test - org.springframework.security spring-security-test @@ -144,13 +138,43 @@ io.micrometer micrometer-registry-prometheus - - org.springframework.security - spring-security-oauth2-jose - 5.7.2 - + + + + coverage + + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + prepare-agent + + prepare-agent + + + + report + + report + + + + XML + + + + + + + + + + @@ -176,4 +200,5 @@ + diff --git a/renovate.json b/renovate.json index 39a2b6e9..17869171 100644 --- a/renovate.json +++ b/renovate.json @@ -2,5 +2,45 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "config:base" - ] + ], + "packageRules": [ + { + "matchPackagePatterns": ["*"], + "labels": ["dependencies"], + "bumpVersion": "patch", + "dependencyDashboardApproval": true + }, + { + "groupName": "spring", + "groupSlug": "spring", + "matchPackagePatterns": ["org.springframework.*"], + "bumpVersion": "minor", + "dependencyDashboardApproval": true + }, + { + "groupName": "all minor dependencies", + "groupSlug": "all-minor-patch", + "matchPackagePatterns": ["*"], + "matchUpdateTypes": ["minor", "patch"], + "bumpVersion": "patch", + "dependencyDashboardApproval": true + }, + { + "groupName": "spring minor dependencies", + "groupSlug": "spring-minor-patch", + "matchPackagePatterns": ["org.springframework.*"], + "matchUpdateTypes": ["minor", "patch"], + "bumpVersion": "patch", + "dependencyDashboardApproval": true + } + ], + "vulnerabilityAlerts": { + "enabled": true, + "addLabels": ["security"], + "bumpVersion": "patch", + "schedule": ["before 5:00am"] + }, + "schedule": ["every weekend"], + "timezone": "Europe/Paris" +} } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/DatacollectionManagementApplication.java b/src/main/java/fr/insee/survey/datacollectionmanagement/DatacollectionManagementApplication.java index 83f55ab1..a52dfaf4 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/DatacollectionManagementApplication.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/DatacollectionManagementApplication.java @@ -5,9 +5,6 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.servers.Server; - @SpringBootApplication public class DatacollectionManagementApplication extends SpringBootServletInitializer { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/ApplicationConfig.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/ApplicationConfig.java index da20d6ff..bbbac362 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/ApplicationConfig.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/ApplicationConfig.java @@ -1,13 +1,11 @@ package fr.insee.survey.datacollectionmanagement.config; -import java.util.List; -import java.util.Optional; - +import lombok.Getter; +import lombok.Setter; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; -import lombok.Getter; -import lombok.Setter; +import java.util.List; @Configuration @Getter @@ -17,10 +15,10 @@ public class ApplicationConfig { //AUTHENTICATION @Value("${jwt.role-claim}") private String roleClaim; + @Value("${jwt.id-claim}") private String idClaim; - @Value("#{'${fr.insee.datacollectionmanagement.roles.admin.role}'.split(',')}") private List roleAdmin; @@ -36,14 +34,18 @@ public class ApplicationConfig { @Value("${fr.insee.datacollectionmanagement.auth.mode}") private String authType; - @Value("${fr.insee.datacollectionmanagement.cors.allowedOrigin}") - private Optional allowedOrigin; + @Value("${fr.insee.datacollectionmanagement.cors.allowedOrigins}") + private String[] allowedOrigins; @Value("${fr.insee.datacollectionmanagement.auth.realm}") private String keycloakRealm; + @Value("${fr.insee.datacollectionmanagement.auth.server-url}") private String keyCloakUrl; @Value("${fr.insee.datacollectionmanagement.api.questioning.url}") private String questioningUrl; + + @Value("#{'${fr.insee.datacollectionmanagement.public.urls}'}") + String[] publicUrls; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/CorsGlobalConfig.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/CorsGlobalConfig.java index d2883454..0c1cf9d2 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/CorsGlobalConfig.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/CorsGlobalConfig.java @@ -1,25 +1,23 @@ package fr.insee.survey.datacollectionmanagement.config; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration -@EnableWebMvc +@RequiredArgsConstructor public class CorsGlobalConfig { - @Autowired - ApplicationConfig applicationConfig; + private final ApplicationConfig applicationConfig; @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { - String ao = applicationConfig.getAllowedOrigin().isPresent() ? applicationConfig.getAllowedOrigin().get() : applicationConfig.getAllowedOrigin().orElse("*"); + String[] ao = applicationConfig.getAllowedOrigins(); registry.addMapping("/**") .allowedOrigins(ao) .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/LogInterceptor.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/LogInterceptor.java index 2c20c9e9..4a8d7a32 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/LogInterceptor.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/LogInterceptor.java @@ -1,36 +1,30 @@ package fr.insee.survey.datacollectionmanagement.config; -import fr.insee.survey.datacollectionmanagement.config.auth.user.User; +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; +import fr.insee.survey.datacollectionmanagement.constants.AuthConstants; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.logging.log4j.ThreadContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.util.UUID; @Component +@Slf4j +@RequiredArgsConstructor public class LogInterceptor implements HandlerInterceptor { - private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class); - - - @Autowired - ApplicationConfig applicationConfig; - - @Autowired - UserProvider userProvider; + private final ApplicationConfig applicationConfig; + private final UserProvider userProvider; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { @@ -42,10 +36,10 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons switch (applicationConfig.getAuthType()) { - case "OIDC": + case AuthConstants.OIDC: Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - User currentUser = userProvider.getUser(authentication); - userId=(currentUser!=null && currentUser.getId()!=null ?currentUser.getId() : "anonymous"); + AuthUser currentAuthUser = userProvider.getUser(authentication); + userId = (currentAuthUser != null && currentAuthUser.getId() != null ? currentAuthUser.getId() : "anonymous"); ThreadContext.put("user", userId.toUpperCase()); break; default: @@ -58,7 +52,7 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons ThreadContext.put("method", method); - logger.info("["+userId.toUpperCase()+"] - ["+method+"] - ["+operationPath+"]"); + log.info("[" + userId.toUpperCase() + "] - [" + method + "] - [" + operationPath + "]"); return true; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/OpenAPIConfiguration.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/OpenAPIConfiguration.java index 89265455..8f907222 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/OpenAPIConfiguration.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/OpenAPIConfiguration.java @@ -1,42 +1,35 @@ package fr.insee.survey.datacollectionmanagement.config; -import java.util.Arrays; - -import org.springframework.beans.factory.annotation.Autowired; +import fr.insee.survey.datacollectionmanagement.constants.AuthConstants; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.*; +import lombok.RequiredArgsConstructor; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.info.BuildProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import io.swagger.v3.oas.models.Components; -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.info.Info; -import io.swagger.v3.oas.models.security.OAuthFlow; -import io.swagger.v3.oas.models.security.OAuthFlows; -import io.swagger.v3.oas.models.security.Scopes; -import io.swagger.v3.oas.models.security.SecurityRequirement; -import io.swagger.v3.oas.models.security.SecurityScheme; -import io.swagger.v3.oas.models.servers.Server; +import java.util.Arrays; @Configuration @ConditionalOnProperty(name = "springdoc.swagger-ui.enabled", havingValue = "true", matchIfMissing = true) - +@RequiredArgsConstructor public class OpenAPIConfiguration { - @Autowired - BuildProperties buildProperties; + private final BuildProperties buildProperties; - @Autowired - ApplicationConfig applicationConfig; + private final ApplicationConfig applicationConfig; @Bean public OpenAPI customOpenAPI() { switch(applicationConfig.getAuthType()) { - case "OIDC": + case AuthConstants.OIDC: OAuthFlows flows = new OAuthFlows(); OAuthFlow flow = new OAuthFlow(); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/PropertyLogger.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/PropertyLogger.java index 8a5222e9..e7e44c8d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/PropertyLogger.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/PropertyLogger.java @@ -1,11 +1,7 @@ package fr.insee.survey.datacollectionmanagement.config; -import java.util.Arrays; -import java.util.stream.StreamSupport; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; import org.springframework.core.env.AbstractEnvironment; @@ -14,11 +10,13 @@ import org.springframework.core.env.MutablePropertySources; import org.springframework.stereotype.Component; +import java.util.Arrays; +import java.util.stream.StreamSupport; + @Component +@Slf4j public class PropertyLogger { - private static final Logger LOGGER = LoggerFactory.getLogger(PropertyLogger.class); - private static boolean alreadyDisplayed=false; @EventListener @@ -28,7 +26,7 @@ public void handleContextRefresh(ContextRefreshedEvent event) { if (!alreadyDisplayed) { - LOGGER.info("================================ Properties ================================"); + log.info("================================ Properties ================================"); final MutablePropertySources sources = ((AbstractEnvironment) env).getPropertySources(); StreamSupport.stream(sources.spliterator(), false) .filter(ps -> ps instanceof EnumerablePropertySource) @@ -39,8 +37,8 @@ public void handleContextRefresh(ContextRefreshedEvent event) { || prop.contains("pw") || prop.contains("Password"))) .filter(prop -> prop.startsWith("fr.insee") || prop.startsWith("logging") || prop.startsWith("jwt") || prop.startsWith("spring")) .sorted() - .forEach(prop -> LOGGER.info("{}: {}", prop, env.getProperty(prop))); - LOGGER.info("==========================================================================="); + .forEach(prop -> log.info("{}: {}", prop, env.getProperty(prop))); + log.info("==========================================================================="); } alreadyDisplayed=true; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/WebConfig.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/WebConfig.java index 87862586..e7489bff 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/WebConfig.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/WebConfig.java @@ -1,13 +1,20 @@ package fr.insee.survey.datacollectionmanagement.config; +import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration +@RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { + private final ApplicationConfig applicationConfig; + + private final UserProvider userProvider; + @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(this.myLogInterceptor()); @@ -16,7 +23,7 @@ public void addInterceptors(InterceptorRegistry registry) { @Bean public LogInterceptor myLogInterceptor() { - return new LogInterceptor(); + return new LogInterceptor(applicationConfig,userProvider); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/DefaultSecurityContext.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/DefaultSecurityContext.java index c257101c..4021787f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/DefaultSecurityContext.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/DefaultSecurityContext.java @@ -1,53 +1,66 @@ package fr.insee.survey.datacollectionmanagement.config.auth.security; -import static org.springframework.security.config.Customizer.withDefaults; - -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import org.springframework.beans.factory.annotation.Autowired; +import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; +import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; +import lombok.AllArgsConstructor; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter; +import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter; -import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; -import fr.insee.survey.datacollectionmanagement.config.auth.user.User; -import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; +import java.util.Collections; @Configuration @EnableWebSecurity -@EnableGlobalMethodSecurity(securedEnabled = false, prePostEnabled = true) +@EnableMethodSecurity @ConditionalOnMissingBean(OpenIDConnectSecurityContext.class) +@AllArgsConstructor public class DefaultSecurityContext { - @Autowired - ApplicationConfig config; + private final PublicSecurityFilterChain publicSecurityFilterChainConfiguration; + private final ApplicationConfig config; + /** + * Configure spring security filter chain when no authentication + * @param http Http Security Object + * @return the spring security filter + * @throws Exception + */ @Bean - protected SecurityFilterChain configure(HttpSecurity http) throws Exception { - http.sessionManagement().disable(); - http.cors(withDefaults()) - .csrf().disable() - .authorizeRequests() - .antMatchers("/csrf", "/", "/webjars/**", "/swagger-resources/**").permitAll() - .antMatchers("/environnement").permitAll()// PublicResources - .antMatchers(Constants.API_HEALTHCHECK).permitAll() - .antMatchers("/actuator/**").permitAll() - .antMatchers("/swagger-ui/*").permitAll() - .antMatchers("/v3/api-docs/swagger-config", "/v3/api-docs").permitAll() - .antMatchers("/openapi.json").permitAll() - .antMatchers(HttpMethod.OPTIONS).permitAll() - .anyRequest().permitAll(); - - return http.build(); + @Order(2) + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + return http + .securityMatcher("/**") + .csrf(csrfConfig -> csrfConfig.disable()) + .cors(Customizer.withDefaults()) + .headers(headers -> headers + .xssProtection(xssConfig -> xssConfig.headerValue(XXssProtectionHeaderWriter.HeaderValue.DISABLED)) + .contentSecurityPolicy(cspConfig -> cspConfig + .policyDirectives("default-src 'none'") + ) + .referrerPolicy(referrerPolicy -> + referrerPolicy + .policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.SAME_ORIGIN) + )) + .authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()) + .build(); } - + @Bean + @Order(1) + SecurityFilterChain filterPublicUrlsChain(HttpSecurity http) throws Exception { + return publicSecurityFilterChainConfiguration.buildSecurityPublicFilterChain(http, config.getPublicUrls()); } @Bean public UserProvider getUserProvider() { - return auth -> new User(); + return auth -> new AuthUser("anonymous", Collections.emptyList()); } + } \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/GrantedAuthorityConverter.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/GrantedAuthorityConverter.java new file mode 100644 index 00000000..87e2b6ff --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/GrantedAuthorityConverter.java @@ -0,0 +1,39 @@ +package fr.insee.survey.datacollectionmanagement.config.auth.security; + +import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; +import lombok.AllArgsConstructor; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.jwt.Jwt; + +import java.util.*; +import java.util.stream.Collectors; + +@AllArgsConstructor +public class GrantedAuthorityConverter implements Converter> { + + ApplicationConfig applicationConfig; + + @Override + public Collection convert(Jwt jwt) { + Map claims = jwt.getClaims(); + List roles = (List) claims.get(applicationConfig.getRoleClaim()); + List authorizedRoles = new ArrayList<>(); + authorizedRoles.addAll(applicationConfig.getRoleAdmin()); + authorizedRoles.addAll(applicationConfig.getRoleRespondent()); + authorizedRoles.addAll(applicationConfig.getRoleInternalUser()); + authorizedRoles.addAll(applicationConfig.getRoleWebClient()); + + return roles.stream() + .map(role -> { + if (authorizedRoles.contains(role)) { + return new SimpleGrantedAuthority(role); + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toCollection(ArrayList::new)); + } +} + diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/OpenIDConnectSecurityContext.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/OpenIDConnectSecurityContext.java index d6463477..491d772d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/OpenIDConnectSecurityContext.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/OpenIDConnectSecurityContext.java @@ -1,69 +1,111 @@ package fr.insee.survey.datacollectionmanagement.config.auth.security; -import static org.springframework.security.config.Customizer.withDefaults; - -import java.util.List; - +import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; +import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; +import fr.insee.survey.datacollectionmanagement.constants.AuthConstants; import fr.insee.survey.datacollectionmanagement.constants.Constants; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.core.convert.converter.Converter; import org.springframework.http.HttpMethod; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter; +import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter; -import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; -import fr.insee.survey.datacollectionmanagement.config.auth.user.User; -import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; -import lombok.extern.slf4j.Slf4j; +import java.util.Collection; +import java.util.List; @Configuration @EnableWebSecurity -@EnableGlobalMethodSecurity(securedEnabled=true, prePostEnabled = true) -@ConditionalOnProperty(name = "fr.insee.datacollectionmanagement.auth.mode", havingValue = "OIDC") +@EnableMethodSecurity +@ConditionalOnProperty(name = "fr.insee.datacollectionmanagement.auth.mode", havingValue = AuthConstants.OIDC) @Slf4j -public class OpenIDConnectSecurityContext { +@RequiredArgsConstructor +public class OpenIDConnectSecurityContext { + + private final PublicSecurityFilterChain publicSecurityFilterChainConfiguration; - @Autowired - ApplicationConfig config; + private final ApplicationConfig config; @Bean + @Order(2) protected SecurityFilterChain configure(HttpSecurity http) throws Exception { - http.sessionManagement().disable(); - - http.cors(withDefaults()) - .csrf().disable() - .authorizeRequests() - .antMatchers("/csrf", "/", "/webjars/**", "/swagger-resources/**").permitAll() - .antMatchers("/environnement").permitAll()//PublicResources - .antMatchers(Constants.API_HEALTHCHECK).permitAll() - .antMatchers("/actuator/**").permitAll() - .antMatchers("/swagger-ui/*").permitAll() - .antMatchers("/v3/api-docs/swagger-config", "/v3/api-docs").permitAll() - .antMatchers("/openapi.json").permitAll() - .antMatchers(HttpMethod.OPTIONS).permitAll() - .anyRequest().authenticated() - .and() - .oauth2ResourceServer() - .jwt(); - return http.build(); + return http + .securityMatcher("/**") + .csrf(AbstractHttpConfigurer::disable) + .cors(Customizer.withDefaults()) + .headers(headers -> headers + .xssProtection(xssConfig -> xssConfig.headerValue(XXssProtectionHeaderWriter.HeaderValue.DISABLED)) + .contentSecurityPolicy(cspConfig -> cspConfig + .policyDirectives("default-src 'none'") + ) + .referrerPolicy(referrerPolicy -> + referrerPolicy + .policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.SAME_ORIGIN) + )) + .authorizeHttpRequests(configurer -> configurer + .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() + .requestMatchers(HttpMethod.GET, Constants.API_HEALTHCHECK).permitAll() + // actuator (actuator metrics are disabled by default) + .requestMatchers(HttpMethod.GET, Constants.ACTUATOR).permitAll() + .anyRequest() + .authenticated() + ) + .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .oauth2ResourceServer(oauth2 -> oauth2 + .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter(config))) + ) + .build(); } + + @Bean + @Order(1) + SecurityFilterChain filterPublicUrlsChain(HttpSecurity http) throws Exception { + String tokenUrl = config.getKeyCloakUrl() + "/realms/" + config.getKeycloakRealm() + "/protocol/openid-connect/token"; + String authorizedConnectionHost = config.getAuthType().equals(AuthConstants.OIDC) ? + " " + tokenUrl : ""; + return publicSecurityFilterChainConfiguration.buildSecurityPublicFilterChain(http, config.getPublicUrls(), authorizedConnectionHost); } + @Bean public UserProvider getUserProvider() { return auth -> { - if ("anonymousUser".equals(auth.getPrincipal())) return null; //init request, or request without authentication + if ("anonymousUser".equals(auth.getPrincipal())) + return null; //init request, or request without authentication final Jwt jwt = (Jwt) auth.getPrincipal(); List tryRoles = jwt.getClaimAsStringList(config.getRoleClaim()); - String tryId=jwt.getClaimAsString(config.getIdClaim()); - return new User(tryId, tryRoles); + String tryId = jwt.getClaimAsString(config.getIdClaim()); + return new AuthUser(tryId, tryRoles); }; } + @Bean + JwtAuthenticationConverter jwtAuthenticationConverter(ApplicationConfig applicationConfig) { + JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter(); + jwtAuthenticationConverter.setPrincipalClaimName("preferred_username"); + jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter(applicationConfig)); + return jwtAuthenticationConverter; + } + + Converter> jwtGrantedAuthoritiesConverter(ApplicationConfig applicationConfig) { + return new GrantedAuthorityConverter(applicationConfig); + } + + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/PublicSecurityFilterChain.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/PublicSecurityFilterChain.java new file mode 100644 index 00000000..048a7e54 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/security/PublicSecurityFilterChain.java @@ -0,0 +1,47 @@ +package fr.insee.survey.datacollectionmanagement.config.auth.security; + +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.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter; +import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter; + +@Configuration +public class PublicSecurityFilterChain { + + + SecurityFilterChain buildSecurityPublicFilterChain(HttpSecurity http, String[] publicUrls) throws Exception { + return buildSecurityPublicFilterChain(http, publicUrls, ""); + } + + SecurityFilterChain buildSecurityPublicFilterChain(HttpSecurity http, String[] publicUrls, String authorizedConnectionHost) throws Exception { + return http + .securityMatcher(publicUrls) + .cors(Customizer.withDefaults()) + .headers(headers -> headers + .xssProtection(xssConfig -> xssConfig.headerValue(XXssProtectionHeaderWriter.HeaderValue.DISABLED)) + .contentSecurityPolicy(cspConfig -> cspConfig + .policyDirectives("default-src 'none'; " + + "connect-src 'self' " + authorizedConnectionHost + "; " + + "img-src 'self' data:; " + + "style-src 'self'; " + + "script-src 'self' 'unsafe-inline'") + ) + .referrerPolicy(referrerPolicy -> + referrerPolicy + .policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.SAME_ORIGIN) + )) + .authorizeHttpRequests(auth -> auth + .requestMatchers(HttpMethod.OPTIONS).permitAll() + .requestMatchers(publicUrls).permitAll() + .anyRequest() + .authenticated() + ) + .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .build(); + } + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/AuthUser.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/AuthUser.java new file mode 100644 index 00000000..8190fba2 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/AuthUser.java @@ -0,0 +1,19 @@ +package fr.insee.survey.datacollectionmanagement.config.auth.user; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@RequiredArgsConstructor +public class AuthUser { + + private final String id; + + private final List roles; + + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/AuthorizeMethodDecider.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/AuthorizeMethodDecider.java index 7b011eda..4b0ce74d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/AuthorizeMethodDecider.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/AuthorizeMethodDecider.java @@ -1,101 +1,97 @@ package fr.insee.survey.datacollectionmanagement.config.auth.user; -import org.json.JSONArray; -import org.json.JSONException; -import org.springframework.beans.factory.annotation.Autowired; +import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; +import fr.insee.survey.datacollectionmanagement.constants.AuthConstants; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; -import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; -import lombok.extern.slf4j.Slf4j; - +import java.util.ArrayList; import java.util.List; @Component("AuthorizeMethodDecider") @Slf4j +@RequiredArgsConstructor public class AuthorizeMethodDecider { - private User noAuthUser; + public static final String ROLE_OFFLINE_ACCESS = "ROLE_offline_access"; + public static final String ROLE_UMA_AUTHORIZATION = "ROLE_uma_authorization"; + private AuthUser noAuthUser; + + private final UserProvider userProvider; - @Autowired - private UserProvider userProvider; + private final ApplicationConfig config; - @Autowired - ApplicationConfig config; - public User getUser() { - if (config.getAuthType().equals("OIDC")) { + public AuthUser getUser() { + if (config.getAuthType().equals(AuthConstants.OIDC)) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - User currentUser = userProvider.getUser(authentication); - return currentUser; + AuthUser currentAuthUser = userProvider.getUser(authentication); + return currentAuthUser; } return noAuthUser(); } - private User noAuthUser() { + private AuthUser noAuthUser() { if (this.noAuthUser != null) { return this.noAuthUser; } - JSONArray roles = new JSONArray(); - roles.put("ROLE_offline_access"); - roles.put(config.getRoleAdmin().get(0)); - roles.put("ROLE_uma_authorization"); - return new User("GUEST", roles); + List roles = new ArrayList<>(); + roles.add(ROLE_OFFLINE_ACCESS); + roles.add(config.getRoleAdmin().get(0)); + roles.add(ROLE_UMA_AUTHORIZATION); + return new AuthUser("GUEST", roles); } - public boolean isInternalUser() throws JSONException { - User user = getUser(); - return isInternalUser(user); + public boolean isInternalUser() { + AuthUser authUser = getUser(); + return isInternalUser(authUser); } - public boolean isInternalUser(User user) throws JSONException { - return (hasRole(user, config.getRoleInternalUser())); + public boolean isInternalUser(AuthUser authUser) { + return (hasRole(authUser, config.getRoleInternalUser())); } - public boolean isAdmin() throws JSONException { - User user = getUser(); - return isAdmin(user); + public boolean isAdmin() { + AuthUser authUser = getUser(); + return isAdmin(authUser); } - public boolean isAdmin(User user) throws JSONException { - return (hasRole(user, config.getRoleAdmin())); + public boolean isAdmin(AuthUser authUser) { + return (hasRole(authUser, config.getRoleAdmin())); } - public boolean isWebClient() throws JSONException { - User user = getUser(); - return isWebClient(user); + public boolean isWebClient() { + AuthUser authUser = getUser(); + return isWebClient(authUser); } - public boolean isWebClient(User user) throws JSONException { - return hasRole(user, config.getRoleWebClient()); + public boolean isWebClient(AuthUser authUser) { + return hasRole(authUser, config.getRoleWebClient()); } - public boolean isRespondent() throws JSONException { - User user = getUser(); - return isRespondent(user); + public boolean isRespondent() { + AuthUser authUser = getUser(); + return isRespondent(authUser); } - public boolean isRespondent(User user) throws JSONException { - return hasRole(user, config.getRoleRespondent()); + public boolean isRespondent(AuthUser authUser) { + + return hasRole(authUser, config.getRoleRespondent()); } - private boolean hasRole(User user, List role) throws JSONException { + private boolean hasRole(AuthUser authUser, List authorizedRoles) { Boolean hasRole = false; - JSONArray roles = user.getRoles(); - for (int i = 0; i < roles.length(); i++) { - if (role.contains(roles.getString(i))) { - hasRole = true; - log.info("role :"+roles.getString(i)+" has been found"); - } - } - return hasRole; + List userRoles = authUser.getRoles(); + return userRoles.stream().anyMatch(authorizedRoles::contains); } - public String getUsername() throws JSONException { - User user = getUser(); - return user.getId().toUpperCase(); + public String getUsername() { + AuthUser authUser = getUser(); + return authUser.getId().toUpperCase(); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/User.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/User.java deleted file mode 100644 index 4752b661..00000000 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/User.java +++ /dev/null @@ -1,50 +0,0 @@ -package fr.insee.survey.datacollectionmanagement.config.auth.user; - -import java.util.Collection; -import java.util.List; - -import org.json.JSONArray; -import org.springframework.security.core.GrantedAuthority; - -public class User { - - private JSONArray roles; - private String id; - - private Collection authorities; - - public User() { - super(); - } - - public User(String id, JSONArray roles) { - this.id=id; - this.roles = roles; - } - - public User(String id, List roles) { - this.id=id; - this.roles = new JSONArray(roles); - } - - public JSONArray getRoles() { - return roles; - } - public void setRoles(JSONArray roles) { - this.roles = roles; - } - - public Collection getAuthorities() { - return authorities; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - -} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/UserProvider.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/UserProvider.java index b67ba536..75017cf6 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/UserProvider.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/UserProvider.java @@ -5,6 +5,6 @@ @FunctionalInterface public interface UserProvider { - User getUser(Authentication authentication); + AuthUser getUser(Authentication authentication); } \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/UserToMdcFilter.java b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/UserToMdcFilter.java new file mode 100644 index 00000000..c3d5cb03 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/config/auth/user/UserToMdcFilter.java @@ -0,0 +1,37 @@ +package fr.insee.survey.datacollectionmanagement.config.auth.user; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.slf4j.MDC; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@RequiredArgsConstructor +public class UserToMdcFilter extends OncePerRequestFilter { + + private static final String USER = "user"; + + private final UserProvider userProvider; + + @Override + protected void doFilterInternal( + HttpServletRequest request, HttpServletResponse response, FilterChain filterChain + ) throws ServletException, IOException { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + AuthUser currentAuthUser = userProvider.getUser(authentication); + String userId = (currentAuthUser != null && currentAuthUser.getId() != null ? currentAuthUser.getId() : "anonymous"); + MDC.put(USER, userId); + try { + filterChain.doFilter(request, response); + } finally { + MDC.remove(USER); + } + } + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/constants/AuthConstants.java b/src/main/java/fr/insee/survey/datacollectionmanagement/constants/AuthConstants.java new file mode 100644 index 00000000..14246eb9 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/constants/AuthConstants.java @@ -0,0 +1,6 @@ +package fr.insee.survey.datacollectionmanagement.constants; + +public class AuthConstants { + + public static final String OIDC = "OIDC"; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/constants/CheckHabilitationsRoles.java b/src/main/java/fr/insee/survey/datacollectionmanagement/constants/CheckHabilitationsRoles.java new file mode 100644 index 00000000..365f581e --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/constants/CheckHabilitationsRoles.java @@ -0,0 +1,6 @@ +package fr.insee.survey.datacollectionmanagement.constants; + +public class CheckHabilitationsRoles { + public static final String INTERVIEWER = "interviewer"; + public static final String REVIEWER = "reviewer"; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/constants/Constants.java b/src/main/java/fr/insee/survey/datacollectionmanagement/constants/Constants.java index 0d022440..7053e06b 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/constants/Constants.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/constants/Constants.java @@ -10,8 +10,6 @@ private Constants() { public static final String API_CONTACTS = "/api/contacts/"; public static final String API_CONTACTS_ALL = "/api/contacts"; public static final String API_CONTACTS_ID = "/api/contacts/{id}"; - public static final String ADDRESS = "/api/address"; - public static final String CONTACT_EVENTS = "/api/contact-events"; public static final String API_CONTACTS_ID_ADDRESS = "/api/contacts/{id}/address"; public static final String API_CONTACTS_ID_CONTACTEVENTS = "/api/contacts/{id}/contact-events"; public static final String API_CONTACTEVENTS = "/api/contacts/contact-events"; @@ -20,6 +18,8 @@ private Constants() { // API USER DOMAIN public static final String API_USERS_ALL = "/api/users"; + + public static final String API_USERS_ALL_NO_PAGINATION ="/api/users/v2" ; public static final String API_USERS_ID = "/api/users/{id}"; public static final String API_USERS_ID_USEREVENTS = "/api/users/{id}/user-events"; public static final String API_USEREVENTS = "/api/users/contact-events"; @@ -33,7 +33,6 @@ private Constants() { public static final String API_SURVEY_UNITS ="/api/survey-units"; public static final String API_SURVEY_UNITS_ID = "/api/survey-units/{id}"; public static final String API_SURVEY_UNITS_ID_QUESTIONINGS = "/api/survey-units/{id}/questionings"; - public static final String API_QUESTIONING_ACCREDITATIONS = "/api/questioning-accreditations"; public static final String API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS = "/api/questionings/{id}/questioning-accreditations"; public static final String API_QUESTIONING_QUESTIONING_EVENTS = "/api/questionings/questioning-events"; public static final String API_QUESTIONING_ID_QUESTIONING_EVENTS = "/api/questionings/{id}/questioning-events"; @@ -45,22 +44,25 @@ private Constants() { public static final String API_SOURCES = "/api/sources"; public static final String API_SOURCES_ID = "/api/sources/{id}"; public static final String API_SOURCES_ID_SURVEYS = "/api/sources/{id}/surveys"; + public static final String API_SURVEYS = "/api/surveys"; + + public static final String API_SURVEYS_SEARCH = "/api/surveys/search"; public static final String API_SURVEYS_ID = "/api/surveys/{id}"; public static final String API_SURVEYS_ID_CAMPAIGNS = "/api/surveys/{id}/campaigns"; + + public static final String API_SURVEYS_ID_CAMPAIGNS_PARTITIONINGS = "/api/surveys/{id}/campaigns-partitionings"; public static final String API_CAMPAIGNS = "/api/campaigns"; public static final String API_CAMPAIGNS_ID = "/api/campaigns/{id}"; public static final String CAMPAIGNS_ID_ONGOING = "/campaigns/{id}/ongoing"; public static final String API_CAMPAIGNS_ID_PARTITIONINGS = "/api/campaigns/{id}/partitionings"; - public static final String API_PARTITIONINGS = "/api/partitionings"; public static final String API_PARTITIONINGS_ID = "/api/partitionings/{id}"; - public static final String API_METADATA_ID = "/api/metadata/{id}"; public static final String API_OWNERS = "/api/owners"; public static final String API_OWNERS_ID = "/api/owners/{id}"; public static final String API_OWNERS_ID_SOURCES = "/api/owners/{id}/sources"; public static final String API_SUPPORTS = "/api/supports"; public static final String API_SUPPORTS_ID = "/api/supports/{id}"; public static final String API_PERIODICITIES = "/api/periodicities"; - public static final String API_PERIODICITIES_ID_PERIODS = "/api/periodicities/{id}/periods"; + public static final String API_PERIODICITIES_ID_PERIODS = "/api/periodicities/{periodicity}/periods"; public static final String API_PERIODS = "/api/periods"; @@ -84,20 +86,22 @@ private Constants() { public static final String API_CONTACTS_SEARCH = "/api/contacts/search"; public static final String API_CONTACTS_ACCREDITATIONS = "/api/contacts/{id}/accreditations"; public static final String API_MY_QUESTIONINGS_ID = "/api/contacts/questionings"; - + public static final String API_SURVEY_UNITS_CONTACTS = "/api/survey-units/{id}/contacts"; + public static final String API_SURVEY_UNITS_PARTITIONINGS = "/api/survey-units/{id}/partitionings"; + + public static final String API_SURVEY_UNITS_SEARCH = "/api/survey-units/search"; + + + + // API WEBCLIENT public static final String API_WEBCLIENT_FOLLOWUP = "/api/partitionings/{idPartitioning}/survey-units/{idSu}/follow-up"; public static final String API_WEBCLIENT_EXTRACT = "/api/partitionings/{idPartitioning}/survey-units/{idSu}/extract"; public static final String API_WEBCLIENT_STATE = "/api/partitionings/{idPartitioning}/survey-units/{idSu}/state"; - public static final String API_WEBCLIENT_METADATA = "/api/metadata"; public static final String API_WEBCLIENT_METADATA_ID = "/api/metadata/{id}"; public static final String API_WEBCLIENT_QUESTIONINGS = "/api/questionings"; - // CHECK HABILITATION ROLES - - public static final String INTERVIEWER = "interviewer"; - public static final String REVIEWER = "reviewer"; - public static final String API_HEALTHCHECK = "/api/healthcheck"; + public static final String ACTUATOR = "/actuator/**"; } \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/AddressController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/AddressController.java index d1e7db74..c8801cfa 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/AddressController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/AddressController.java @@ -1,86 +1,65 @@ package fr.insee.survey.datacollectionmanagement.contact.controller; -import java.util.List; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; +import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.contact.domain.Address; import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; import fr.insee.survey.datacollectionmanagement.contact.dto.AddressDto; -import fr.insee.survey.datacollectionmanagement.contact.dto.ContactDto; import fr.insee.survey.datacollectionmanagement.contact.service.AddressService; import fr.insee.survey.datacollectionmanagement.contact.service.ContactEventService; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; +import fr.insee.survey.datacollectionmanagement.contact.util.PayloadUtil; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.List; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "1 - Contacts", description = "Enpoints to create, update, delete and find contacts") +@Slf4j +@RequiredArgsConstructor public class AddressController { - static final Logger LOGGER = LoggerFactory.getLogger(AddressController.class); + private final AddressService addressService; + + private final ContactService contactService; - @Autowired - private AddressService addressService; + private final ContactEventService contactEventService; - @Autowired - private ContactService contactService; + private final UserProvider userProvider; - @Autowired - private ContactEventService contactEventService; @Operation(summary = "Search for a contact address by the contact id") @GetMapping(value = Constants.API_CONTACTS_ID_ADDRESS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AddressDto.class))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "500", description = "Internal servor error") - }) @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| (@AuthorizeMethodDecider.isRespondent() && (#id == @AuthorizeMethodDecider.getUsername()))" + "|| @AuthorizeMethodDecider.isAdmin() ") - public ResponseEntity getContactAddress(@PathVariable("id") String id) { - try { - Optional contact = contactService.findByIdentifier(id); - if (contact.isPresent()) { - if (contact.get().getAddress() != null) - return ResponseEntity.status(HttpStatus.OK) - .body(addressService.convertToDto(contact.get().getAddress())); - else { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Address does not exist"); - } - } else { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact does not exist"); - } - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error"); - } + public ResponseEntity getContactAddress(@PathVariable("id") String id) { + Contact contact = contactService.findByIdentifier(id); + if (contact.getAddress() != null) + return ResponseEntity.status(HttpStatus.OK) + .body(addressService.convertToDto(contact.getAddress())); + else throw new NotFoundException(String.format("No address found for contact %s", id)); + } @@ -90,43 +69,34 @@ public ResponseEntity getContactAddress(@PathVariable("id") String id) { + "|| @AuthorizeMethodDecider.isWebClient() " + "|| (@AuthorizeMethodDecider.isRespondent() && (#id == @AuthorizeMethodDecider.getUsername()))" + "|| @AuthorizeMethodDecider.isAdmin() ") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AddressDto.class))), - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = ContactDto.class))), - @ApiResponse(responseCode = "404", description = "Not found") - }) - public ResponseEntity putAddress(@PathVariable("id") String id, @RequestBody AddressDto addressDto) { - Optional optContact = contactService.findByIdentifier(id); - if (optContact.isPresent()) { - HttpStatus httpStatus; - Address addressUpdate; - Contact contact = optContact.get(); - Address address = addressService.convertToEntity(addressDto); - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.set(HttpHeaders.LOCATION, ServletUriComponentsBuilder.fromCurrentRequest().toUriString()); - - if (contact.getAddress() != null) { - LOGGER.info("Update address for the contact {} ", id); - address.setId(contact.getAddress().getId()); - addressUpdate = addressService.saveAddress(address); - httpStatus = HttpStatus.OK; - } else { - LOGGER.info("Create address for the contact {} ", id); - addressUpdate = addressService.saveAddress(address); - contact.setAddress(addressUpdate); - contactService.saveContact(contact); - httpStatus = HttpStatus.CREATED; - } - - ContactEvent contactEventUpdate = contactEventService.createContactEvent(contact, ContactEventType.update, - null); - contactEventService.saveContactEvent(contactEventUpdate); - return ResponseEntity.status(httpStatus).headers(responseHeaders) - .body(addressService.convertToDto(addressUpdate)); - + public ResponseEntity putAddress(@PathVariable("id") String id, @RequestBody AddressDto addressDto, Authentication auth) { + Contact contact = contactService.findByIdentifier(id); + HttpStatus httpStatus; + Address addressUpdate; + Address address = addressService.convertToEntity(addressDto); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set(HttpHeaders.LOCATION, ServletUriComponentsBuilder.fromCurrentRequest().toUriString()); + + if (contact.getAddress() != null) { + log.info("Update address for the contact {} ", id); + address.setId(contact.getAddress().getId()); + addressUpdate = addressService.saveAddress(address); + httpStatus = HttpStatus.OK; } else { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact does not exist"); + log.info("Create address for the contact {} ", id); + addressUpdate = addressService.saveAddress(address); + contact.setAddress(addressUpdate); + contactService.saveContact(contact); + httpStatus = HttpStatus.CREATED; } + AuthUser authUser = userProvider.getUser(auth); + PayloadUtil.getPayloadAuthor(authUser.getId()); + ContactEvent contactEventUpdate = contactEventService.createContactEvent(contact, ContactEventType.update, + null); + contactEventService.saveContactEvent(contactEventUpdate); + return ResponseEntity.status(httpStatus).headers(responseHeaders) + .body(addressService.convertToDto(addressUpdate)); + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/ContactController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/ContactController.java index 6fbb359b..39f7f508 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/ContactController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/ContactController.java @@ -1,235 +1,177 @@ package fr.insee.survey.datacollectionmanagement.contact.controller; -import java.text.ParseException; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.modelmapper.ModelMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; +import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact.Gender; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; import fr.insee.survey.datacollectionmanagement.contact.dto.ContactDto; import fr.insee.survey.datacollectionmanagement.contact.dto.ContactFirstLoginDto; import fr.insee.survey.datacollectionmanagement.contact.service.AddressService; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; +import fr.insee.survey.datacollectionmanagement.contact.util.PayloadUtil; +import fr.insee.survey.datacollectionmanagement.exception.ImpossibleToDeleteException; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningAccreditationService; -import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import fr.insee.survey.datacollectionmanagement.view.service.ViewService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.io.Serial; +import java.util.List; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") -@Tag(name = "1 - Contacts", description = "Enpoints to create, update, delete and find contacts") +@Tag(name = "1 - Contacts", description = "Endpoints to create, update, delete and find contacts") @Slf4j +@RequiredArgsConstructor +@Validated public class ContactController { - static final Logger LOGGER = LoggerFactory.getLogger(ContactController.class); + private final ContactService contactService; - @Autowired - private ContactService contactService; + private final AddressService addressService; - @Autowired - private AddressService addressService; + private final ViewService viewService; - @Autowired - private ViewService viewService; + private final QuestioningAccreditationService questioningAccreditationService; - @Autowired - private QuestioningService questioningService; + private final ModelMapper modelMapper; - @Autowired - private QuestioningAccreditationService questioningAccreditationService; + private final UserProvider userProvider; - @Autowired - private ModelMapper modelMapper; @Operation(summary = "Search for contacts, paginated") @GetMapping(value = Constants.API_CONTACTS_ALL, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ContactPage.class))) - }) - public ResponseEntity getContacts( + public ResponseEntity getContacts( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "identifier") String sort) { Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); Page pageC = contactService.findAll(pageable); - List listC = pageC.stream().map(c -> convertToDto(c)).collect(Collectors.toList()); + List listC = pageC.stream().map(this::convertToDto).toList(); return ResponseEntity.ok().body(new ContactPage(listC, pageable, pageC.getTotalElements())); } @Operation(summary = "Search for a contact by its id") - @GetMapping(value = Constants.API_CONTACTS_ID, produces = "application/json") + @GetMapping(value = Constants.API_CONTACTS_ID) @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| (@AuthorizeMethodDecider.isRespondent() && (#id == @AuthorizeMethodDecider.getUsername()))" + "|| @AuthorizeMethodDecider.isAdmin() ") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ContactFirstLoginDto.class))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad Request") - }) - public ResponseEntity getContact(@PathVariable("id") String id) { - Optional contact = contactService.findByIdentifier(StringUtils.upperCase(id)); - try { - if (contact.isPresent()) - return ResponseEntity.ok().body(convertToFirstLoginDto(contact.get())); - else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact does not exist"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity getContact(@PathVariable("id") String id) { + Contact contact = contactService.findByIdentifier(StringUtils.upperCase(id)); + return ResponseEntity.ok().body(convertToFirstLoginDto(contact)); + } + @Operation(summary = "Update or create a contact") @PutMapping(value = Constants.API_CONTACTS_ID, produces = "application/json", consumes = "application/json") @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| (@AuthorizeMethodDecider.isRespondent() && (#id == @AuthorizeMethodDecider.getUsername()))" + "|| @AuthorizeMethodDecider.isAdmin() ") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ContactDto.class))), - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = ContactDto.class))), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity putContact(@PathVariable("id") String id, @RequestBody ContactDto contactDto) { - if (StringUtils.isBlank(contactDto.getIdentifier()) || !contactDto.getIdentifier().equalsIgnoreCase(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and contact identifier don't match"); + public ResponseEntity putContact(@PathVariable("id") String id, @RequestBody @Valid ContactDto contactDto, Authentication auth) throws JsonProcessingException { + if (!contactDto.getIdentifier().equalsIgnoreCase(id)) { + throw new NotMatchException("id and contact identifier don't match"); } Contact contact; HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set(HttpHeaders.LOCATION, ServletUriComponentsBuilder.fromCurrentRequest() .buildAndExpand(contactDto.getIdentifier()).toUriString()); + AuthUser authUser = userProvider.getUser(auth); + + JsonNode payload = PayloadUtil.getPayloadAuthor(authUser.getId()); try { contact = convertToEntity(contactDto); - } catch (ParseException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Impossible to parse contact"); - } catch (NoSuchElementException e) { - LOGGER.info("Creating contact with the identifier {}", contactDto.getIdentifier()); + if (contactDto.getAddress() != null) + contact.setAddress(addressService.convertToEntity(contactDto.getAddress())); + Contact contactUpdate = contactService.updateContactAddressEvent(contact, payload); + return ResponseEntity.ok().headers(responseHeaders).body(convertToDto(contactUpdate)); + } catch (NotFoundException e) { + log.info("Creating contact with the identifier {}", contactDto.getIdentifier()); contact = convertToEntityNewContact(contactDto); if (contactDto.getAddress() != null) contact.setAddress(addressService.convertToEntity(contactDto.getAddress())); - Contact contactCreate = contactService.createContactAddressEvent(contact, null); + Contact contactCreate = contactService.createContactAddressEvent(contact, payload); viewService.createView(id, null, null); return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders).body(convertToDto(contactCreate)); - } - if (contactDto.getAddress() != null) - contact.setAddress(addressService.convertToEntity(contactDto.getAddress())); - Contact contactUpdate = contactService.updateContactAddressEvent(contact, null); - return ResponseEntity.ok().headers(responseHeaders).body(convertToDto(contactUpdate)); + } - @Operation(summary = "Delete a contact, its address, its contactEvents and its accreditations") + + @Operation(summary = "Delete a contact, its address, its contactEvents") @DeleteMapping(value = Constants.API_CONTACTS_ID) - @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "No Content"), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad Request") - }) - @Transactional - public ResponseEntity deleteContact(@PathVariable("id") String id) { - try { - Optional contact = contactService.findByIdentifier(id); - if (contact.isPresent()) { - contactService.deleteContactAddressEvent(contact.get()); - - viewService.findViewByIdentifier(id).stream().forEach(c -> viewService.deleteView(c)); - questioningAccreditationService.findByContactIdentifier(id).stream().forEach(acc -> { - Questioning questioning = questioningService.findbyId(acc.getQuestioning().getId()).get(); - Set newSet = questioning.getQuestioningAccreditations(); - newSet.removeIf(a -> a.getId().equals(acc.getId())); - questioning.setQuestioningAccreditations(newSet); - questioningService.saveQuestioning(questioning); - questioningAccreditationService.deleteAccreditation(acc); - - }); - log.info("Delete contact {}", id); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Contact deleted"); - } else { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact does not exist"); - } - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteContact(@PathVariable("id") String id) { + + if (!questioningAccreditationService.findByContactIdentifier(id).isEmpty()) { + throw new ImpossibleToDeleteException( + String.format("Contact %s cannot be deleted as he/she is still entitled to answer one or more questionnaires", id)); } + + log.info("Delete contact {}", id); + Contact contact = contactService.findByIdentifier(id); + contactService.deleteContactAddressEvent(contact); + } private ContactDto convertToDto(Contact contact) { ContactDto contactDto = modelMapper.map(contact, ContactDto.class); - contactDto.setCivility(contact.getGender()); + contactDto.setCivility(contact.getGender().name()); return contactDto; } private ContactFirstLoginDto convertToFirstLoginDto(Contact contact) { ContactFirstLoginDto contactFirstLoginDto = modelMapper.map(contact, ContactFirstLoginDto.class); contactFirstLoginDto.setCivility(contact.getGender()); - contactFirstLoginDto.setFirstConnect(contact.getContactEvents().stream() - .filter(e -> e.getType().equals(ContactEventType.firstConnect)).collect(Collectors.toList()).isEmpty()); + contactFirstLoginDto.setFirstConnect(contact.getContactEvents().stream().noneMatch(e -> e.getType().equals(ContactEventType.firstConnect))); return contactFirstLoginDto; } - private Contact convertToEntity(ContactDto contactDto) throws ParseException, NoSuchElementException { + private Contact convertToEntity(ContactDto contactDto) { Contact contact = modelMapper.map(contactDto, Contact.class); - contact.setGender(contactDto.getCivility()); - Optional oldContact = contactService.findByIdentifier(contactDto.getIdentifier()); - if (!oldContact.isPresent()) { - throw new NoSuchElementException(); - } - contact.setComment(oldContact.get().getComment()); - contact.setAddress(oldContact.get().getAddress()); - contact.setContactEvents(oldContact.get().getContactEvents()); + contact.setGender(Contact.Gender.valueOf(contactDto.getCivility())); + Contact oldContact = contactService.findByIdentifier(contactDto.getIdentifier()); + contact.setComment(oldContact.getComment()); + contact.setAddress(oldContact.getAddress()); + contact.setContactEvents(oldContact.getContactEvents()); return contact; } private Contact convertToEntityNewContact(ContactDto contactDto) { Contact contact = modelMapper.map(contactDto, Contact.class); - contact.setGender(contactDto.getCivility()); - return contact; + contact.setGender(Contact.Gender.valueOf(contactDto.getCivility())); + return contact; } - class ContactPage extends PageImpl { + static class ContactPage extends PageImpl { + @Serial private static final long serialVersionUID = 656181199902518234L; public ContactPage(List content, Pageable pageable, long total) { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/ContactEventController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/ContactEventController.java index bd2431ed..c29e88bc 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/ContactEventController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/controller/ContactEventController.java @@ -1,145 +1,87 @@ package fr.insee.survey.datacollectionmanagement.contact.controller; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; - +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; +import fr.insee.survey.datacollectionmanagement.contact.dto.ContactEventDto; +import fr.insee.survey.datacollectionmanagement.contact.service.ContactEventService; +import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import org.modelmapper.ModelMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; -import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; -import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; -import fr.insee.survey.datacollectionmanagement.contact.dto.ContactEventDto; -import fr.insee.survey.datacollectionmanagement.contact.service.ContactEventService; -import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; -import fr.insee.survey.datacollectionmanagement.exception.EventException; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; @RestController(value = "contactEvents") @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " - + "|| @AuthorizeMethodDecider.isWebClient() "+ "|| @AuthorizeMethodDecider.isRespondent() " + + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isRespondent() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "1 - Contacts", description = "Enpoints to create, update, delete and find contacts") +@RequiredArgsConstructor +@Validated public class ContactEventController { - static final Logger LOGGER = LoggerFactory.getLogger(ContactEventController.class); + private final ContactEventService contactEventService; - @Autowired - private ContactEventService contactEventService; + private final ContactService contactService; - @Autowired - private ContactService contactService; - - @Autowired - private ModelMapper modelMapper; + private final ModelMapper modelMapper; @Operation(summary = "Search for contactEvents by the contact id") @GetMapping(value = Constants.API_CONTACTS_ID_CONTACTEVENTS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ContactEventDto.class)))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Internal servor error") - }) - public ResponseEntity getContactContactEvents(@PathVariable("id") String identifier) { - try { - - Optional optContact = contactService.findByIdentifier(identifier); - if (optContact.isPresent()) { - return ResponseEntity.status(HttpStatus.OK) - .body(optContact.get().getContactEvents().stream().map(ce -> convertToDto(ce)) - .collect(Collectors.toList())); - - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact does not exist"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity> getContactContactEvents(@PathVariable("id") String identifier) { + Contact contact = contactService.findByIdentifier(identifier); + return ResponseEntity.status(HttpStatus.OK) + .body(contact.getContactEvents().stream().map(this::convertToDto) + .toList()); + } @Operation(summary = "Create a contactEvent") @PostMapping(value = Constants.API_CONTACTEVENTS, produces = "application/json", consumes = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = ContactEventDto.class))), - @ApiResponse(responseCode = "400", description = "Bad request"), - @ApiResponse(responseCode = "404", description = "Not found") - }) - public ResponseEntity postContactEvent(@RequestBody ContactEventDto contactEventDto) { - try { - - Optional optContact = contactService.findByIdentifier(contactEventDto.getIdentifier()); - if (optContact.isPresent()) { - Contact contact = optContact.get(); - ContactEvent contactEvent = convertToEntity(contactEventDto); - ContactEvent newContactEvent = contactEventService.saveContactEvent(contactEvent); - Set setContactEvents = contact.getContactEvents(); - setContactEvents.add(newContactEvent); - contact.setContactEvents(setContactEvents); - contactService.saveContact(contact); - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.set(HttpHeaders.LOCATION, - ServletUriComponentsBuilder.fromCurrentRequest().toUriString()); - return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders) - .body(convertToDto(newContactEvent)); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact does not exist"); - } catch (EventException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body("Event not recognized: only [" + Stream.of(ContactEventType.values()) - .map(ContactEventType::name).collect(Collectors.joining(", ")) + "] are possible"); - } + public ResponseEntity postContactEvent(@RequestBody @Valid ContactEventDto contactEventDto) { + + Contact contact = contactService.findByIdentifier(contactEventDto.getIdentifier()); + ContactEvent contactEvent = convertToEntity(contactEventDto); + ContactEvent newContactEvent = contactEventService.saveContactEvent(contactEvent); + Set setContactEvents = contact.getContactEvents(); + setContactEvents.add(newContactEvent); + contact.setContactEvents(setContactEvents); + contactService.saveContact(contact); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set(HttpHeaders.LOCATION, + ServletUriComponentsBuilder.fromCurrentRequest().toUriString()); + return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders) + .body(convertToDto(newContactEvent)); } + @Operation(summary = "Delete a contact event") @DeleteMapping(value = Constants.API_CONTACTEVENTS_ID, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "No Content"), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad Request") - }) - public ResponseEntity deleteContactEvent(@PathVariable("id") Long id) { - try { - Optional optContactEvent = contactEventService.findById(id); - if (optContactEvent.isPresent()) { - ContactEvent contactEvent = optContactEvent.get(); - Contact contact = contactEvent.getContact(); - contact.setContactEvents(contact.getContactEvents().stream().filter(ce -> !ce.equals(contactEvent)) - .collect(Collectors.toSet())); - contactService.saveContact(contact); - contactEventService.deleteContactEvent(id); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Contact event deleted"); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact event does not exist"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteContactEvent(@PathVariable("id") Long id) { + ContactEvent contactEvent = contactEventService.findById(id); + Contact contact = contactEvent.getContact(); + contact.setContactEvents(contact.getContactEvents().stream().filter(ce -> !ce.equals(contactEvent)) + .collect(Collectors.toSet())); + contactService.saveContact(contact); + contactEventService.deleteContactEvent(id); - } } private ContactEventDto convertToDto(ContactEvent contactEvent) { @@ -148,11 +90,8 @@ private ContactEventDto convertToDto(ContactEvent contactEvent) { return ceDto; } - private ContactEvent convertToEntity(ContactEventDto contactEventDto) throws EventException { - ContactEvent contactEvent = modelMapper.map(contactEventDto, ContactEvent.class); - if (contactEvent.getType() == null) - throw new EventException("Contact event not recognized"); - return contactEvent; + private ContactEvent convertToEntity(ContactEventDto contactEventDto) { + return modelMapper.map(contactEventDto, ContactEvent.class); } class ContactEventPage extends PageImpl { @@ -164,4 +103,5 @@ public ContactEventPage(List content, Pageable pageable, long t } } + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/Address.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/Address.java index d8216ac8..ad606d07 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/Address.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/Address.java @@ -1,16 +1,20 @@ package fr.insee.survey.datacollectionmanagement.contact.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import lombok.Data; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.Setter; @Entity -@Data +@Getter +@Setter public class Address { - @Id @GeneratedValue + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "address_seq") private Long id; private String streetNumber; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/Contact.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/Contact.java index 34e6bc1e..544110cd 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/Contact.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/Contact.java @@ -1,30 +1,21 @@ package fr.insee.survey.datacollectionmanagement.contact.domain; -import java.util.Set; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; +import java.util.Set; @Entity @Table(indexes = { @Index(name = "fn_index", columnList = "firstName"), @Index(name = "ln_index", columnList = "lastName"), @Index(name = "lnfn_index", columnList = "lastName, firstName"), - @Index(name = "email_index", columnList = "email") + @Index(name = "email_index", columnList = "email"), + @Index(name = "contactAddress_index", columnList = "address_id") + }) -@Data +@Getter +@Setter public class Contact { public enum Gender { @@ -39,19 +30,16 @@ public enum Gender { private String firstName; private String email; private String function; + private String usualCompanyName; private String phone; private String comment; @Column(columnDefinition = "boolean default false") private boolean emailVerify; @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Address address; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set contactEvents; @Enumerated(EnumType.STRING) diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/ContactEvent.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/ContactEvent.java index 46b2280e..8acd1999 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/ContactEvent.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/domain/ContactEvent.java @@ -1,29 +1,17 @@ package fr.insee.survey.datacollectionmanagement.contact.domain; -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToOne; - -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; - import com.fasterxml.jackson.databind.JsonNode; -import com.vladmihalcea.hibernate.type.json.JsonBinaryType; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.ToString; +import java.util.Date; @Entity -@Data +@Getter +@Setter @NoArgsConstructor -@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) public class ContactEvent { public enum ContactEventType { @@ -31,18 +19,18 @@ public enum ContactEventType { } @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "contact_event_seq") private Long id; private Date eventDate; - @NonNull + + @JdbcTypeCode(SqlTypes.INTEGER) + @Enumerated(EnumType.ORDINAL) private ContactEventType type; @ManyToOne - @EqualsAndHashCode.Exclude - @ToString.Exclude private Contact contact; - @Type(type = "jsonb") + @JdbcTypeCode(SqlTypes.JSON) @Column(columnDefinition = "jsonb") private JsonNode payload; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactDto.java index 6d157baa..a89f7702 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactDto.java @@ -1,6 +1,7 @@ package fr.insee.survey.datacollectionmanagement.contact.dto; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +import fr.insee.survey.datacollectionmanagement.contact.validation.ContactGenderValid; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -8,14 +9,17 @@ @Setter public class ContactDto{ + @NotBlank(message = "Id can't be empty") private String identifier; private String externalId; - private Contact.Gender civility; + @ContactGenderValid + private String civility; private String lastName; private String firstName; private String function; private String email; private String phone; + private String usualCompanyName; private AddressDto address; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactEventDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactEventDto.java index cb1f603b..75fac077 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactEventDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactEventDto.java @@ -1,19 +1,19 @@ package fr.insee.survey.datacollectionmanagement.contact.dto; -import java.util.Date; - import com.fasterxml.jackson.databind.JsonNode; - +import fr.insee.survey.datacollectionmanagement.contact.validation.ContactEventTypeValid; import lombok.Getter; import lombok.Setter; +import java.util.Date; + @Getter @Setter public class ContactEventDto { - private Long id; private String identifier; private Date eventDate; + @ContactEventTypeValid private String type; private JsonNode payload; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactFirstLoginDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactFirstLoginDto.java index 61735601..2a6d262b 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactFirstLoginDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/dto/ContactFirstLoginDto.java @@ -1,6 +1,7 @@ package fr.insee.survey.datacollectionmanagement.contact.dto; import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +import fr.insee.survey.datacollectionmanagement.contact.validation.ContactGenderValid; import lombok.Getter; import lombok.Setter; @@ -10,12 +11,14 @@ public class ContactFirstLoginDto{ private String identifier; private String externalId; + @ContactGenderValid private Contact.Gender civility; private String lastName; private String firstName; private String function; private String email; private String phone; + private String usualCompanyName; private boolean firstConnect; private AddressDto address; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/repository/ContactRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/repository/ContactRepository.java index 7b3251af..976e067c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/repository/ContactRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/repository/ContactRepository.java @@ -1,30 +1,47 @@ package fr.insee.survey.datacollectionmanagement.contact.repository; -import java.util.List; - +import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +public interface ContactRepository extends PagingAndSortingRepository, JpaRepository { -public interface ContactRepository extends PagingAndSortingRepository,JpaRepository { - + @Override Page findAll(Pageable pageable); @Query(nativeQuery = true, value = "SELECT * FROM contact ORDER BY random() LIMIT 1") - public Contact findRandomContact(); + Contact findRandomContact(); @Query(nativeQuery = true, value = "SELECT identifier FROM contact TABLESAMPLE system_rows(1)") - public String findRandomIdentifierContact(); - - public List findByLastNameIgnoreCase(String lastName); - - public List findByFirstNameIgnoreCase(String firstName); - - public List findByEmailIgnoreCase(String email); + String findRandomIdentifierContact(); + + @Query( + value = """ + SELECT + * + FROM + contact c + JOIN + address a + ON + c.address_id = a.id + WHERE + (:identifier IS NULL OR UPPER(c.identifier) = UPPER(:identifier)) + AND + (:name IS NULL OR UPPER(CONCAT(c.first_name, ' ', c.last_name)) LIKE UPPER(CONCAT('%', :name, '%'))) + AND + (:email IS NULL OR UPPER(c.email) = UPPER(:email)) + AND + (:function IS NULL OR UPPER(c.function) LIKE UPPER(CONCAT('%', :function, '%'))) + AND + (:city IS NULL OR UPPER(a.city_name) = UPPER(:city)) + """, + nativeQuery = true + ) + Page findByParameters(String identifier, String name, String email, String city, String function, Pageable pageable); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/AddressService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/AddressService.java index 13f49cc2..9af53e06 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/AddressService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/AddressService.java @@ -1,18 +1,15 @@ package fr.insee.survey.datacollectionmanagement.contact.service; -import java.util.Optional; - +import fr.insee.survey.datacollectionmanagement.contact.domain.Address; +import fr.insee.survey.datacollectionmanagement.contact.dto.AddressDto; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import fr.insee.survey.datacollectionmanagement.contact.domain.Address; -import fr.insee.survey.datacollectionmanagement.contact.dto.AddressDto; - @Service public interface AddressService { - public Optional
findById(Long id); + public Address findById(Long id); public Page
findAll(Pageable pageable); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/ContactEventService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/ContactEventService.java index 26a6d8a7..4e39b430 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/ContactEventService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/ContactEventService.java @@ -1,24 +1,21 @@ package fr.insee.survey.datacollectionmanagement.contact.service; -import java.util.Optional; -import java.util.Set; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - import com.fasterxml.jackson.databind.JsonNode; - import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.Set; @Service public interface ContactEventService { public Page findAll(Pageable pageable); - public Optional findById(Long id); + public ContactEvent findById(Long id); public ContactEvent saveContactEvent(ContactEvent contactEvent); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/ContactService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/ContactService.java index 3f11541d..96d871bf 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/ContactService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/ContactService.java @@ -1,63 +1,55 @@ package fr.insee.survey.datacollectionmanagement.contact.service; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; - +import com.fasterxml.jackson.databind.JsonNode; +import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.databind.JsonNode; - -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +import java.util.List; @Service public interface ContactService { /** * Find all contacts - * - * @param pageable + * + * @param pageable pageable * @return contact Page */ - public Page findAll(Pageable pageable); + Page findAll(Pageable pageable); + + List findAll(); /** * Find a contact by its identifier. - * - * @param identifier - * @return Optional contact found + * + * @param identifier contact identifier + * @return contact found */ - public Optional findByIdentifier(String identifier) ; + Contact findByIdentifier(String identifier) ; /** * Update an existing contact and its address, or creates a new one - * - * @param contact + * + * @param contact Contact to save * @return contact updated */ - public Contact saveContact(Contact contact); + Contact saveContact(Contact contact); /** * Delete a contact. Delete also the contact address. - * @param identifier + * @param identifier contact identifier */ - public void deleteContact(String identifier); - - public List findByLastName(String lastName); - - public List findByFirstName(String firstName); - - public List findByEmail(String email); + void deleteContact(String identifier); - public List searchListContactParameters(String identifier, String lastName, String firstName, - String email); + Page findByParameters(String identifier, String name, String email, String city, String function, Pageable pageable); - public Contact createContactAddressEvent(Contact contact, JsonNode payload); + Contact createContactAddressEvent(Contact contact, JsonNode payload); - public Contact updateContactAddressEvent(Contact contact, JsonNode payload); + Contact updateContactAddressEvent(Contact contact, JsonNode payload) throws NotFoundException; - public void deleteContactAddressEvent(Contact contact); + void deleteContactAddressEvent(Contact contact); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/AddressServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/AddressServiceImpl.java index c52249d8..6cfb866b 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/AddressServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/AddressServiceImpl.java @@ -1,30 +1,27 @@ package fr.insee.survey.datacollectionmanagement.contact.service.impl; -import java.util.Optional; - -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - import fr.insee.survey.datacollectionmanagement.contact.domain.Address; import fr.insee.survey.datacollectionmanagement.contact.dto.AddressDto; import fr.insee.survey.datacollectionmanagement.contact.repository.AddressRepository; import fr.insee.survey.datacollectionmanagement.contact.service.AddressService; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import lombok.RequiredArgsConstructor; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; @Service +@RequiredArgsConstructor public class AddressServiceImpl implements AddressService { - @Autowired - AddressRepository addressRepository; + private final AddressRepository addressRepository; - @Autowired - private ModelMapper modelMapper; + private final ModelMapper modelMapper; @Override - public Optional
findById(Long id) { - return addressRepository.findById(id); + public Address findById(Long id) { + return addressRepository.findById(id).orElseThrow(() -> new NotFoundException(String.format("Address %s not found", id))); } @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/ContactEventServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/ContactEventServiceImpl.java index e5c55149..63d15226 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/ContactEventServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/ContactEventServiceImpl.java @@ -1,27 +1,25 @@ package fr.insee.survey.datacollectionmanagement.contact.service.impl; -import java.util.Date; -import java.util.Optional; -import java.util.Set; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - import com.fasterxml.jackson.databind.JsonNode; - import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; import fr.insee.survey.datacollectionmanagement.contact.repository.ContactEventRepository; import fr.insee.survey.datacollectionmanagement.contact.service.ContactEventService; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.Set; @Service +@RequiredArgsConstructor public class ContactEventServiceImpl implements ContactEventService { - @Autowired - private ContactEventRepository contactEventRepository; + private final ContactEventRepository contactEventRepository; @Override public Page findAll(Pageable pageable) { @@ -29,8 +27,8 @@ public Page findAll(Pageable pageable) { } @Override - public Optional findById(Long id) { - return contactEventRepository.findById(id); + public ContactEvent findById(Long id) { + return contactEventRepository.findById(id).orElseThrow(()->new NotFoundException(String.format("ContactEvent %s not found", id))); } @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/ContactServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/ContactServiceImpl.java index 2d336372..c3e64f39 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/ContactServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/service/impl/ContactServiceImpl.java @@ -1,22 +1,6 @@ package fr.insee.survey.datacollectionmanagement.contact.service.impl; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - import com.fasterxml.jackson.databind.JsonNode; - import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; @@ -24,18 +8,27 @@ import fr.insee.survey.datacollectionmanagement.contact.service.AddressService; import fr.insee.survey.datacollectionmanagement.contact.service.ContactEventService; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; @Service +@RequiredArgsConstructor public class ContactServiceImpl implements ContactService { - @Autowired - private ContactRepository contactRepository; + private final ContactRepository contactRepository; - @Autowired - private AddressService addressService; + private final AddressService addressService; - @Autowired - private ContactEventService contactEventService; + private final ContactEventService contactEventService; @Override public Page findAll(Pageable pageable) { @@ -43,8 +36,13 @@ public Page findAll(Pageable pageable) { } @Override - public Optional findByIdentifier(String identifier) { - return contactRepository.findById(identifier); + public List findAll() { + return contactRepository.findAll(); + } + + @Override + public Contact findByIdentifier(String identifier) { + return contactRepository.findById(identifier).orElseThrow(() -> new NotFoundException(String.format("Contact %s not found", identifier))); } @Override @@ -58,78 +56,28 @@ public void deleteContact(String identifier) { } @Override - public List findByLastName(String lastName) { - return contactRepository.findByLastNameIgnoreCase(lastName); + public Page findByParameters(String identifier, String name, String email, String city, String function, Pageable pageable) { + return contactRepository.findByParameters(identifier, name, email, city, function, pageable); } - @Override - public List findByFirstName(String firstName) { - return contactRepository.findByFirstNameIgnoreCase(firstName); - } - - @Override - public List findByEmail(String email) { - return contactRepository.findByEmailIgnoreCase(email); - } - - @Override - public List searchListContactParameters(String identifier, String lastName, String firstName, - String email) { - - List listContactContact = new ArrayList<>(); - boolean alwaysEmpty = true; - - if (!StringUtils.isEmpty(identifier)) { - listContactContact = Arrays.asList(findByIdentifier(identifier).get()); - alwaysEmpty = false; - } - - if (!StringUtils.isEmpty(lastName)) { - if (listContactContact.isEmpty() && alwaysEmpty) { - listContactContact.addAll(findByLastName(lastName)); - alwaysEmpty = false; - } else - listContactContact = listContactContact.stream().filter(c -> c.getLastName().equalsIgnoreCase(lastName)) - .collect(Collectors.toList()); - - } - - if (!StringUtils.isEmpty(firstName)) { - if (listContactContact.isEmpty() && alwaysEmpty) { - listContactContact.addAll(findByFirstName(firstName)); - alwaysEmpty = false; - } else - listContactContact = listContactContact.stream() - .filter(c -> c.getFirstName().equalsIgnoreCase(firstName)).collect(Collectors.toList()); - } - - if (!StringUtils.isEmpty(email)) { - if (listContactContact.isEmpty() && alwaysEmpty) { - listContactContact.addAll(findByEmail(email)); - alwaysEmpty = false; - } else - listContactContact = listContactContact.stream().filter(c -> c.getEmail().equalsIgnoreCase(email)) - .collect(Collectors.toList()); - } - - return listContactContact; - } @Override + @Transactional public Contact createContactAddressEvent(Contact contact, JsonNode payload) { if (contact.getAddress() != null) { addressService.saveAddress(contact.getAddress()); } ContactEvent newContactEvent = contactEventService.createContactEvent(contact, ContactEventType.create, payload); - contact.setContactEvents(new HashSet<>(Arrays.asList(newContactEvent))); + contact.setContactEvents(new HashSet<>(Collections.singletonList(newContactEvent))); return saveContact(contact); } @Override - public Contact updateContactAddressEvent(Contact contact, JsonNode payload) { + @Transactional + public Contact updateContactAddressEvent(Contact contact, JsonNode payload) throws NotFoundException { - Contact existingContact = findByIdentifier(contact.getIdentifier()).get(); + Contact existingContact = findByIdentifier(contact.getIdentifier()); if (contact.getAddress() != null) { if (existingContact.getAddress() != null) { contact.getAddress().setId(existingContact.getAddress().getId()); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/util/PayloadUtil.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/util/PayloadUtil.java new file mode 100644 index 00000000..e5b26742 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/util/PayloadUtil.java @@ -0,0 +1,24 @@ +package fr.insee.survey.datacollectionmanagement.contact.util; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.HashMap; +import java.util.Map; + + +public class PayloadUtil { + + private PayloadUtil() { + throw new IllegalStateException("Utility class"); + } + + + public static JsonNode getPayloadAuthor(String author) { + Map mapAuthor = new HashMap<>(); + mapAuthor.put("author", author); + return new ObjectMapper().valueToTree(mapAuthor); + } + + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactEventTypeValid.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactEventTypeValid.java new file mode 100644 index 00000000..da18c277 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactEventTypeValid.java @@ -0,0 +1,26 @@ +package fr.insee.survey.datacollectionmanagement.contact.validation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +@Target({FIELD, PARAMETER, METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = ContactEventTypeValidator.class) +public @interface ContactEventTypeValid { + //error message + String message() default "Type missing or not recognized. Only create, update, merged, firstConnect, reinitPassword are valid"; + + //represents group of constraints + Class[] groups() default {}; + + //represents additional information about annotation + Class[] payload() default {}; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactEventTypeValidator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactEventTypeValidator.java new file mode 100644 index 00000000..f2de33f6 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactEventTypeValidator.java @@ -0,0 +1,23 @@ +package fr.insee.survey.datacollectionmanagement.contact.validation; + +import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.util.Arrays; + +public class ContactEventTypeValidator implements ConstraintValidator { + + + @Override + public void initialize(ContactEventTypeValid constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (value == null) + return false; + return Arrays.stream(ContactEvent.ContactEventType.values()).anyMatch(v -> value.equalsIgnoreCase(v.name())); + } +} \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactGenderValid.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactGenderValid.java new file mode 100644 index 00000000..5be66de4 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactGenderValid.java @@ -0,0 +1,26 @@ +package fr.insee.survey.datacollectionmanagement.contact.validation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +@Target({FIELD, PARAMETER, METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = ContactGenderValidator.class) +public @interface ContactGenderValid { + //error message + String message() default "Type missing or not recognized. Only Female, Male, Undefined are valid"; + + //represents group of constraints + Class[] groups() default {}; + + //represents additional information about annotation + Class[] payload() default {}; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactGenderValidator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactGenderValidator.java new file mode 100644 index 00000000..d82bd99c --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/contact/validation/ContactGenderValidator.java @@ -0,0 +1,23 @@ +package fr.insee.survey.datacollectionmanagement.contact.validation; + +import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.util.Arrays; + +public class ContactGenderValidator implements ConstraintValidator { + + + @Override + public void initialize(ContactGenderValid constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (value == null) + return false; + return Arrays.stream(Contact.Gender.values()).anyMatch(v -> value.equals(v.name())); + } +} \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/Dataloader.java b/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/Dataloader.java new file mode 100644 index 00000000..e75d8095 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/Dataloader.java @@ -0,0 +1,54 @@ +package fr.insee.survey.datacollectionmanagement.dataloader; + +import fr.insee.survey.datacollectionmanagement.questioning.domain.EventOrder; +import fr.insee.survey.datacollectionmanagement.questioning.repository.EventOrderRepository; +import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +@Profile("poc") +@RequiredArgsConstructor +public class Dataloader { + + private final EventOrderRepository orderRepository; + + + @PostConstruct + public void init() { + + initOrder(); + + } + + private void initOrder() { + + Long nbExistingOrders = orderRepository.count(); + log.info("{} orders in database", nbExistingOrders); + + if (nbExistingOrders != 8) { + // Creating table order + log.info("loading eventorder data"); + orderRepository.deleteAll(); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("8"), TypeQuestioningEvent.REFUSAL.toString(), 8)); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("7"), TypeQuestioningEvent.VALINT.toString(), 7)); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("6"), TypeQuestioningEvent.VALPAP.toString(), 6)); + orderRepository.saveAndFlush(new EventOrder(Long.parseLong("5"), TypeQuestioningEvent.HC.toString(), 5)); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("4"), TypeQuestioningEvent.PARTIELINT.toString(), 4)); + orderRepository.saveAndFlush(new EventOrder(Long.parseLong("3"), TypeQuestioningEvent.WASTE.toString(), 3)); + orderRepository.saveAndFlush(new EventOrder(Long.parseLong("2"), TypeQuestioningEvent.PND.toString(), 2)); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("1"), TypeQuestioningEvent.INITLA.toString(), 1)); + } + } + + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderPoc.java b/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderPoc.java new file mode 100644 index 00000000..f6cb3160 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderPoc.java @@ -0,0 +1,603 @@ +package fr.insee.survey.datacollectionmanagement.dataloader; + +import com.github.javafaker.Faker; +import com.github.javafaker.Name; +import fr.insee.survey.datacollectionmanagement.contact.domain.Address; +import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +import fr.insee.survey.datacollectionmanagement.contact.domain.Contact.Gender; +import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; +import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; +import fr.insee.survey.datacollectionmanagement.contact.repository.AddressRepository; +import fr.insee.survey.datacollectionmanagement.contact.repository.ContactEventRepository; +import fr.insee.survey.datacollectionmanagement.contact.repository.ContactRepository; +import fr.insee.survey.datacollectionmanagement.metadata.domain.*; +import fr.insee.survey.datacollectionmanagement.metadata.repository.*; +import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; +import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; +import fr.insee.survey.datacollectionmanagement.questioning.domain.*; +import fr.insee.survey.datacollectionmanagement.questioning.repository.*; +import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import fr.insee.survey.datacollectionmanagement.view.domain.View; +import fr.insee.survey.datacollectionmanagement.view.repository.ViewRepository; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +import java.security.SecureRandom; +import java.util.*; +import java.util.concurrent.TimeUnit; + +@Component +@Slf4j +@Profile(("demo")) +@RequiredArgsConstructor +public class DataloaderPoc { + + private final ContactRepository contactRepository; + + private final AddressRepository addressRepository; + + private final ContactEventRepository contactEventRepository; + + private final OwnerRepository ownerRepository; + + private final SupportRepository supportRepository; + + private final SourceRepository sourceRepository; + + private final SurveyRepository surveyRepository; + + private final SurveyUnitRepository surveyUnitRepository; + + private final SurveyUnitAddressRepository surveyUnitAddressRepository; + + private final OperatorServiceRepository operatorServiceRepository; + + private final OperatorRepository operatorRepository; + + private final QuestioningRepository questioningRepository; + + private final QuestioningAccreditationRepository questioningAccreditationRepository; + + private final CampaignRepository campaignRepository; + + private final PartitioningRepository partitioningRepository; + + private final EventOrderRepository orderRepository; + + private final QuestioningEventRepository questioningEventRepository; + + private final ViewRepository viewRepository; + + static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + static final String NUMBERS = "0123456789"; + + static SecureRandom rnd = new SecureRandom(); + + @PostConstruct + public void init() { + + Faker faker = new Faker(); + + initOrder(); + //initContact(faker); + + /*initDataForOneSource(faker, "DVM", 2, PeriodicityEnum.M, 12, 3, 1); + initDataForOneSource(faker, "DVT", 3, PeriodicityEnum.T, 4, 2, 1); + initDataForOneSource(faker, "DVX", 2, PeriodicityEnum.X, 1, 2, 1); + initDataForOneSource(faker, "DVB", 2, PeriodicityEnum.B, 6, 1, 1);*/ + } + + + private void initSurveyUnitAddressAndOperators(Faker faker) { + if (surveyUnitAddressRepository.count() == 0) { + for (SurveyUnit su : surveyUnitRepository.findAll()) { + SurveyUnitAddress a = new SurveyUnitAddress(); + com.github.javafaker.Address fakeAddress = faker.address(); + + a.setCountryName(fakeAddress.country()); + a.setStreetNumber(fakeAddress.buildingNumber()); + a.setStreetName(fakeAddress.streetName()); + a.setZipCode(fakeAddress.zipCode()); + a.setCityName(fakeAddress.cityName()); + su.setSurveyUnitAddress(a); + surveyUnitRepository.save(su); + } + } + + if (operatorServiceRepository.count() == 0) { + Set setOpConj = new HashSet<>(); + OperatorService operatorServiceConj = new OperatorService(); + operatorServiceConj.setName("Conjoncture"); + operatorServiceConj.setMail("conjoncture@Cocorico.fr"); + for (int i = 0; i < 9; i++) { + setOpConj.add(createOperator(faker)); + } + operatorServiceConj.setOperators(setOpConj); + operatorServiceRepository.save(operatorServiceConj); + + Set setOpLogement = new HashSet<>(); + OperatorService operatorServiceLogement = new OperatorService(); + operatorServiceLogement.setName("Logement"); + operatorServiceLogement.setMail("logement@Cocorico.fr"); + operatorServiceRepository.save(operatorServiceLogement); + for (int i = 0; i < 9; i++) { + setOpLogement.add(createOperator(faker)); + } + operatorServiceLogement.setOperators(setOpLogement); + operatorServiceRepository.save(operatorServiceLogement); + + Set setOpEmploi = new HashSet<>(); + OperatorService operatorServiceEmploi = new OperatorService(); + operatorServiceEmploi.setName("Emploi"); + operatorServiceEmploi.setMail("emploi@Cocorico.fr"); + operatorServiceRepository.save(operatorServiceEmploi); + for (int i = 0; i < 9; i++) { + setOpEmploi.add(createOperator(faker)); + } + operatorServiceEmploi.setOperators(setOpEmploi); + operatorServiceRepository.save(operatorServiceEmploi); + + Set setOpPrix = new HashSet<>(); + OperatorService operatorServicePrix = new OperatorService(); + operatorServicePrix.setName("Prix"); + operatorServicePrix.setMail("prix@Cocorico.fr"); + operatorServiceRepository.save(operatorServicePrix); + for (int i = 0; i < 9; i++) { + setOpPrix.add(createOperator(faker)); + } + operatorServicePrix.setOperators(setOpPrix); + operatorServiceRepository.save(operatorServicePrix); + } + + if (operatorServiceRepository.count() == 0) { + for (SurveyUnit su : surveyUnitRepository.findAll()) { + SurveyUnitAddress a = new SurveyUnitAddress(); + com.github.javafaker.Address fakeAddress = faker.address(); + + a.setCountryName(fakeAddress.country()); + a.setStreetNumber(fakeAddress.buildingNumber()); + a.setStreetName(fakeAddress.streetName()); + a.setZipCode(fakeAddress.zipCode()); + a.setCityName(fakeAddress.cityName()); + su.setSurveyUnitAddress(a); + surveyUnitRepository.save(su); + } + } + + } + + private Operator createOperator(Faker faker) { + Operator operator = new Operator(); + Name n = faker.name(); + String name = n.lastName(); + String firstName = n.firstName(); + operator.setLastName(name); + operator.setFirstName(firstName); + operator.setPhoneNumber(faker.phoneNumber().phoneNumber()); + return operatorRepository.save(operator); + } + + private void initOrder() { + + Long nbExistingOrders = orderRepository.count(); + log.info("{} orders in database", nbExistingOrders); + + if (nbExistingOrders != 8) { + // Creating table order + log.info("loading eventorder data"); + orderRepository.deleteAll(); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("8"), TypeQuestioningEvent.REFUSAL.toString(), 8)); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("7"), TypeQuestioningEvent.VALINT.toString(), 7)); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("6"), TypeQuestioningEvent.VALPAP.toString(), 6)); + orderRepository.saveAndFlush(new EventOrder(Long.parseLong("5"), TypeQuestioningEvent.HC.toString(), 5)); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("4"), TypeQuestioningEvent.PARTIELINT.toString(), 4)); + orderRepository.saveAndFlush(new EventOrder(Long.parseLong("3"), TypeQuestioningEvent.WASTE.toString(), 3)); + orderRepository.saveAndFlush(new EventOrder(Long.parseLong("2"), TypeQuestioningEvent.PND.toString(), 2)); + orderRepository + .saveAndFlush(new EventOrder(Long.parseLong("1"), TypeQuestioningEvent.INITLA.toString(), 1)); + } + } + + private void initContact(Faker faker) { + + List listContact = new ArrayList<>(); + Long nbExistingContacts = contactRepository.count(); + + log.info("{} contacts exist in database", nbExistingContacts); + + int nbContacts = 10000; + + for (Long i = nbExistingContacts; i < nbContacts; i++) { + long start = System.currentTimeMillis(); + + final Contact c = initOneContact(faker); + listContact.add(c); + + if ((i + 1) % 10000 == 0) { + //addressRepository.saveAll(listAddresses); + contactRepository.saveAll(listContact); + //listAddresses = new ArrayList<>(); + listContact = new ArrayList<>(); + long end = System.currentTimeMillis(); + + log.info("It took {}ms to execute saveAll() for 10000 contacts.", (end - start)); + } + + } + + Long nbContactEvents = contactEventRepository.count(); + + for (Long j = nbContactEvents; j < 300; j++) { + Contact contact = contactRepository.findRandomContact(); + ContactEvent contactEvent = new ContactEvent(); + contactEvent.setType(ContactEventType.create); + contactEvent.setEventDate(new Date()); + contactEvent.setContact(contact); + contactEventRepository.save(contactEvent); + Set setContactEvents = new HashSet<>(); + setContactEvents.add(contactEvent); + contact.setContactEvents(setContactEvents); + contactRepository.save(contact); + } + + + } + + private Contact initOneContact(Faker faker) { + final Contact c = new Contact(); + final Address a = new Address(); + + Name n = faker.name(); + String name = n.lastName(); + String firstName = n.firstName(); + com.github.javafaker.Address fakeAddress = faker.address(); + + a.setCountryName(fakeAddress.country()); + a.setStreetNumber(fakeAddress.buildingNumber()); + a.setStreetName(fakeAddress.streetName()); + a.setZipCode(fakeAddress.zipCode()); + a.setCityName(fakeAddress.cityName()); + addressRepository.save(a); + //listAddresses.add(a); + + c.setIdentifier(randomString(7).toUpperCase()); + c.setLastName(name); + c.setFirstName(firstName); + c.setPhone(faker.phoneNumber().phoneNumber()); + c.setGender(Gender.valueOf(faker.demographic().sex())); + c.setFunction(faker.job().title()); + c.setComment(faker.beer().name()); + c.setEmail(firstName.toLowerCase() + "." + name.toLowerCase() + "@cocorico.fr"); + c.setAddress(a); + contactRepository.save(c); + return c; + } + + private void initDataForOneSource(Faker faker, String sourceName, int nbSurveysBySource, PeriodicityEnum periodicity, + int nbCampaignsBySource, int nbPartByCampaign, int nbQuestioningsByPart) { + + int year = Calendar.getInstance().get(Calendar.YEAR); + + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, Calendar.DECEMBER); + calendar.set(Calendar.DAY_OF_MONTH, 31); + Date dateEndOfYear = calendar.getTime(); + + Owner ownerInsee = new Owner(); + ownerInsee.setId("insee"); + ownerInsee.setLabel("Insee"); + Set setSourcesInsee = new HashSet<>(); + + Owner ownerAgri = new Owner(); + ownerAgri.setId("agri"); + ownerAgri.setLabel("SSM Agriculture"); + Set setSourcesSsp = new HashSet<>(); + + + Support supportInseeHdf = new Support(); + supportInseeHdf.setId("inseehdf"); + supportInseeHdf.setLabel("Insee Hauts-de-France"); + Set setSourcesSupportInsee = new HashSet<>(); + + Support supportSsne = new Support(); + supportSsne.setId("ssne"); + supportSsne.setLabel("Insee Normandie - SSNE"); + Set setSourcesSupportSsne = new HashSet<>(); + + log.info("{} campaigns exist in database", campaignRepository.count()); + + // while (sourceRepository.count() < 10) { + + Source source = new Source(); + + String nameSource = sourceName; + + if (!StringUtils.contains(nameSource, " ") && sourceRepository.findById(nameSource).isEmpty()) { + + source.setId(nameSource); + source.setLongWording("Have you ever heard about " + nameSource + " ?"); + source.setShortWording("Source about " + nameSource); + source.setPeriodicity(periodicity); + source.setMandatoryMySurveys(false); + + sourceRepository.save(source); + Set setSurveys = new HashSet<>(); + Integer i = rnd.nextInt(); + if (i % 2 == 0) { + setSourcesInsee.add(source); + source.setOwner(ownerInsee); + setSourcesSupportInsee.add(source); + source.setSupport(supportInseeHdf); + } else { + setSourcesSsp.add(source); + source.setOwner(ownerAgri); + setSourcesSupportSsne.add(source); + source.setSupport(supportSsne); + } + + for (int j = 0; j < nbSurveysBySource; j++) { + + Survey survey = new Survey(); + String id = nameSource + (year - j); + survey.setId(id); + survey.setYear(year - j); + survey.setLongObjectives("The purpose of this survey is to find out everything you can about " + + nameSource + + ". Your response is essential to ensure the quality and reliability of the results of this survey."); + survey.setShortObjectives("All about " + id); + survey.setCommunication("Communication around " + id); + survey.setSpecimenUrl("http://specimenUrl/" + id); + survey.setDiffusionUrl("http://diffusion/" + id); + survey.setCnisUrl("http://cnis/" + id); + survey.setNoticeUrl("http://notice/" + id); + survey.setVisaNumber(year + randomString(6).toUpperCase()); + survey.setLongWording("Survey " + nameSource + " " + (year - j)); + survey.setShortWording(id); + setSurveys.add(survey); + surveyRepository.save(survey); + Set setCampaigns = new HashSet<>(); + + for (int k = 0; k < nbCampaignsBySource; k++) { + + Campaign campaign = new Campaign(); + int periodValue = k + 1; + String period = periodValue < 10 ? periodicity + "0" + periodValue : periodicity + String.valueOf(periodValue); + campaign.setYear(year - j); + campaign.setPeriod(PeriodEnum.valueOf(period)); + String idampaign = nameSource + (year - j) + period; + campaign.setId(idampaign); + campaign.setCampaignWording( + "Campaign about " + nameSource + " in " + (year - j) + " and period " + period); + + if (campaignRepository.findById(idampaign).isEmpty()) { + + campaignRepository.save(campaign); + Set setParts = new HashSet<>(); + + for (int l = 0; l < nbPartByCampaign; l++) { + + Partitioning part = new Partitioning(); + part.setId(campaign.getId() + "0" + l); + Date openingDate = faker.date().past(90, 0, TimeUnit.DAYS); + Date closingDate = faker.date().between(openingDate, dateEndOfYear); + Date returnDate = faker.date().between(openingDate, closingDate); + + part.setOpeningDate(openingDate); + part.setClosingDate(closingDate); + part.setReturnDate(returnDate); + setParts.add(part); + part.setCampaign(campaign); + partitioningRepository.save(part); + initQuestionning(faker, part, nbQuestioningsByPart); + } + campaign.setSurvey(survey); + campaign.setPartitionings(setParts); + setCampaigns.add(campaign); + campaignRepository.save(campaign); + } + + } + survey.setSource(source); + survey.setCampaigns(setCampaigns); + surveyRepository.save(survey); + } + source.setSurveys(setSurveys); + source.setSurveys(setSurveys); + + sourceRepository.save(source); + ownerInsee.setSources(setSourcesInsee); + ownerAgri.setSources(setSourcesSsp); + ownerRepository.saveAll(Arrays.asList(ownerInsee, ownerAgri)); + + supportInseeHdf.setSources(setSourcesSupportInsee); + supportSsne.setSources(setSourcesSupportSsne); + supportRepository.saveAll(Arrays.asList(supportInseeHdf, supportSsne)); + } + } + + private void initQuestionning(Faker faker, Partitioning part, int nbQuestionings) { + + //Long nbExistingQuestionings = questioningRepository.count(); + + //log.info("{} questionings exist in database", nbExistingQuestionings); + + long start = System.currentTimeMillis(); + Questioning qu; + QuestioningEvent qe; + Set setQuestioning; + QuestioningAccreditation accreditation; + Set questioningAccreditations; + String fakeSiren; + + log.info("{} survey units exist in database", surveyUnitRepository.count()); + + for (int i = 0; i < nbQuestionings; i++) { + SurveyUnit su = new SurveyUnit(); + fakeSiren = randomNumeric(9); + + su.setIdSu(fakeSiren); + su.setIdentificationName(faker.company().name()); + su.setIdentificationCode(fakeSiren); + surveyUnitRepository.save(su); + + qu = new Questioning(); + qe = new QuestioningEvent(); + Set questioningEvents = new HashSet<>(); + questioningAccreditations = new HashSet<>(); + + setQuestioning = new HashSet<>(); + qu.setModelName("m" + randomNumeric(2)); + qu.setIdPartitioning(part.getId()); + qu.setSurveyUnit(su); + questioningRepository.save(qu); + setQuestioning.add(qu); + su.setQuestionings(setQuestioning); + + // questioning events + // everybody in INITLA + Date eventDate = faker.date().between(part.getOpeningDate(), part.getClosingDate()); + qe.setType(TypeQuestioningEvent.INITLA); + qe.setDate(eventDate); + qe.setQuestioning(qu); + questioningEvents.add(qe); + + int qeProfile = rnd.nextInt(10); + + switch (qeProfile) { + case 0: + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.REFUSAL, qu)); + break; + case 1: + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.PND, qu)); + break; + case 2: + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.FOLLOWUP, qu)); + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.FOLLOWUP, qu)); + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.PARTIELINT, qu)); + break; + case 3, 4: + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.FOLLOWUP, qu)); + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.FOLLOWUP, qu)); + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.VALINT, qu)); + break; + case 5, 6, 7: + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.PARTIELINT, qu)); + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.VALINT, qu)); + break; + default: + questioningEvents.add(new QuestioningEvent( + faker.date().between(part.getOpeningDate(), part.getClosingDate()), + TypeQuestioningEvent.PARTIELINT, qu)); + break; + + } + + questioningEvents.stream().forEach(questioningEventRepository::save); + + //for (int j = 0; j < 4; j++) { + accreditation = new QuestioningAccreditation(); + accreditation.setIdContact(initOneContact(faker).getIdentifier()); + accreditation.setQuestioning(qu); + + int randomDoubleContact = rnd.nextInt(300); + + if (randomDoubleContact == 1) { + QuestioningAccreditation accreditation2 = new QuestioningAccreditation(); + accreditation2.setIdContact(contactRepository.findRandomIdentifierContact()); + accreditation2.setQuestioning(qu); + questioningAccreditations.add(accreditation2); + initOneView(accreditation); + + } + + questioningAccreditations.add(accreditation); + questioningAccreditationRepository.save(accreditation); + initOneView(accreditation); + // } + qu.setQuestioningEvents(questioningEvents); + qu.setQuestioningAccreditations(questioningAccreditations); + questioningRepository.save(qu); + if (i % 10000 == 0) { + long end = System.currentTimeMillis(); + log.info("It took {}ms to execute save() for 10000 questionings.", (end - start)); + start = System.currentTimeMillis(); + } + + } + } + + + private void initView() { + if (viewRepository.count() == 0) { + + List listAccreditations = questioningAccreditationRepository.findAll(); + listAccreditations.stream().forEach(this::initOneView); + + Iterable listContacts = contactRepository.findAll(); + for (Contact contact : listContacts) { + if (viewRepository.findByIdentifier(contact.getIdentifier()).isEmpty()) { + View view = new View(); + view.setIdentifier(contact.getIdentifier()); + viewRepository.save(view); + + } + } + } + } + + private void initOneView(QuestioningAccreditation a) { + Partitioning p = partitioningRepository.findById(a.getQuestioning().getIdPartitioning()).orElse(null); + View view = new View(); + view.setIdentifier(contactRepository.findById(a.getIdContact()).orElse(null).getIdentifier()); + view.setCampaignId(p.getCampaign().getId()); + view.setIdSu(a.getQuestioning().getSurveyUnit().getIdSu()); + viewRepository.save(view); + } + + + String randomString(int len) { + StringBuilder sb = new StringBuilder(len); + for (int i = 0; i < len; i++) + sb.append(AB.charAt(rnd.nextInt(AB.length()))); + return sb.toString(); + } + + String randomNumeric(int len) { + StringBuilder sb = new StringBuilder(len); + for (int i = 0; i < len; i++) + sb.append(NUMBERS.charAt(rnd.nextInt(NUMBERS.length()))); + return sb.toString(); + } + + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ApiError.java b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ApiError.java new file mode 100644 index 00000000..475f937b --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ApiError.java @@ -0,0 +1,42 @@ +package fr.insee.survey.datacollectionmanagement.exception; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.http.HttpStatus; + +import java.util.Date; + +/** + * Default API Error object returned as JSON response to client + */ +@Data +@AllArgsConstructor +public class ApiError { + private Integer code; + private String path; + private String message; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy hh:mm:ss") + private Date timestamp; + + /** + * @param status http status for this error + * @param path origin request path + * @param timestamp timestamp of the generated error + * @param errorMessage error message + */ + public ApiError(HttpStatus status, String path, Date timestamp, String errorMessage) { + if (errorMessage == null || errorMessage.isEmpty()) { + errorMessage = status.getReasonPhrase(); + } + createApiError(status.value(), path, timestamp, errorMessage); + } + + private void createApiError(int code, String path, Date timestamp, String errorMessage) { + this.code = code; + this.path = path; + this.message = errorMessage; + this.timestamp = timestamp; + } +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ApiExceptionComponent.java b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ApiExceptionComponent.java new file mode 100644 index 00000000..0902b583 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ApiExceptionComponent.java @@ -0,0 +1,54 @@ +package fr.insee.survey.datacollectionmanagement.exception; + +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.context.request.WebRequest; + +import java.util.Date; +import java.util.Map; + + +/** + * Component used to build APIError objects + */ +@Component +public class ApiExceptionComponent { + + private final ErrorAttributes errorAttributes; + + public ApiExceptionComponent(ErrorAttributes errorAttributes) { + this.errorAttributes = errorAttributes; + } + + /** + * @param request origin request + * @param status status from exception + * @param errorMessage error message + * @return error object used for JSON response + */ + public ApiError buildApiErrorObject(WebRequest request, HttpStatus status, String errorMessage) { + String path = getPath(request); + Date timestamp = getTimeStamp(request); + return new ApiError(status, path, timestamp, errorMessage); + } + + /** + * @param request origin request + * @return get timestamp from error attributes + */ + private Date getTimeStamp(WebRequest request) { + Map attributes = errorAttributes.getErrorAttributes(request, ErrorAttributeOptions.defaults()); + return ((Date) attributes.get("timestamp")); + } + + /** + * @param request origin request + * @return get path from origin request + */ + private String getPath(WebRequest request) { + return ((ServletWebRequest) request).getRequest().getRequestURI(); + } +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ExceptionControllerAdvice.java b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ExceptionControllerAdvice.java new file mode 100644 index 00000000..6e11d77f --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ExceptionControllerAdvice.java @@ -0,0 +1,162 @@ +package fr.insee.survey.datacollectionmanagement.exception; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import jakarta.persistence.EntityNotFoundException; +import jakarta.validation.ConstraintViolationException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.NoHandlerFoundException; + +/** + * Handle API exceptions for project + * Do not work on exceptions occuring before/outside controllers scope + */ +@ControllerAdvice +@Slf4j +@RequiredArgsConstructor +public class ExceptionControllerAdvice { + + private static final String ERROR_OCCURRED_LABEL = "An error has occurred"; + private final ApiExceptionComponent errorComponent; + + /** + * Global method to process the catched exception + * + * @param ex Exception catched + * @param status status linked with this exception + * @param request request initiating the exception + * @return the apierror object with linked status code + */ + private ResponseEntity processException(Exception ex, HttpStatus status, WebRequest request) { + return processException(ex, status, request, null); + } + + /** + * Global method to process the catched exception + * + * @param ex Exception catched + * @param status status linked with this exception + * @param request request initiating the exception + * @param overrideErrorMessage message overriding default error message from exception + * @return the apierror object with linked status code + */ + private ResponseEntity processException(Exception ex, HttpStatus status, WebRequest request, String overrideErrorMessage) { + String errorMessage = ex.getMessage(); + if (overrideErrorMessage != null) { + errorMessage = overrideErrorMessage; + } + ApiError error = errorComponent.buildApiErrorObject(request, status, errorMessage); + return new ResponseEntity<>(error, status); + } + + @ExceptionHandler(NoHandlerFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ResponseEntity noHandlerFoundException(NoHandlerFoundException e, WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.NOT_FOUND, request); + } + + @ExceptionHandler(AccessDeniedException.class) + @ResponseStatus(HttpStatus.FORBIDDEN) + public ResponseEntity accessDeniedException(AccessDeniedException e, WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.FORBIDDEN, request); + } + + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleMethodArgumentNotValid( + MethodArgumentNotValidException e, + WebRequest request) { + + String defaultMessage = e.getBindingResult().getAllErrors().get(0).getDefaultMessage(); + log.error(defaultMessage, e); + return processException(e, HttpStatus.BAD_REQUEST, request, defaultMessage); + } + + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + @ExceptionHandler(ConstraintViolationException.class) + public ResponseEntity handleConstraintViolation( + ConstraintViolationException e, + WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.BAD_REQUEST, request, e.getMessage()); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + public ResponseEntity handleHttpMessageNotReadableException( + HttpMessageNotReadableException e, WebRequest request) { + log.error(e.getMessage(), e); + + Throwable rootCause = e.getRootCause(); + + String errorMessage = "Error when deserializing JSON"; + if (rootCause instanceof JsonParseException parseException) { + String location = parseException.getLocation() != null ? "[line: " + parseException.getLocation().getLineNr() + ", column: " + parseException.getLocation().getColumnNr() + "]" : ""; + errorMessage = "Error with JSON syntax. Check that your json is well formatted: " + parseException.getOriginalMessage() + " " + location; + } + if (rootCause instanceof JsonMappingException mappingException) { + String location = mappingException.getLocation() != null ? "[line: " + mappingException.getLocation().getLineNr() + ", column: " + mappingException.getLocation().getColumnNr() + "]" : ""; + errorMessage = "Error when deserializing JSON. Check that your JSON properties are of the expected types " + location; + } + return processException(e, HttpStatus.BAD_REQUEST, request, errorMessage); + } + + @ExceptionHandler(NotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ResponseEntity notFoundException(NotFoundException e, WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.NOT_FOUND, request); + } + + @ExceptionHandler(EntityNotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ResponseEntity entityNotFoundException(NotFoundException e, WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.NOT_FOUND, request); + } + + + @ExceptionHandler(NotMatchException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity notMatchException(NotMatchException e, WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.BAD_REQUEST, request); + } + + @ExceptionHandler(ImpossibleToDeleteException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity impossibleToDeleteException(ImpossibleToDeleteException e, WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.BAD_REQUEST, request); + } + + + @ExceptionHandler(HttpClientErrorException.class) + @ResponseBody + public ResponseEntity exceptions(HttpClientErrorException e, WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.valueOf(e.getStatusCode().value()), request, ERROR_OCCURRED_LABEL); + } + + @ExceptionHandler(Exception.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + @ResponseBody + public ResponseEntity exceptions(Exception e, WebRequest request) { + log.error(e.getMessage(), e); + return processException(e, HttpStatus.INTERNAL_SERVER_ERROR, request, ERROR_OCCURRED_LABEL); + } +} \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ImpossibleToDeleteException.java b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ImpossibleToDeleteException.java new file mode 100644 index 00000000..8d358b42 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/ImpossibleToDeleteException.java @@ -0,0 +1,9 @@ +package fr.insee.survey.datacollectionmanagement.exception; + +public class ImpossibleToDeleteException extends RuntimeException { + + public ImpossibleToDeleteException(String errorMessage) { + super(errorMessage); + } + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/exception/NotFoundException.java b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/NotFoundException.java new file mode 100644 index 00000000..c3860788 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/NotFoundException.java @@ -0,0 +1,7 @@ +package fr.insee.survey.datacollectionmanagement.exception; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String errorMessage) { + super(errorMessage); + } +} \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/exception/NotMatchException.java b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/NotMatchException.java new file mode 100644 index 00000000..122900ca --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/exception/NotMatchException.java @@ -0,0 +1,8 @@ +package fr.insee.survey.datacollectionmanagement.exception; + +public class NotMatchException extends RuntimeException { + public NotMatchException(String errorMessage) { + super(errorMessage); + } + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignController.java index 4e6bf935..2299032a 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignController.java @@ -1,53 +1,44 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import fr.insee.survey.datacollectionmanagement.metadata.dto.OnGoingDto; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Upload; -import fr.insee.survey.datacollectionmanagement.questioning.service.UploadService; -import org.apache.commons.lang3.StringUtils; -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.ImpossibleToDeleteException; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignDto; +import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignPartitioningsDto; +import fr.insee.survey.datacollectionmanagement.metadata.dto.OnGoingDto; import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; import fr.insee.survey.datacollectionmanagement.metadata.service.SurveyService; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Upload; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; +import fr.insee.survey.datacollectionmanagement.questioning.service.UploadService; import fr.insee.survey.datacollectionmanagement.view.service.ViewService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.webjars.NotFoundException; +import org.apache.commons.lang3.StringUtils; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.List; +import java.util.Set; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -55,60 +46,53 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "3 - Metadata", description = "Enpoints to create, update, delete and find entities in metadata domain") @Slf4j +@Validated +@RequiredArgsConstructor public class CampaignController { - @Autowired - private CampaignService campaignService; + private final CampaignService campaignService; + + private final SurveyService surveyService; - @Autowired - private SurveyService surveyService; + private final ViewService viewService; - @Autowired - private ViewService viewService; + private final QuestioningService questioningService; - @Autowired - private ModelMapper modelmapper; + private final UploadService uploadService; + + private final ModelMapper modelmapper; - @Autowired - private QuestioningService questioningService; - @Autowired - UploadService uploadService; - @Operation(summary = "Search for campaigns, paginated") @GetMapping(value = Constants.API_CAMPAIGNS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CampaignPage.class))) - }) - public ResponseEntity getSources( + public ResponseEntity getSources( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "id") String sort) { Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); Page pageCampaign = campaignService.findAll(pageable); - List listCampaigns = pageCampaign.stream().map(c -> convertToDto(c)).collect(Collectors.toList()); + List listCampaigns = pageCampaign.stream().map(this::convertToDto).toList(); return ResponseEntity.ok().body(new CampaignPage(listCampaigns, pageable, pageCampaign.getTotalElements())); } @Operation(summary = "Search for campaigns by the survey id") @GetMapping(value = Constants.API_SURVEYS_ID_CAMPAIGNS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = CampaignDto.class)))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity getCampaignsBySurvey(@PathVariable("id") String id) { - try { - Optional survey = surveyService.findById(id); - if (!survey.isPresent()) { - log.warn("Survey {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("survey does not exist"); - } - return ResponseEntity.ok() - .body(survey.get().getCampaigns().stream().map(s -> convertToDto(s)).collect(Collectors.toList())); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity> getCampaignsBySurvey(@PathVariable("id") String id) { + + Survey survey = surveyService.findById(id); + return ResponseEntity.ok() + .body(survey.getCampaigns().stream().map(this::convertToDto).toList()); + + } + + @Operation(summary = "Search for campaigns and partitionings by the survey id") + @GetMapping(value = Constants.API_SURVEYS_ID_CAMPAIGNS_PARTITIONINGS, produces = "application/json") + public ResponseEntity> getCampaignsPartitioningsBySurvey(@PathVariable("id") String id) { + + Survey survey = surveyService.findById(id); + return ResponseEntity.ok() + .body(survey.getCampaigns().stream().map(this::convertToCampaignPartitioningsDto).toList()); + } @Operation(summary = "Search for a campaign by its id") @@ -118,17 +102,10 @@ public ResponseEntity getCampaignsBySurvey(@PathVariable("id") String id) { @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Bad request") }) - public ResponseEntity getCampaign(@PathVariable("id") String id) { - try { - Optional campaign = campaignService.findById(StringUtils.upperCase(id)); - if (!campaign.isPresent()) { - log.warn("campaign {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("campaign does not exist"); - } - return ResponseEntity.ok().body(convertToDto(campaign.get())); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity getCampaign(@PathVariable("id") String id) { + Campaign campaign = campaignService.findById(StringUtils.upperCase(id)); + return ResponseEntity.ok().body(convertToDto(campaign)); + } @@ -139,29 +116,25 @@ public ResponseEntity getCampaign(@PathVariable("id") String id) { @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = CampaignDto.class))), @ApiResponse(responseCode = "400", description = "Bad request") }) - public ResponseEntity putCampaign(@PathVariable("id") String id, @RequestBody CampaignDto campaignDto) { - if (StringUtils.isBlank(campaignDto.getId()) || !campaignDto.getId().equalsIgnoreCase(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and idCampaign don't match"); - } - Campaign campaign; - if (!surveyService.findById(campaignDto.getSurveyId()).isPresent()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Survey does not exist"); + public ResponseEntity putCampaign(@PathVariable("id") String id, @RequestBody @Valid CampaignDto campaignDto) { + if (!campaignDto.getId().equalsIgnoreCase(id)) { + throw new NotMatchException("id and idCampaign don't match"); } HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set(HttpHeaders.LOCATION, ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(campaignDto.getId()).toUriString()); HttpStatus httpStatus; - if (campaignService.findById(id).isPresent()) { - log.info("Update campaign with the id {}", campaignDto.getId()); + try { campaignService.findById(id); + log.info("Update campaign with the id {}", campaignDto.getId()); httpStatus = HttpStatus.OK; - } else { + } catch (NotFoundException e) { log.info("Create campaign with the id {}", campaignDto.getId()); httpStatus = HttpStatus.CREATED; } - campaign = campaignService.insertOrUpdateCampaign(convertToEntity(campaignDto)); + Campaign campaign = campaignService.insertOrUpdateCampaign(convertToEntity(campaignDto)); Survey survey = campaign.getSurvey(); survey.getCampaigns().add(campaign); surveyService.insertOrUpdateSurvey(survey); @@ -170,44 +143,34 @@ public ResponseEntity putCampaign(@PathVariable("id") String id, @RequestBody @Operation(summary = "Delete a campaign, its campaigns, partitionings, questionings ...") @DeleteMapping(value = {Constants.API_CAMPAIGNS_ID, Constants.MOOG_API_CAMPAIGNS_ID}) - @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "No Content"), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad Request") - }) + @Transactional - public ResponseEntity deleteCampaign(@PathVariable("id") String id) { - if(campaignService.isCampaignOngoing(id)){ - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Campaign is still ongoing and can't be deleted"); + public void deleteCampaign(@PathVariable("id") String id) throws fr.insee.survey.datacollectionmanagement.exception.NotFoundException { + + if (campaignService.isCampaignOngoing(id)) { + throw new ImpossibleToDeleteException("Campaign is still ongoing and can't be deleted"); } - try { - Optional campaign = campaignService.findById(id); - if (!campaign.isPresent()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Campaign does not exist"); - } - - int nbQuestioningDeleted = 0; - Survey survey = campaign.get().getSurvey(); - survey.getCampaigns().remove(campaign.get()); - surveyService.insertOrUpdateSurvey(survey); - List uploadsCamp = uploadService.findAllByIdCampaign(id); - campaignService.deleteCampaignById(id); - Set listPartitionings = campaign.get().getPartitionings(); - - int nbViewDeleted = viewService.deleteViewsOfOneCampaign(campaign.get()); - - for (Partitioning partitioning : listPartitionings) { - nbQuestioningDeleted += questioningService.deleteQuestioningsOfOnePartitioning(partitioning); - } - uploadsCamp.stream().forEach(up->uploadService.delete(up)); - log.info("Campaign {} deleted with all its metadata children - {} questioning deleted - {} view deleted - {} uploads deleted", - id, - nbQuestioningDeleted, nbViewDeleted, uploadsCamp.size()); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Campaign deleted"); - } catch (Exception e) { - e.printStackTrace(); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); + + Campaign campaign = campaignService.findById(id); + + int nbQuestioningDeleted = 0; + Survey survey = campaign.getSurvey(); + survey.getCampaigns().remove(campaign); + surveyService.insertOrUpdateSurvey(survey); + List uploadsCamp = uploadService.findAllByIdCampaign(id); + campaignService.deleteCampaignById(id); + Set listPartitionings = campaign.getPartitionings(); + + int nbViewDeleted = viewService.deleteViewsOfOneCampaign(campaign); + + for (Partitioning partitioning : listPartitionings) { + nbQuestioningDeleted += questioningService.deleteQuestioningsOfOnePartitioning(partitioning); } + uploadsCamp.forEach(uploadService::delete); + log.info("Campaign {} deleted with all its metadata children - {} questioning deleted - {} view deleted - {} uploads deleted", + id, + nbQuestioningDeleted, nbViewDeleted, uploadsCamp.size()); + } @Operation(summary = "campaign is ongoing") @@ -216,19 +179,20 @@ public ResponseEntity deleteCampaign(@PathVariable("id") String id) { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = OnGoingDto.class))), @ApiResponse(responseCode = "404", description = "Not found") }) - public ResponseEntity isOnGoingCampaign(@PathVariable("id") String id) { - try { - boolean isOnGoing = campaignService.isCampaignOngoing(id); - return ResponseEntity.ok().body(new OnGoingDto(isOnGoing)); - } catch (NotFoundException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Campaign does not exist"); - } + public ResponseEntity isOnGoingCampaign(@PathVariable("id") String id) { + boolean isOnGoing = campaignService.isCampaignOngoing(id); + return ResponseEntity.ok().body(new OnGoingDto(isOnGoing)); + } private CampaignDto convertToDto(Campaign campaign) { return modelmapper.map(campaign, CampaignDto.class); } + private CampaignPartitioningsDto convertToCampaignPartitioningsDto(Campaign campaign) { + return modelmapper.map(campaign, CampaignPartitioningsDto.class); + } + private Campaign convertToEntity(CampaignDto campaignDto) { return modelmapper.map(campaignDto, Campaign.class); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/MetadataController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/MetadataController.java index 477ad481..f748cfb1 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/MetadataController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/MetadataController.java @@ -1,26 +1,18 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; +import fr.insee.survey.datacollectionmanagement.config.JSONCollectionWrapper; import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; -import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignDto; -import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; -import fr.insee.survey.datacollectionmanagement.query.domain.MoogCampaign; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; - -import fr.insee.survey.datacollectionmanagement.config.JSONCollectionWrapper; import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignMoogDto; import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; +import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; import java.util.Date; -import java.util.List; -import java.util.Optional; @RestController @Slf4j @@ -28,13 +20,12 @@ @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") +@RequiredArgsConstructor public class MetadataController { - @Autowired - CampaignService campaignService; + private final CampaignService campaignService; - @Autowired - PartitioningService partitioningService; + private final PartitioningService partitioningService; @GetMapping(value = Constants.MOOG_API_CAMPAIGNS) public JSONCollectionWrapper displayCampaignInProgress() { @@ -45,18 +36,14 @@ public JSONCollectionWrapper displayCampaignInProgress() { @PutMapping(value = Constants.MOOG_API_CAMPAIGNS_ID) public void updateCampaignInProgressMoog(@PathVariable("id") String id, @RequestBody CampaignMoogDto campaignMoogDto) { log.info("Updating Moog campaign with id " + id); - Optional campaign = campaignService.findById(id); - if(!campaign.isPresent()) - { - - } - campaign.get().getPartitionings().stream().forEach(p->{ + Campaign campaign = campaignService.findById(id); + campaign.getPartitionings().stream().forEach(p->{ p.setClosingDate(new Date(campaignMoogDto.getCollectionEndDate())); p.setOpeningDate(new Date(campaignMoogDto.getCollectionStartDate())); partitioningService.insertOrUpdatePartitioning(p); }); - campaign.get().setCampaignWording(campaignMoogDto.getLabel()); - campaignService.insertOrUpdateCampaign(campaign.get()); + campaign.setCampaignWording(campaignMoogDto.getLabel()); + campaignService.insertOrUpdateCampaign(campaign); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/OwnerController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/OwnerController.java index 77ddbed8..1a1eb574 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/OwnerController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/OwnerController.java @@ -1,40 +1,27 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Owner; import fr.insee.survey.datacollectionmanagement.metadata.dto.OwnerDto; import fr.insee.survey.datacollectionmanagement.metadata.service.OwnerService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.List; @RestController @CrossOrigin @@ -43,57 +30,39 @@ + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "3 - Metadata", description = "Enpoints to create, update, delete and find entities in metadata domain") +@RequiredArgsConstructor +@Validated public class OwnerController { - @Autowired - private ModelMapper modelmapper; + private final ModelMapper modelmapper; - @Autowired - private OwnerService ownerService; + private final OwnerService ownerService; @Operation(summary = "Search for owners, paginated") @GetMapping(value = Constants.API_OWNERS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = OwnerPage.class))) - }) - public ResponseEntity getOwners( + public ResponseEntity getOwners( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "id") String sort) { Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); Page pageOwner = ownerService.findAll(pageable); - List listOwners = pageOwner.stream().map(c -> convertToDto(c)).collect(Collectors.toList()); + List listOwners = pageOwner.stream().map(this::convertToDto).toList(); return ResponseEntity.ok().body(new OwnerPage(listOwners, pageable, pageOwner.getTotalElements())); } @Operation(summary = "Search for a owner by its id") @GetMapping(value = Constants.API_OWNERS_ID, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = OwnerDto.class))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity getOwner(@PathVariable("id") String id) { - Optional owner = ownerService.findById(id); - if (!owner.isPresent()) { - log.warn("Owner {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("owner does not exist"); - } - owner = ownerService.findById(id); - return ResponseEntity.ok().body(convertToDto(owner.orElse(null))); + public ResponseEntity getOwner(@PathVariable("id") String id) { + Owner owner = ownerService.findById(id); + return ResponseEntity.ok().body(convertToDto(owner)); } @Operation(summary = "Update or create a owner") @PutMapping(value = Constants.API_OWNERS_ID, produces = "application/json", consumes = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = OwnerDto.class))), - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = OwnerDto.class))), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity putOwner(@PathVariable("id") String id, @RequestBody OwnerDto ownerDto) { + public ResponseEntity putOwner(@PathVariable("id") String id, @RequestBody @Valid OwnerDto ownerDto) { if (!ownerDto.getId().equals(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and owner id don't match"); + throw new NotMatchException("id and owner id don't match"); } HttpHeaders responseHeaders = new HttpHeaders(); @@ -101,19 +70,21 @@ public ResponseEntity putOwner(@PathVariable("id") String id, @RequestBody Ow ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(ownerDto.getId()).toUriString()); HttpStatus httpStatus; - log.warn("Update owner with the id {}", ownerDto.getId()); - Optional ownerBase = ownerService.findById(id); - httpStatus = HttpStatus.OK; + try { + Owner ownerBase = ownerService.findById(id); + log.warn("Update owner with the id {}", ownerDto.getId()); + httpStatus = HttpStatus.OK; - if (!ownerBase.isPresent()) { + } catch (NotFoundException e) { log.info("Create owner with the id {}", ownerDto.getId()); httpStatus = HttpStatus.CREATED; } + Owner owner = ownerService.insertOrUpdateOwner(convertToEntity(ownerDto)); return ResponseEntity.status(httpStatus).headers(responseHeaders).body(convertToDto(owner)); } - + private OwnerDto convertToDto(Owner owner) { return modelmapper.map(owner, OwnerDto.class); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/PartitioningController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/PartitioningController.java index 736d45fd..265633db 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/PartitioningController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/PartitioningController.java @@ -1,28 +1,8 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.dto.PartitioningDto; @@ -30,13 +10,26 @@ import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.List; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -44,62 +37,34 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "3 - Metadata", description = "Enpoints to create, update, delete and find entities in metadata domain") @Slf4j +@RequiredArgsConstructor public class PartitioningController { - @Autowired - private PartitioningService partitioningService; + private final PartitioningService partitioningService; - @Autowired - private CampaignService campaignService; + private final CampaignService campaignService; - @Autowired - private ModelMapper modelmapper; + private final ModelMapper modelmapper; - @Autowired - private QuestioningService questioningService; + private final QuestioningService questioningService; @Operation(summary = "Search for partitionings by the campaign id") @GetMapping(value = Constants.API_CAMPAIGNS_ID_PARTITIONINGS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = PartitioningDto.class)))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity getPartitioningsByCampaign(@PathVariable("id") String id) { - try { - Optional campaign = campaignService.findById(id); - if (!campaign.isPresent()) { - log.warn("Campaign {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("campaign does not exist"); - } - return ResponseEntity.ok() - .body(campaign.get().getPartitionings().stream().map(s -> convertToDto(s)) - .collect(Collectors.toList())); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity> getPartitioningsByCampaign(@PathVariable("id") String id) { + Campaign campaign = campaignService.findById(id); + return ResponseEntity.ok() + .body(campaign.getPartitionings().stream().map(this::convertToDto) + .toList()); + } @Operation(summary = "Search for a partitioning by its id") @GetMapping(value = Constants.API_PARTITIONINGS_ID, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = PartitioningDto.class))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity getPartitioning(@PathVariable("id") String id) { - try { - Optional partitioning = partitioningService.findById(StringUtils.upperCase(id)); - if (!partitioning.isPresent()) { - log.warn("Partitioning {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("partitioning does not exist"); - } - return ResponseEntity.ok().body(convertToDto(partitioning.get())); - - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity getPartitioning(@PathVariable("id") String id) { + Partitioning partitioning = partitioningService.findById(StringUtils.upperCase(id)); + return ResponseEntity.ok().body(convertToDto(partitioning)); + } @@ -110,29 +75,28 @@ public ResponseEntity getPartitioning(@PathVariable("id") String id) { @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = PartitioningDto.class))), @ApiResponse(responseCode = "400", description = "Bad request") }) - public ResponseEntity putPartitioning(@PathVariable("id") String id, - @RequestBody PartitioningDto partitioningDto) { - if (StringUtils.isBlank(partitioningDto.getId()) || !partitioningDto.getId().equalsIgnoreCase(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and idPartitioning don't match"); + public ResponseEntity putPartitioning(@PathVariable("id") String id, + @RequestBody PartitioningDto partitioningDto) { + if (!partitioningDto.getId().equalsIgnoreCase(id)) { + throw new NotMatchException("id and owner id don't match"); } Partitioning partitioning; - if (!campaignService.findById(partitioningDto.getCampaignId()).isPresent()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Campaign does not exist"); - } + HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set(HttpHeaders.LOCATION, ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(partitioningDto.getId()).toUriString()); HttpStatus httpStatus; - if (partitioningService.findById(id).isPresent()) { - log.info("Update partitioning with the id {}", partitioningDto.getId()); + try { partitioningService.findById(id); + log.info("Update partitioning with the id {}", partitioningDto.getId()); httpStatus = HttpStatus.OK; - } else { + } catch (NotFoundException e) { log.info("Create partitioning with the id {}", partitioningDto.getId()); httpStatus = HttpStatus.CREATED; } + partitioning = partitioningService.insertOrUpdatePartitioning(convertToEntity(partitioningDto)); Campaign campaign = partitioning.getCampaign(); campaign.getPartitionings().add(partitioning); @@ -142,30 +106,17 @@ public ResponseEntity putPartitioning(@PathVariable("id") String id, @Operation(summary = "Delete a partitioning, its partitionings, partitionings, questionings ...") @DeleteMapping(value = Constants.API_PARTITIONINGS_ID) - @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "No Content"), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad Request") - }) @Transactional - public ResponseEntity deletePartitioning(@PathVariable("id") String id) { - try { - Optional partitioning = partitioningService.findById(id); - if (!partitioning.isPresent()) { - log.warn("Partitioning {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Partitioning does not exist"); - } - Campaign campaign = partitioning.get().getCampaign(); - campaign.getPartitionings().remove(partitioning.get()); - campaignService.insertOrUpdateCampaign(campaign); - partitioningService.deletePartitioningById(id); - - int nbQuestioningDeleted = questioningService.deleteQuestioningsOfOnePartitioning(partitioning.get()); - log.info("Partitioning {} deleted - {} questionings deleted", id, nbQuestioningDeleted); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Partitioning deleted"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public void deletePartitioning(@PathVariable("id") String id) { + Partitioning partitioning = partitioningService.findById(id); + Campaign campaign = partitioning.getCampaign(); + campaign.getPartitionings().remove(partitioning); + campaignService.insertOrUpdateCampaign(campaign); + partitioningService.deletePartitioningById(id); + + int nbQuestioningDeleted = questioningService.deleteQuestioningsOfOnePartitioning(partitioning); + log.info("Partitioning {} deleted - {} questionings deleted", id, nbQuestioningDeleted); + } private PartitioningDto convertToDto(Partitioning partitioning) { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/PeriodPeriodicityController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/PeriodPeriodicityController.java index 530f45ba..ea386ddc 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/PeriodPeriodicityController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/PeriodPeriodicityController.java @@ -1,24 +1,24 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.fasterxml.jackson.core.JsonProcessingException; - import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.metadata.dto.PeriodDto; +import fr.insee.survey.datacollectionmanagement.metadata.dto.PeriodicityDto; import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; +@Slf4j @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " @@ -28,59 +28,38 @@ public class PeriodPeriodicityController { @Operation(summary = "Search for periodicities") @GetMapping(value = Constants.API_PERIODICITIES, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK") - }) - public ResponseEntity getPeriodicities() throws JsonProcessingException, JSONException { - JSONArray jsonArray = new JSONArray(); + public ResponseEntity> getPeriodicities() { + List periodicities = new ArrayList<>(); for (PeriodicityEnum periodicity : PeriodicityEnum.values()) { - JSONObject json = new JSONObject(); - json.put("key", periodicity.name()); - json.put("label", periodicity.getValue()); - jsonArray.put(json); + periodicities.add(new PeriodicityDto(periodicity.name(),periodicity.getValue())); } - return ResponseEntity.ok().body(jsonArray.toString()); + return ResponseEntity.ok().body(periodicities); } @Operation(summary = "Search for periods") @GetMapping(value = Constants.API_PERIODS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK") - }) - public ResponseEntity getPeriods() throws JsonProcessingException, JSONException { - JSONArray jsonArray = new JSONArray(); - + public ResponseEntity> getPeriods() { + List periods = new ArrayList<>(); for (PeriodEnum period : PeriodEnum.values()) { - JSONObject json = new JSONObject(); - json.put("key", period.name()); - json.put("label", period.getValue()); - json.put("period",period.getPeriod().name()); - jsonArray.put(json); + periods.add(new PeriodDto(period.name(), period.getValue(), period.getPeriod().getValue())); } - return ResponseEntity.ok().body(jsonArray.toString()); + return ResponseEntity.ok().body(periods); } @Operation(summary = "Search for periods of a periodicity") @GetMapping(value = Constants.API_PERIODICITIES_ID_PERIODS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK") - }) - public ResponseEntity getPeriodsOdPeriodicity(String periodicity) throws JsonProcessingException, JSONException { + public ResponseEntity> getPeriodsOfPeriodicity(@PathVariable("periodicity") String periodicity) { try { PeriodicityEnum.valueOf(periodicity); - JSONArray jsonArray = new JSONArray(); + List periods = new ArrayList<>(); for (PeriodEnum period : PeriodEnum.values()) { if (period.getPeriod().equals(PeriodicityEnum.valueOf(periodicity))) { - JSONObject json = new JSONObject(); - json.put("key", period.name()); - json.put("label", period.getValue()); - json.put("period",period.getPeriod().name()); - jsonArray.put(json); + periods.add(new PeriodDto(period.name(), period.getValue(),period.getPeriod().getValue())); } } - return ResponseEntity.ok().body(jsonArray.toString()); + return ResponseEntity.ok().body(periods); } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("periodicity does not exist"); + throw new NotFoundException("periodicity does not exist"); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SourceController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SourceController.java index 7cd69979..6a6f1367 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SourceController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SourceController.java @@ -1,52 +1,37 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Owner; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; import fr.insee.survey.datacollectionmanagement.metadata.dto.SourceCompleteDto; -import fr.insee.survey.datacollectionmanagement.metadata.dto.SurveyDto; import fr.insee.survey.datacollectionmanagement.metadata.service.OwnerService; import fr.insee.survey.datacollectionmanagement.metadata.service.SourceService; import fr.insee.survey.datacollectionmanagement.metadata.service.SupportService; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import fr.insee.survey.datacollectionmanagement.view.service.ViewService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.ArrayList; +import java.util.List; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -54,69 +39,49 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "3 - Metadata", description = "Enpoints to create, update, delete and find entities in metadata domain") @Slf4j +@RequiredArgsConstructor +@Validated public class SourceController { - @Autowired - private SourceService sourceService; + private final SourceService sourceService; - @Autowired - private OwnerService ownerService; + private final OwnerService ownerService; - @Autowired - private SupportService supportService; + private final SupportService supportService; - @Autowired - private ViewService viewService; + private final ViewService viewService; - @Autowired - private ModelMapper modelmapper; + private final ModelMapper modelmapper; - @Autowired - private QuestioningService questioningService; + private final QuestioningService questioningService; @Operation(summary = "Search for sources, paginated") @GetMapping(value = Constants.API_SOURCES, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SourcePage.class))) - }) - public ResponseEntity getSources( + public ResponseEntity getSources( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "id") String sort) { Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); Page pageSource = sourceService.findAll(pageable); - List listSources = pageSource.stream().map(c -> convertToDto(c)).collect(Collectors.toList()); + List listSources = pageSource.stream().map(this::convertToDto).toList(); return ResponseEntity.ok().body(new SourcePage(listSources, pageable, pageSource.getTotalElements())); } @Operation(summary = "Search for a source by its id") @GetMapping(value = Constants.API_SOURCES_ID, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SourceCompleteDto.class))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity getSource(@PathVariable("id") String id) { - Optional source = sourceService.findById(StringUtils.upperCase(id)); - if (!source.isPresent()) { - log.warn("Source {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("source does not exist"); - } + public ResponseEntity getSource(@PathVariable("id") String id) { + Source source = sourceService.findById(StringUtils.upperCase(id)); source = sourceService.findById(StringUtils.upperCase(id)); - return ResponseEntity.ok().body(convertToDto(source.orElse(null))); + return ResponseEntity.ok().body(convertToDto(source)); } @Operation(summary = "Update or create a source") @PutMapping(value = Constants.API_SOURCES_ID, produces = "application/json", consumes = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SourceCompleteDto.class))), - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = SourceCompleteDto.class))), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity putSource(@PathVariable("id") String id, @RequestBody SourceCompleteDto SourceCompleteDto) { - if (StringUtils.isBlank(SourceCompleteDto.getId()) || !SourceCompleteDto.getId().equalsIgnoreCase(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and source id don't match"); + public ResponseEntity putSource(@PathVariable("id") String id, @RequestBody @Valid SourceCompleteDto SourceCompleteDto) { + if (!SourceCompleteDto.getId().equalsIgnoreCase(id)) { + throw new NotMatchException("id and source id don't match"); + } Source source; @@ -124,88 +89,65 @@ public ResponseEntity putSource(@PathVariable("id") String id, @RequestBody S responseHeaders.set(HttpHeaders.LOCATION, ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(SourceCompleteDto.getId()).toUriString()); HttpStatus httpStatus; - - if (sourceService.findById(id).isPresent()) { + try { + sourceService.findById(id); log.warn("Update source with the id {}", SourceCompleteDto.getId()); httpStatus = HttpStatus.OK; - } else { + } catch (NotFoundException e) { log.info("Create source with the id {}", SourceCompleteDto.getId()); httpStatus = HttpStatus.CREATED; } + source = sourceService.insertOrUpdateSource(convertToEntity(SourceCompleteDto)); if (source.getOwner() != null && httpStatus.equals(HttpStatus.CREATED)) ownerService.addSourceFromOwner(source.getOwner(), source); - if (source.getSupport()!=null&& httpStatus.equals(HttpStatus.CREATED)) + if (source.getSupport() != null && httpStatus.equals(HttpStatus.CREATED)) supportService.addSourceFromSupport(source.getSupport(), source); - + return ResponseEntity.status(httpStatus).headers(responseHeaders).body(convertToDto(source)); } @Operation(summary = "Delete a source, its surveys, campaigns, partitionings, questionings ...") @DeleteMapping(value = Constants.API_SOURCES_ID) - @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "No Content"), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad Request") - }) + @ResponseStatus(HttpStatus.NO_CONTENT) @Transactional - public ResponseEntity deleteSource(@PathVariable("id") String id) { + public void deleteSource(@PathVariable("id") String id) { int nbQuestioningDeleted = 0, nbViewDeleted = 0; - try { - Optional source = sourceService.findById(id); - if (!source.isPresent()) { - log.warn("Source {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("source does not exist"); - } - if (source.get().getOwner() != null) - ownerService.removeSourceFromOwner(source.get().getOwner(), source.get()); - - if (source.get().getSupport()!=null) - supportService.removeSourceFromSupport(source.get().getSupport(), source.get()); - - sourceService.deleteSourceById(id); - List listCampaigns = new ArrayList<>(); - List listPartitionings = new ArrayList<>(); - - source.get().getSurveys().stream().forEach(su -> listCampaigns.addAll(su.getCampaigns())); - source.get().getSurveys().stream().forEach( - su -> su.getCampaigns().stream().forEach(c -> listPartitionings.addAll(c.getPartitionings()))); - - for (Campaign campaign : listCampaigns) { - nbViewDeleted += viewService.deleteViewsOfOneCampaign(campaign); - } - for (Partitioning partitioning : listPartitionings) { - nbQuestioningDeleted += questioningService.deleteQuestioningsOfOnePartitioning(partitioning); - } - log.info("Source {} deleted with all its metadata children - {} questioning deleted - {} view deleted", id, - nbQuestioningDeleted, nbViewDeleted); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Source deleted"); - - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); + Source source = sourceService.findById(id); + + if (source.getOwner() != null) + ownerService.removeSourceFromOwner(source.getOwner(), source); + + if (source.getSupport() != null) + supportService.removeSourceFromSupport(source.getSupport(), source); + + sourceService.deleteSourceById(id); + List listCampaigns = new ArrayList<>(); + List listPartitionings = new ArrayList<>(); + + source.getSurveys().stream().forEach(su -> listCampaigns.addAll(su.getCampaigns())); + source.getSurveys().stream().forEach( + su -> su.getCampaigns().stream().forEach(c -> listPartitionings.addAll(c.getPartitionings()))); + + for (Campaign campaign : listCampaigns) { + nbViewDeleted += viewService.deleteViewsOfOneCampaign(campaign); } + for (Partitioning partitioning : listPartitionings) { + nbQuestioningDeleted += questioningService.deleteQuestioningsOfOnePartitioning(partitioning); + } + log.info("Source {} deleted with all its metadata children - {} questioning deleted - {} view deleted", id, + nbQuestioningDeleted, nbViewDeleted); + } @Operation(summary = "Search for surveys by the owner id") @GetMapping(value = Constants.API_OWNERS_ID_SOURCES, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = SurveyDto.class)))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) public ResponseEntity getSourcesByOwner(@PathVariable("id") String id) { + Owner owner = ownerService.findById(id); + return ResponseEntity.ok() + .body(owner.getSources().stream().map(this::convertToDto).toList()); - try { - Optional owner = ownerService.findById(id); - if (!owner.isPresent()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("owner does not exist"); - } - return ResponseEntity.ok() - .body(owner.get().getSources().stream().map(s -> convertToDto(s)).collect(Collectors.toList())); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SupportController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SupportController.java index 030c30b7..d5d027f4 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SupportController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SupportController.java @@ -1,40 +1,27 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Support; import fr.insee.survey.datacollectionmanagement.metadata.dto.SupportDto; import fr.insee.survey.datacollectionmanagement.metadata.service.SupportService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.List; @RestController @CrossOrigin @@ -43,73 +30,56 @@ + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "3 - Metadata", description = "Enpoints to create, update, delete and find entities in metadata domain") +@RequiredArgsConstructor +@Validated public class SupportController { - @Autowired - private ModelMapper modelmapper; + private final ModelMapper modelmapper; - @Autowired - private SupportService supportService; + private final SupportService supportService; @Operation(summary = "Search for supports, paginated") @GetMapping(value = Constants.API_SUPPORTS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SupportPage.class))) - }) - public ResponseEntity getSupports( + public ResponseEntity getSupports( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "id") String sort) { Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); Page pageSupport = supportService.findAll(pageable); - List listSupports = pageSupport.stream().map(c -> convertToDto(c)).collect(Collectors.toList()); + List listSupports = pageSupport.stream().map(this::convertToDto).toList(); return ResponseEntity.ok().body(new SupportPage(listSupports, pageable, pageSupport.getTotalElements())); } @Operation(summary = "Search for a support by its id") @GetMapping(value = Constants.API_SUPPORTS_ID, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SupportDto.class))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity getSupport(@PathVariable("id") String id) { - Optional support = supportService.findById(id); - if (!support.isPresent()) { - log.warn("Support {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("support does not exist"); - } - support = supportService.findById(id); - return ResponseEntity.ok().body(convertToDto(support.orElse(null))); + public ResponseEntity getSupport(@PathVariable("id") String id) { + Support support = supportService.findById(id); + return ResponseEntity.ok().body(convertToDto(support)); } @Operation(summary = "Update or create a support") @PutMapping(value = Constants.API_SUPPORTS_ID, produces = "application/json", consumes = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SupportDto.class))), - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = SupportDto.class))), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity putSupport(@PathVariable("id") String id, @RequestBody SupportDto supportDto) { + public ResponseEntity putSupport(@PathVariable("id") String id, @RequestBody @Valid SupportDto supportDto) { if (!supportDto.getId().equals(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and support id don't match"); + throw new NotMatchException("id and support id don't match"); } HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set(HttpHeaders.LOCATION, ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(supportDto.getId()).toUriString()); HttpStatus httpStatus; + try { + supportService.findById(id); + log.info("Update support with the id {}", supportDto.getId()); + httpStatus = HttpStatus.OK; - log.warn("Update support with the id {}", supportDto.getId()); - Optional supportBase = supportService.findById(id); - httpStatus = HttpStatus.OK; - - if (!supportBase.isPresent()) { + } catch (NotFoundException e) { log.info("Create support with the id {}", supportDto.getId()); httpStatus = HttpStatus.CREATED; } + Support support = supportService.insertOrUpdateSupport(convertToEntity(supportDto)); return ResponseEntity.status(httpStatus).headers(responseHeaders).body(convertToDto(support)); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SurveyController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SurveyController.java index 1480f8a5..74dd99a5 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SurveyController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SurveyController.java @@ -1,29 +1,8 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; @@ -34,13 +13,23 @@ import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import fr.insee.survey.datacollectionmanagement.view.service.ViewService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.ArrayList; +import java.util.List; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -48,77 +37,71 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "3 - Metadata", description = "Enpoints to create, update, delete and find entities in metadata domain") @Slf4j +@RequiredArgsConstructor public class SurveyController { - @Autowired - private SurveyService surveyService; + private final SurveyService surveyService; + + private final SourceService sourceService; - @Autowired - private SourceService sourceService; + private final ViewService viewService; - @Autowired - private ViewService viewService; + private final ModelMapper modelmapper; - @Autowired - private ModelMapper modelmapper; - - @Autowired - private QuestioningService questioningService; + private final QuestioningService questioningService; + @Operation(summary = "Search for surveys, paginated") + @GetMapping(value = Constants.API_SURVEYS, produces = "application/json") + public ResponseEntity getSurveys( + @RequestParam(defaultValue = "0") Integer page, + @RequestParam(defaultValue = "20") Integer size, + @RequestParam(defaultValue = "id") String sort) { + Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); + Page pageSurvey = surveyService.findAll(pageable); + List listSurveys = pageSurvey.stream().map(this::convertToDto).toList(); + return ResponseEntity.ok().body(new SurveyController.SurveyPage(listSurveys, pageable, pageSurvey.getTotalElements())); + } + + @Operation(summary = "Search for surveys, paginated") + @GetMapping(value = Constants.API_SURVEYS_SEARCH, produces = "application/json") + public ResponseEntity getSurveys( + @RequestParam(required = false) String idSource, + @RequestParam(required = false) Integer year, + @RequestParam(required = false) String periodicity, + @RequestParam(defaultValue = "0") Integer page, + @RequestParam(defaultValue = "20") Integer size, + @RequestParam(defaultValue = "id") String sort) { + Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); + Page pageSurvey = surveyService.findBySourceIdYearPeriodicity(pageable, idSource, year, periodicity); + List listSurveys = pageSurvey.stream().map(this::convertToDto).toList(); + return ResponseEntity.ok().body(new SurveyController.SurveyPage(listSurveys, pageable, pageSurvey.getTotalElements())); + } @Operation(summary = "Search for surveys by the source id") @GetMapping(value = Constants.API_SOURCES_ID_SURVEYS, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = SurveyDto.class)))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity getSurveysBySource(@PathVariable("id") String id) { + public ResponseEntity> getSurveysBySource(@PathVariable("id") String id) { + Source source = sourceService.findById(id); + return ResponseEntity.ok() + .body(source.getSurveys().stream().map(this::convertToDto).toList()); - try { - Optional source = sourceService.findById(id); - if (!source.isPresent()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("source does not exist"); - } - return ResponseEntity.ok() - .body(source.get().getSurveys().stream().map(s -> convertToDto(s)).collect(Collectors.toList())); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } } @Operation(summary = "Search for a survey by its id") @GetMapping(value = Constants.API_SURVEYS_ID, produces = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SurveyDto.class))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity getSurvey(@PathVariable("id") String id) { - try { - Optional survey = surveyService.findById(StringUtils.upperCase(id)); - if (!survey.isPresent()) { - log.warn("Survey {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("survey does not exist"); - } - return ResponseEntity.ok().body(convertToDto(survey.get())); - - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity getSurvey(@PathVariable("id") String id) { + Survey survey = surveyService.findById(StringUtils.upperCase(id)); + return ResponseEntity.ok().body(convertToDto(survey)); + } @Operation(summary = "Update or create a survey") @PutMapping(value = Constants.API_SURVEYS_ID, produces = "application/json", consumes = "application/json") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SurveyDto.class))), - @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = SurveyDto.class))), - @ApiResponse(responseCode = "400", description = "Bad request") - }) - public ResponseEntity putSurvey(@PathVariable("id") String id, @RequestBody SurveyDto surveyDto) { - if (StringUtils.isBlank(surveyDto.getId()) || !surveyDto.getId().equalsIgnoreCase(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and idSurvey don't match"); + public ResponseEntity putSurvey(@PathVariable("id") String id, @RequestBody @Valid SurveyDto surveyDto) { + if (!surveyDto.getId().equalsIgnoreCase(id)) { + throw new NotMatchException("id and idSurvey don't match"); + + } Survey survey; HttpHeaders responseHeaders = new HttpHeaders(); @@ -126,11 +109,11 @@ public ResponseEntity putSurvey(@PathVariable("id") String id, @RequestBody S ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(surveyDto.getId()).toUriString()); HttpStatus httpStatus; - if (surveyService.findById(id).isPresent()) { + try { + surveyService.findById(id); log.info("Update survey with the id {}", surveyDto.getId()); httpStatus = HttpStatus.OK; - - } else { + } catch (NotFoundException e) { log.info("Creating survey with the id {}", surveyDto.getId()); httpStatus = HttpStatus.CREATED; } @@ -144,54 +127,40 @@ public ResponseEntity putSurvey(@PathVariable("id") String id, @RequestBody S @Operation(summary = "Delete a survey, its campaigns, partitionings, questionings ...") @DeleteMapping(value = Constants.API_SURVEYS_ID) - @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "No Content"), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad Request") - }) + @ResponseStatus(HttpStatus.NO_CONTENT) @Transactional - public ResponseEntity deleteSurvey(@PathVariable("id") String id) { + public void deleteSurvey(@PathVariable("id") String id) { + Survey survey = surveyService.findById(id); - try { - Optional survey = surveyService.findById(id); - if (!survey.isPresent()) { - log.warn("Survey {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Survey does not exist"); - } - - int nbQuestioningDeleted = 0; - int nbViewDeleted = 0; - - Source source = survey.get().getSource(); - source.getSurveys().remove(survey.get()); - sourceService.insertOrUpdateSource(source); - surveyService.deleteSurveyById(id); - List listPartitionings = new ArrayList<>(); - - survey.get().getCampaigns().stream().forEach(c -> listPartitionings.addAll(c.getPartitionings())); - - for (Campaign campaign : survey.get().getCampaigns()) { - viewService.findViewByCampaignId(campaign.getId()).stream() - .forEach(v -> viewService.deleteView(v)); - } - for (Partitioning partitioning : listPartitionings) { - questioningService.findByIdPartitioning(partitioning.getId()).stream() - .forEach(q -> questioningService.deleteQuestioning(q.getId())); - } - - for (Campaign campaign : survey.get().getCampaigns()) { - nbViewDeleted += viewService.deleteViewsOfOneCampaign(campaign); - } - for (Partitioning partitioning : listPartitionings) { - nbQuestioningDeleted += questioningService.deleteQuestioningsOfOnePartitioning(partitioning); - } - log.info("Source {} deleted and all its metadata children - {} questioning deleted - {} view deleted", id, - nbQuestioningDeleted, nbViewDeleted); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Survey deleted"); - - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); + int nbQuestioningDeleted = 0; + int nbViewDeleted = 0; + + Source source = survey.getSource(); + source.getSurveys().remove(survey); + sourceService.insertOrUpdateSource(source); + surveyService.deleteSurveyById(id); + List listPartitionings = new ArrayList<>(); + + survey.getCampaigns().stream().forEach(c -> listPartitionings.addAll(c.getPartitionings())); + + for (Campaign campaign : survey.getCampaigns()) { + viewService.findViewByCampaignId(campaign.getId()).stream() + .forEach(v -> viewService.deleteView(v)); } + for (Partitioning partitioning : listPartitionings) { + questioningService.findByIdPartitioning(partitioning.getId()).stream() + .forEach(q -> questioningService.deleteQuestioning(q.getId())); + } + + for (Campaign campaign : survey.getCampaigns()) { + nbViewDeleted += viewService.deleteViewsOfOneCampaign(campaign); + } + for (Partitioning partitioning : listPartitionings) { + nbQuestioningDeleted += questioningService.deleteQuestioningsOfOnePartitioning(partitioning); + } + log.info("Source {} deleted and all its metadata children - {} questioning deleted - {} view deleted", id, + nbQuestioningDeleted, nbViewDeleted); + } private SurveyDto convertToDto(Survey survey) { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Campaign.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Campaign.java index e7ec998e..26a15a1d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Campaign.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Campaign.java @@ -1,28 +1,14 @@ package fr.insee.survey.datacollectionmanagement.metadata.domain; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; - import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.ToString; +import jakarta.persistence.*; +import lombok.*; + +import java.util.Set; @Entity -@Data +@Getter +@Setter @NoArgsConstructor @Table(indexes = { @Index(name = "year_index", columnList = "year_value"), @@ -45,11 +31,9 @@ public class Campaign { private String campaignWording; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set partitionings; - @OneToOne + @ManyToOne private Survey survey; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/CampaignEvent.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/CampaignEvent.java index 5a7e5967..0e2686b6 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/CampaignEvent.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/CampaignEvent.java @@ -1,25 +1,18 @@ package fr.insee.survey.datacollectionmanagement.metadata.domain; -import java.util.Date; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToOne; +import jakarta.persistence.*; +import lombok.*; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.ToString; +import java.util.Date; @Entity -@Data +@Getter +@Setter @NoArgsConstructor public class CampaignEvent { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "campaign_event_seq") private Long id; @NonNull private String type; @@ -27,8 +20,6 @@ public class CampaignEvent { private Date date; @ManyToOne - @EqualsAndHashCode.Exclude - @ToString.Exclude private Campaign campaign; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Owner.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Owner.java index 4a17dc5d..f63ce85c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Owner.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Owner.java @@ -1,17 +1,16 @@ package fr.insee.survey.datacollectionmanagement.metadata.domain; -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import lombok.Getter; +import lombok.Setter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; +import java.util.Set; @Entity -@Data +@Getter +@Setter public class Owner { @Id @@ -22,8 +21,6 @@ public class Owner { private String logo; @OneToMany - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set sources; } \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Partitioning.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Partitioning.java index 7b2dcb68..29c661a2 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Partitioning.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Partitioning.java @@ -1,17 +1,14 @@ package fr.insee.survey.datacollectionmanagement.metadata.domain; -import java.util.Date; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; -import lombok.Data; +import java.util.Date; @Entity -@Data +@Getter +@Setter @Table(indexes = { @Index(name = "campainId_index", columnList = "campaign_id") }) @@ -24,7 +21,7 @@ public class Partitioning { private Date closingDate; private Date returnDate; - @OneToOne + @ManyToOne private Campaign campaign; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Source.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Source.java index 931661aa..8e47519a 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Source.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Source.java @@ -2,13 +2,14 @@ import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; import fr.insee.survey.datacollectionmanagement.user.domain.SourceAccreditation; +import jakarta.persistence.*; import lombok.*; -import javax.persistence.*; import java.util.Set; @Entity -@Data +@Getter +@Setter @NoArgsConstructor public class Source { @@ -23,20 +24,16 @@ public class Source { private Boolean mandatoryMySurveys; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set surveys; @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set sourceAccreditations; - @OneToOne + @ManyToOne @NonNull private Owner owner; - @OneToOne + @ManyToOne @NonNull private Support support; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Support.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Support.java index a4bd9438..101bc512 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Support.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Support.java @@ -1,17 +1,16 @@ package fr.insee.survey.datacollectionmanagement.metadata.domain; -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import lombok.Getter; +import lombok.Setter; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; +import java.util.Set; @Entity -@Data +@Getter +@Setter public class Support { @Id @@ -27,8 +26,6 @@ public class Support { private String zipCode; @OneToMany - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set sources; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Survey.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Survey.java index 63c0d8ca..2d65b999 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Survey.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/domain/Survey.java @@ -1,25 +1,13 @@ package fr.insee.survey.datacollectionmanagement.metadata.domain; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.*; +import lombok.*; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.ToString; +import java.util.Set; @Entity -@Data +@Getter +@Setter @NoArgsConstructor @Table(indexes = { @Index(name = "surveyyear_index", columnList = "year_value"), @@ -49,11 +37,9 @@ public class Survey { private String communication; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set campaigns; - @OneToOne + @ManyToOne private Source source; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/CampaignDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/CampaignDto.java index 41125197..67a1f4c6 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/CampaignDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/CampaignDto.java @@ -1,11 +1,13 @@ package fr.insee.survey.datacollectionmanagement.metadata.dto; import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; +import jakarta.validation.constraints.NotBlank; import lombok.Data; @Data public class CampaignDto { + @NotBlank private String id; private String surveyId; private int year; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/CampaignPartitioningsDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/CampaignPartitioningsDto.java new file mode 100644 index 00000000..7ba74db9 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/CampaignPartitioningsDto.java @@ -0,0 +1,19 @@ +package fr.insee.survey.datacollectionmanagement.metadata.dto; + +import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.util.List; + +@Data +public class CampaignPartitioningsDto { + + @NotBlank + private String id; + private String surveyId; + private int year; + private String campaignWording; + private PeriodEnum period; + private List partitionings; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/OwnerDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/OwnerDto.java index cd4047b1..3c4ecc6f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/OwnerDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/OwnerDto.java @@ -1,5 +1,6 @@ package fr.insee.survey.datacollectionmanagement.metadata.dto; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -7,6 +8,7 @@ @Setter public class OwnerDto { + @NotBlank private String id; private String label; private String ministry; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PartitioningDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PartitioningDto.java index 750b7680..8a18e185 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PartitioningDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PartitioningDto.java @@ -1,12 +1,14 @@ package fr.insee.survey.datacollectionmanagement.metadata.dto; -import java.util.Date; - +import jakarta.validation.constraints.NotBlank; import lombok.Data; +import java.util.Date; + @Data public class PartitioningDto { + @NotBlank private String id; private String campaignId; private String label; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PeriodDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PeriodDto.java new file mode 100644 index 00000000..f8639ce8 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PeriodDto.java @@ -0,0 +1,15 @@ +package fr.insee.survey.datacollectionmanagement.metadata.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +public class PeriodDto { + private String value; + private String label; + private String period; + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PeriodicityDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PeriodicityDto.java new file mode 100644 index 00000000..0ab5426a --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/PeriodicityDto.java @@ -0,0 +1,14 @@ +package fr.insee.survey.datacollectionmanagement.metadata.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +public class PeriodicityDto { + private String value; + private String label; + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SourceCompleteDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SourceCompleteDto.java index b2419eb3..806a40e0 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SourceCompleteDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SourceCompleteDto.java @@ -1,6 +1,7 @@ package fr.insee.survey.datacollectionmanagement.metadata.dto; import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -8,6 +9,7 @@ @Setter public class SourceCompleteDto { + @NotBlank private String id; private String longWording; private String shortWording; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SupportDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SupportDto.java index f0c110a7..8ae7c2e0 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SupportDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SupportDto.java @@ -1,5 +1,6 @@ package fr.insee.survey.datacollectionmanagement.metadata.dto; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -7,6 +8,7 @@ @Setter public class SupportDto { + @NotBlank private String id; private String label; private String phoneNumber; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SurveyDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SurveyDto.java index 6e8c7ed8..a408b27a 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SurveyDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/dto/SurveyDto.java @@ -1,15 +1,16 @@ package fr.insee.survey.datacollectionmanagement.metadata.dto; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; -import lombok.NonNull; import lombok.Setter; @Getter @Setter public class SurveyDto { + @NotBlank private String id; - @NonNull + @NotBlank private String sourceId; private Integer year; private Integer sampleSize; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/repository/CampaignRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/repository/CampaignRepository.java index b833760f..fb747c4d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/repository/CampaignRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/repository/CampaignRepository.java @@ -1,12 +1,11 @@ package fr.insee.survey.datacollectionmanagement.metadata.repository; -import java.util.List; - +import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; +import java.util.List; public interface CampaignRepository extends JpaRepository,PagingAndSortingRepository { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/repository/SurveyRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/repository/SurveyRepository.java index 902d3274..91cd701c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/repository/SurveyRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/repository/SurveyRepository.java @@ -1,13 +1,28 @@ package fr.insee.survey.datacollectionmanagement.metadata.repository; -import java.util.List; - +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; public interface SurveyRepository extends JpaRepository, PagingAndSortingRepository { - - List findByYear(int year); + + static final String QUERY_FIND_SURVEY = + """ + select + su.* + from + survey su + join source so + on (so.id=su.source_id) + where + (:sourceId is null or UPPER(su.source_id) = UPPER(cast( :sourceId as text))) + and (:periodicity is null or UPPER(so.periodicity) = UPPER(cast( :periodicity as text))) + and (:year is null or su.year_value = :year) + """; + @Query(nativeQuery = true, value = QUERY_FIND_SURVEY) + Page findBySourceIdYearPeriodicity(Pageable pageable, String sourceId, Integer year, String periodicity); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/CampaignService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/CampaignService.java index aff3fdb9..46ea6fd4 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/CampaignService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/CampaignService.java @@ -1,24 +1,21 @@ package fr.insee.survey.datacollectionmanagement.metadata.service; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - +import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; +import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignMoogDto; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; -import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignMoogDto; -import org.webjars.NotFoundException; +import java.util.Collection; +import java.util.List; @Service public interface CampaignService { Collection getCampaigns(); - Optional findById(String idCampaign); + Campaign findById(String idCampaign); List findbyPeriod(String period); @@ -38,7 +35,6 @@ public interface CampaignService { * Check if a campaign is ongoing, which means checks if all the partitiongs of the campaign are ongoing * @param idCampaign id of the campaign * @return true - * @throws NotFoundException if the campaign does not exist */ - boolean isCampaignOngoing(String idCampaign) throws NotFoundException; + boolean isCampaignOngoing(String idCampaign) ; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/OwnerService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/OwnerService.java index 586d2daf..2485f242 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/OwnerService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/OwnerService.java @@ -1,16 +1,13 @@ package fr.insee.survey.datacollectionmanagement.metadata.service; -import java.util.Optional; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - import fr.insee.survey.datacollectionmanagement.metadata.domain.Owner; import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; public interface OwnerService { - Optional findById(String owner); + Owner findById(String owner); Page findAll(Pageable pageable); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/PartitioningService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/PartitioningService.java index ea26e73f..88d46070 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/PartitioningService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/PartitioningService.java @@ -1,13 +1,12 @@ package fr.insee.survey.datacollectionmanagement.metadata.service; -import java.util.Date; -import java.util.Optional; - import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; +import java.util.Date; + public interface PartitioningService { - Optional findById(String id); + Partitioning findById(String id); Partitioning insertOrUpdatePartitioning(Partitioning partitioning); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SourceService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SourceService.java index d3494073..b676baf3 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SourceService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SourceService.java @@ -1,16 +1,13 @@ package fr.insee.survey.datacollectionmanagement.metadata.service; -import java.util.Optional; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; public interface SourceService { - Optional findById(String source); + Source findById(String source); Page findAll(Pageable pageable); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SupportService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SupportService.java index 0a773848..b10b3e59 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SupportService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SupportService.java @@ -1,17 +1,13 @@ package fr.insee.survey.datacollectionmanagement.metadata.service; -import java.util.Optional; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; import fr.insee.survey.datacollectionmanagement.metadata.domain.Support; -import lombok.NonNull; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; public interface SupportService { - Optional findById(String support); + Support findById(String support); Page findAll(Pageable pageable); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SurveyService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SurveyService.java index 69db9ff3..49ad1e7a 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SurveyService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/SurveyService.java @@ -1,19 +1,15 @@ package fr.insee.survey.datacollectionmanagement.metadata.service; -import java.util.List; -import java.util.Optional; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; public interface SurveyService { - List findByYear(int year); + Page findBySourceIdYearPeriodicity(Pageable pageable, String sourceId, Integer year, String periodicity); - Optional findById(String id); + Survey findById(String id); Page findAll(Pageable pageable); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/CampaignServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/CampaignServiceImpl.java index 9b0b0047..4f160827 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/CampaignServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/CampaignServiceImpl.java @@ -1,42 +1,28 @@ package fr.insee.survey.datacollectionmanagement.metadata.service.impl; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.dto.CampaignMoogDto; import fr.insee.survey.datacollectionmanagement.metadata.repository.CampaignRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; +import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.webjars.NotFoundException; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.*; @Service @Slf4j +@RequiredArgsConstructor public class CampaignServiceImpl implements CampaignService { - static final Logger LOGGER = LoggerFactory.getLogger(CampaignServiceImpl.class); - - @Autowired - CampaignRepository campaignRepository; + private final CampaignRepository campaignRepository; - @Autowired - PartitioningService partitioningService; + private final PartitioningService partitioningService; public Collection getCampaigns() { @@ -70,8 +56,8 @@ public List findbyPeriod(String period) { } @Override - public Optional findById(String idCampaign) { - return campaignRepository.findById(idCampaign); + public Campaign findById(String idCampaign) { + return campaignRepository.findById(idCampaign).orElseThrow(() -> new NotFoundException(String.format("Campaign %s not found", idCampaign))); } @Override @@ -91,14 +77,16 @@ public Page findAll(Pageable pageable) { @Override public Campaign insertOrUpdateCampaign(Campaign campaign) { - Optional campaignBase = findById(campaign.getId()); - if (!campaignBase.isPresent()) { + try { + Campaign campaignBase = findById(campaign.getId()); + log.info("Update campaign with the id {}", campaign.getId()); + campaign.setPartitionings(campaignBase.getPartitionings()); + + } catch (NotFoundException e) { log.info("Create campaign with the id {}", campaign.getId()); - return campaignRepository.save(campaign); } - log.info("Update campaign with the id {}", campaign.getId()); - campaign.setPartitionings(campaignBase.get().getPartitionings()); return campaignRepository.save(campaign); + } @Override @@ -108,15 +96,16 @@ public void deleteCampaignById(String id) { @Override public Campaign addPartitionigToCampaign(Campaign campaign, Partitioning partitioning) { - Optional campaignBase = findById(campaign.getId()); - if (campaignBase.isPresent() && isPartitioningPresent(partitioning, campaignBase.get())) { - campaign.setPartitionings(campaignBase.get().getPartitionings()); - } else { - Set partitionings = (!campaignBase.isPresent()) ? new HashSet<>() - : campaignBase.get().getPartitionings(); - partitionings.add(partitioning); - campaign.setPartitionings(partitionings); + Set partitionings; + try { + Campaign campaignBase = findById(campaign.getId()); + partitionings = campaignBase.getPartitionings(); + if (!isPartitioningPresent(partitioning, campaignBase)) + partitionings.add(partitioning); + } catch (NotFoundException e) { + partitionings = Set.of(partitioning); } + campaign.setPartitionings(partitionings); return campaign; } @@ -130,24 +119,21 @@ private boolean isPartitioningPresent(Partitioning p, Campaign c) { } @Override - public boolean isCampaignOngoing(String idCampaign) throws NotFoundException { - Optional camp = findById(idCampaign); + public boolean isCampaignOngoing(String idCampaign) { + Campaign camp = findById(idCampaign); - if (camp.isEmpty()) { - throw new NotFoundException("Campaign does not exist"); - } Date now = new Date(); int nbOnGoingParts = 0; - for (Partitioning part : camp.get().getPartitionings()) { + for (Partitioning part : camp.getPartitionings()) { if (partitioningService.isOnGoing(part, now)) { nbOnGoingParts++; - LOGGER.info("Partitiong {} of campaign {} is ongoing", part.getId(), idCampaign); + log.info("Partitiong {} of campaign {} is ongoing", part.getId(), idCampaign); } else { - LOGGER.info("Partitiong {} of campaign {} is closed", part.getId(), idCampaign); + log.info("Partitiong {} of campaign {} is closed", part.getId(), idCampaign); } } - return !camp.get().getPartitionings().isEmpty() && nbOnGoingParts == camp.get().getPartitionings().size(); + return !camp.getPartitionings().isEmpty() && nbOnGoingParts == camp.getPartitionings().size(); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/OwnerServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/OwnerServiceImpl.java index 3fa113d7..80bd7a8c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/OwnerServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/OwnerServiceImpl.java @@ -1,27 +1,25 @@ package fr.insee.survey.datacollectionmanagement.metadata.service.impl; -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Owner; import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; import fr.insee.survey.datacollectionmanagement.metadata.repository.OwnerRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.OwnerService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; @Service @Slf4j +@RequiredArgsConstructor public class OwnerServiceImpl implements OwnerService { - @Autowired - private OwnerRepository ownerRepository; + private final OwnerRepository ownerRepository; - public Optional findById(String owner) { - return ownerRepository.findById(owner); + public Owner findById(String owner) { + return ownerRepository.findById(owner).orElseThrow(() -> new NotFoundException(String.format("Owner %s not found", owner))); } @Override @@ -31,13 +29,17 @@ public Page findAll(Pageable pageable) { @Override public Owner insertOrUpdateOwner(Owner owner) { - Optional ownerBase = findById(owner.getId()); - if (!ownerBase.isPresent()) { + + try { + Owner ownerBase = findById(owner.getId()); + log.info("Update owner with the id {}", owner.getId()); + owner.setSources(ownerBase.getSources()); + } catch (NotFoundException e) { log.info("Create owner with the id {}", owner.getId()); return ownerRepository.save(owner); } - log.info("Update owner with the id {}", owner.getId()); - owner.setSources(ownerBase.get().getSources()); + + return ownerRepository.save(owner); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/PartioningServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/PartioningServiceImpl.java index 2ed08dc2..e1972d07 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/PartioningServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/PartioningServiceImpl.java @@ -1,37 +1,31 @@ package fr.insee.survey.datacollectionmanagement.metadata.service.impl; -import java.util.Date; -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.repository.PartitioningRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Date; @Service @Slf4j +@RequiredArgsConstructor public class PartioningServiceImpl implements PartitioningService { - @Autowired - private PartitioningRepository partitioningRepository; + private final PartitioningRepository partitioningRepository; @Override - public Optional findById(String id) { - return partitioningRepository.findById(id); + public Partitioning findById(String id) { + return partitioningRepository.findById(id). + orElseThrow(() -> new NotFoundException(String.format("Partitioning %s not found", id))); } @Override public Partitioning insertOrUpdatePartitioning(Partitioning partitioning) { - Optional campaignBase = findById(partitioning.getId()); - if (!campaignBase.isPresent()) { - log.info("Create partitioning with the id {}", partitioning.getId()); - return partitioningRepository.save(partitioning); - } - log.info("Update partitioning with the id {}", partitioning.getId()); return partitioningRepository.save(partitioning); } @@ -44,6 +38,6 @@ public void deletePartitioningById(String id) { @Override public boolean isOnGoing(Partitioning part, Date date) { - return part.getClosingDate().compareTo(date)>0 && part.getOpeningDate().compareTo(date)<0; + return part.getClosingDate().compareTo(date) > 0 && part.getOpeningDate().compareTo(date) < 0; } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SourceServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SourceServiceImpl.java index d4b140b0..1f8f483b 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SourceServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SourceServiceImpl.java @@ -1,31 +1,27 @@ package fr.insee.survey.datacollectionmanagement.metadata.service.impl; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; -import fr.insee.survey.datacollectionmanagement.metadata.repository.OwnerRepository; import fr.insee.survey.datacollectionmanagement.metadata.repository.SourceRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SupportRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.SourceService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.Set; @Service @Slf4j +@RequiredArgsConstructor public class SourceServiceImpl implements SourceService { - @Autowired - private SourceRepository sourceRepository; + private final SourceRepository sourceRepository; - public Optional findById(String source) { - return sourceRepository.findById(source); + public Source findById(String source) { + return sourceRepository.findById(source).orElseThrow(() -> new NotFoundException(String.format("Source %s not found", source))); } @Override @@ -35,13 +31,15 @@ public Page findAll(Pageable pageable) { @Override public Source insertOrUpdateSource(Source source) { - Optional sourceBase = findById(source.getId()); - if (!sourceBase.isPresent()) { + try { + Source sourceBase = findById(source.getId()); + log.info("Update source with the id {}", source.getId()); + source.setSurveys(sourceBase.getSurveys()); + } catch (NotFoundException e) { log.info("Create source with the id {}", source.getId()); return sourceRepository.save(source); + } - log.info("Update source with the id {}", source.getId()); - source.setSurveys(sourceBase.get().getSurveys()); return sourceRepository.save(source); } @@ -53,20 +51,21 @@ public void deleteSourceById(String id) { @Override public Source addSurveyToSource(Source source, Survey survey) { - Optional sourceBase = findById(source.getId()); - if (sourceBase.isPresent() && isSurveyPresent(survey, sourceBase.get())) { - source.setSurveys(sourceBase.get().getSurveys()); - - } else { + Set surveys; + try { + Source sourceBase = findById(source.getId()); + surveys = sourceBase.getSurveys(); + if (!isSurveyPresent(survey, sourceBase)) { + surveys.add(survey); + } + } catch (NotFoundException e) { + surveys = Set.of(survey); - Set surveys = (!sourceBase.isPresent()) ? new HashSet<>() - : sourceBase.get().getSurveys(); - surveys.add(survey); - source.setSurveys(surveys); } + source.setSurveys(surveys); return source; } - + private boolean isSurveyPresent(Survey su, Source s) { for (Survey survey : s.getSurveys()) { if (survey.getId().equals(su.getId())) { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SupportServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SupportServiceImpl.java index caa36f95..cfc3513b 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SupportServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SupportServiceImpl.java @@ -1,27 +1,26 @@ package fr.insee.survey.datacollectionmanagement.metadata.service.impl; -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; import fr.insee.survey.datacollectionmanagement.metadata.domain.Support; import fr.insee.survey.datacollectionmanagement.metadata.repository.SupportRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.SupportService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; @Service @Slf4j +@RequiredArgsConstructor public class SupportServiceImpl implements SupportService { - @Autowired - private SupportRepository supportRepository; + private final SupportRepository supportRepository; + + public Support findById(String support) { - public Optional findById(String support) { - return supportRepository.findById(support); + return supportRepository.findById(support).orElseThrow(() -> new NotFoundException(String.format("Support %s not found", support))); } @Override @@ -31,14 +30,16 @@ public Page findAll(Pageable pageable) { @Override public Support insertOrUpdateSupport(Support support) { - Optional supportBase = findById(support.getId()); - if (!supportBase.isPresent()) { + try { + Support supportBase = findById(support.getId()); + log.info("Update support with the id {}", support.getId()); + support.setSources(supportBase.getSources()); + + } catch (NotFoundException e) { log.info("Create support with the id {}", support.getId()); - return supportRepository.save(support); } - log.info("Update support with the id {}", support.getId()); - support.setSources(supportBase.get().getSources()); return supportRepository.save(support); + } @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SurveyServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SurveyServiceImpl.java index 62b3b98c..aa7b1ba6 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SurveyServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/service/impl/SurveyServiceImpl.java @@ -1,36 +1,35 @@ package fr.insee.survey.datacollectionmanagement.metadata.service.impl; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; import fr.insee.survey.datacollectionmanagement.metadata.repository.SurveyRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.SurveyService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Set; @Service @Slf4j +@RequiredArgsConstructor public class SurveyServiceImpl implements SurveyService { - @Autowired - private SurveyRepository surveyRepository; + private final SurveyRepository surveyRepository; @Override - public List findByYear(int year) { - return surveyRepository.findByYear(year); + public Page findBySourceIdYearPeriodicity(Pageable pageable, String sourceId, Integer year, String periodicity) { + return surveyRepository.findBySourceIdYearPeriodicity(pageable,sourceId, year, periodicity); } @Override - public Optional findById(String id) { - return surveyRepository.findById(id); + public Survey findById(String id) { + return surveyRepository.findById(id) + .orElseThrow(() -> new NotFoundException(String.format("Survey %s not found", id))); } @Override @@ -40,14 +39,15 @@ public Page findAll(Pageable pageable) { @Override public Survey insertOrUpdateSurvey(Survey survey) { - Optional surveyBase = findById(survey.getId()); - if (!surveyBase.isPresent()) { + try { + Survey surveyBase = findById(survey.getId()); + log.info("Update survey with the id {}", survey.getId()); + survey.setCampaigns(surveyBase.getCampaigns()); + } catch (NotFoundException e) { log.info("Create survey with the id {}", survey.getId()); - return surveyRepository.save(survey); } - log.info("Update survey with the id {}", survey.getId()); - survey.setCampaigns(surveyBase.get().getCampaigns()); return surveyRepository.save(survey); + } @Override @@ -58,20 +58,23 @@ public void deleteSurveyById(String id) { @Override public Survey addCampaignToSurvey(Survey survey, Campaign campaign) { - Optional surveyBase = findById(survey.getId()); - if (surveyBase.isPresent() && isCampaignPresent(campaign, surveyBase.get())) { - survey.setCampaigns(surveyBase.get().getCampaigns()); - - } else { + Set campaigns; + try { + Survey surveyBase = findById(survey.getId()); + campaigns = surveyBase.getCampaigns(); + if(!isCampaignPresent(campaign, surveyBase)) { + campaigns.add(campaign); + } + } + catch (NotFoundException e){ + campaigns = Set.of(campaign); - Set campaigns = (!surveyBase.isPresent()) ? new HashSet<>() - : surveyBase.get().getCampaigns(); - campaigns.add(campaign); - survey.setCampaigns(campaigns); } + survey.setCampaigns(campaigns); return survey; + } - + private boolean isCampaignPresent(Campaign c, Survey s) { for (Campaign camp : s.getCampaigns()) { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/util/PeriodEnum.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/util/PeriodEnum.java index eb7b6b96..2db05522 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/util/PeriodEnum.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/util/PeriodEnum.java @@ -5,131 +5,131 @@ @Getter public enum PeriodEnum { - A00(PeriodicityEnum.A, "annual"), - X00(PeriodicityEnum.X, "pluriannual"), - X01(PeriodicityEnum.X, "pluriannual"), - X02(PeriodicityEnum.X, "pluriannual"), - X03(PeriodicityEnum.X, "pluriannual"), - X04(PeriodicityEnum.X, "pluriannual"), - X05(PeriodicityEnum.X, "pluriannual"), - X06(PeriodicityEnum.X, "pluriannual"), - X07(PeriodicityEnum.X, "pluriannual"), - X08(PeriodicityEnum.X, "pluriannual"), - X09(PeriodicityEnum.X, "pluriannual"), - X10(PeriodicityEnum.X, "pluriannual"), - X11(PeriodicityEnum.X, "pluriannual"), - X12(PeriodicityEnum.X, "pluriannual"), - X13(PeriodicityEnum.X, "pluriannual"), - X14(PeriodicityEnum.X, "pluriannual"), - X15(PeriodicityEnum.X, "pluriannual"), - X16(PeriodicityEnum.X, "pluriannual"), - X17(PeriodicityEnum.X, "pluriannual"), - X18(PeriodicityEnum.X, "pluriannual"), - X19(PeriodicityEnum.X, "pluriannual"), - X20(PeriodicityEnum.X, "pluriannual"), - X21(PeriodicityEnum.X, "pluriannual"), - X22(PeriodicityEnum.X, "pluriannual"), - X23(PeriodicityEnum.X, "pluriannual"), - X24(PeriodicityEnum.X, "pluriannual"), - X25(PeriodicityEnum.X, "pluriannual"), - X26(PeriodicityEnum.X, "pluriannual"), - X27(PeriodicityEnum.X, "pluriannual"), - X28(PeriodicityEnum.X, "pluriannual"), - X29(PeriodicityEnum.X, "pluriannual"), - X30(PeriodicityEnum.X, "pluriannual"), - X31(PeriodicityEnum.X, "pluriannual"), - X32(PeriodicityEnum.X, "pluriannual"), - X33(PeriodicityEnum.X, "pluriannual"), - X34(PeriodicityEnum.X, "pluriannual"), - X35(PeriodicityEnum.X, "pluriannual"), - X36(PeriodicityEnum.X, "pluriannual"), - X37(PeriodicityEnum.X, "pluriannual"), - X38(PeriodicityEnum.X, "pluriannual"), - X39(PeriodicityEnum.X, "pluriannual"), - X40(PeriodicityEnum.X, "pluriannual"), - X41(PeriodicityEnum.X, "pluriannual"), - X42(PeriodicityEnum.X, "pluriannual"), - X43(PeriodicityEnum.X, "pluriannual"), - X44(PeriodicityEnum.X, "pluriannual"), - X45(PeriodicityEnum.X, "pluriannual"), - X46(PeriodicityEnum.X, "pluriannual"), - X47(PeriodicityEnum.X, "pluriannual"), - X48(PeriodicityEnum.X, "pluriannual"), - X49(PeriodicityEnum.X, "pluriannual"), - X50(PeriodicityEnum.X, "pluriannual"), - X51(PeriodicityEnum.X, "pluriannual"), - X52(PeriodicityEnum.X, "pluriannual"), - X53(PeriodicityEnum.X, "pluriannual"), - X54(PeriodicityEnum.X, "pluriannual"), - X55(PeriodicityEnum.X, "pluriannual"), - X56(PeriodicityEnum.X, "pluriannual"), - X57(PeriodicityEnum.X, "pluriannual"), - X58(PeriodicityEnum.X, "pluriannual"), - X59(PeriodicityEnum.X, "pluriannual"), - X60(PeriodicityEnum.X, "pluriannual"), - X61(PeriodicityEnum.X, "pluriannual"), - X62(PeriodicityEnum.X, "pluriannual"), - X63(PeriodicityEnum.X, "pluriannual"), - X64(PeriodicityEnum.X, "pluriannual"), - X65(PeriodicityEnum.X, "pluriannual"), - X66(PeriodicityEnum.X, "pluriannual"), - X67(PeriodicityEnum.X, "pluriannual"), - X68(PeriodicityEnum.X, "pluriannual"), - X69(PeriodicityEnum.X, "pluriannual"), - X70(PeriodicityEnum.X, "pluriannual"), - X71(PeriodicityEnum.X, "pluriannual"), - X72(PeriodicityEnum.X, "pluriannual"), - X73(PeriodicityEnum.X, "pluriannual"), - X74(PeriodicityEnum.X, "pluriannual"), - X75(PeriodicityEnum.X, "pluriannual"), - X76(PeriodicityEnum.X, "pluriannual"), - X77(PeriodicityEnum.X, "pluriannual"), - X78(PeriodicityEnum.X, "pluriannual"), - X79(PeriodicityEnum.X, "pluriannual"), - X80(PeriodicityEnum.X, "pluriannual"), - X81(PeriodicityEnum.X, "pluriannual"), - X82(PeriodicityEnum.X, "pluriannual"), - X83(PeriodicityEnum.X, "pluriannual"), - X84(PeriodicityEnum.X, "pluriannual"), - X85(PeriodicityEnum.X, "pluriannual"), - X86(PeriodicityEnum.X, "pluriannual"), - X87(PeriodicityEnum.X, "pluriannual"), - X88(PeriodicityEnum.X, "pluriannual"), - X89(PeriodicityEnum.X, "pluriannual"), - X90(PeriodicityEnum.X, "pluriannual"), - X91(PeriodicityEnum.X, "pluriannual"), - X92(PeriodicityEnum.X, "pluriannual"), - X93(PeriodicityEnum.X, "pluriannual"), - X94(PeriodicityEnum.X, "pluriannual"), - X95(PeriodicityEnum.X, "pluriannual"), - X96(PeriodicityEnum.X, "pluriannual"), - X97(PeriodicityEnum.X, "pluriannual"), - X98(PeriodicityEnum.X, "pluriannual"), - X99(PeriodicityEnum.X, "pluriannual"), - S01(PeriodicityEnum.S, "1st semester"), - S02(PeriodicityEnum.S, "2nd semester"), - T01(PeriodicityEnum.T, "1st trimester"), - T02(PeriodicityEnum.T, "2nd trimester"), - T03(PeriodicityEnum.T, "3rd trimester"), - T04(PeriodicityEnum.T, "4th trimester"), - M01(PeriodicityEnum.M, "january"), - M02(PeriodicityEnum.M, "february"), - M03(PeriodicityEnum.M, "march"), - M04(PeriodicityEnum.M, "april"), - M05(PeriodicityEnum.M, "may"), - M06(PeriodicityEnum.M, "june"), - M07(PeriodicityEnum.M, "july"), - M08(PeriodicityEnum.M, "august"), - M09(PeriodicityEnum.M, "september"), - M10(PeriodicityEnum.M, "october"), - M11(PeriodicityEnum.M, "november"), - M12(PeriodicityEnum.M, "december"), - B01(PeriodicityEnum.B, "1st bimester"), - B02(PeriodicityEnum.B, "2nd bimester"), - B03(PeriodicityEnum.B, "3rd bimester"), - B04(PeriodicityEnum.B, "4th bimester"), - B05(PeriodicityEnum.B, "5th bimester"), - B06(PeriodicityEnum.B, "6th bimester"), + A00(PeriodicityEnum.A, "annuel"), + X00(PeriodicityEnum.X, "pluriannuel"), + X01(PeriodicityEnum.X, "pluriannuel"), + X02(PeriodicityEnum.X, "pluriannuel"), + X03(PeriodicityEnum.X, "pluriannuel"), + X04(PeriodicityEnum.X, "pluriannuel"), + X05(PeriodicityEnum.X, "pluriannuel"), + X06(PeriodicityEnum.X, "pluriannuel"), + X07(PeriodicityEnum.X, "pluriannuel"), + X08(PeriodicityEnum.X, "pluriannuel"), + X09(PeriodicityEnum.X, "pluriannuel"), + X10(PeriodicityEnum.X, "pluriannuel"), + X11(PeriodicityEnum.X, "pluriannuel"), + X12(PeriodicityEnum.X, "pluriannuel"), + X13(PeriodicityEnum.X, "pluriannuel"), + X14(PeriodicityEnum.X, "pluriannuel"), + X15(PeriodicityEnum.X, "pluriannuel"), + X16(PeriodicityEnum.X, "pluriannuel"), + X17(PeriodicityEnum.X, "pluriannuel"), + X18(PeriodicityEnum.X, "pluriannuel"), + X19(PeriodicityEnum.X, "pluriannuel"), + X20(PeriodicityEnum.X, "pluriannuel"), + X21(PeriodicityEnum.X, "pluriannuel"), + X22(PeriodicityEnum.X, "pluriannuel"), + X23(PeriodicityEnum.X, "pluriannuel"), + X24(PeriodicityEnum.X, "pluriannuel"), + X25(PeriodicityEnum.X, "pluriannuel"), + X26(PeriodicityEnum.X, "pluriannuel"), + X27(PeriodicityEnum.X, "pluriannuel"), + X28(PeriodicityEnum.X, "pluriannuel"), + X29(PeriodicityEnum.X, "pluriannuel"), + X30(PeriodicityEnum.X, "pluriannuel"), + X31(PeriodicityEnum.X, "pluriannuel"), + X32(PeriodicityEnum.X, "pluriannuel"), + X33(PeriodicityEnum.X, "pluriannuel"), + X34(PeriodicityEnum.X, "pluriannuel"), + X35(PeriodicityEnum.X, "pluriannuel"), + X36(PeriodicityEnum.X, "pluriannuel"), + X37(PeriodicityEnum.X, "pluriannuel"), + X38(PeriodicityEnum.X, "pluriannuel"), + X39(PeriodicityEnum.X, "pluriannuel"), + X40(PeriodicityEnum.X, "pluriannuel"), + X41(PeriodicityEnum.X, "pluriannuel"), + X42(PeriodicityEnum.X, "pluriannuel"), + X43(PeriodicityEnum.X, "pluriannuel"), + X44(PeriodicityEnum.X, "pluriannuel"), + X45(PeriodicityEnum.X, "pluriannuel"), + X46(PeriodicityEnum.X, "pluriannuel"), + X47(PeriodicityEnum.X, "pluriannuel"), + X48(PeriodicityEnum.X, "pluriannuel"), + X49(PeriodicityEnum.X, "pluriannuel"), + X50(PeriodicityEnum.X, "pluriannuel"), + X51(PeriodicityEnum.X, "pluriannuel"), + X52(PeriodicityEnum.X, "pluriannuel"), + X53(PeriodicityEnum.X, "pluriannuel"), + X54(PeriodicityEnum.X, "pluriannuel"), + X55(PeriodicityEnum.X, "pluriannuel"), + X56(PeriodicityEnum.X, "pluriannuel"), + X57(PeriodicityEnum.X, "pluriannuel"), + X58(PeriodicityEnum.X, "pluriannuel"), + X59(PeriodicityEnum.X, "pluriannuel"), + X60(PeriodicityEnum.X, "pluriannuel"), + X61(PeriodicityEnum.X, "pluriannuel"), + X62(PeriodicityEnum.X, "pluriannuel"), + X63(PeriodicityEnum.X, "pluriannuel"), + X64(PeriodicityEnum.X, "pluriannuel"), + X65(PeriodicityEnum.X, "pluriannuel"), + X66(PeriodicityEnum.X, "pluriannuel"), + X67(PeriodicityEnum.X, "pluriannuel"), + X68(PeriodicityEnum.X, "pluriannuel"), + X69(PeriodicityEnum.X, "pluriannuel"), + X70(PeriodicityEnum.X, "pluriannuel"), + X71(PeriodicityEnum.X, "pluriannuel"), + X72(PeriodicityEnum.X, "pluriannuel"), + X73(PeriodicityEnum.X, "pluriannuel"), + X74(PeriodicityEnum.X, "pluriannuel"), + X75(PeriodicityEnum.X, "pluriannuel"), + X76(PeriodicityEnum.X, "pluriannuel"), + X77(PeriodicityEnum.X, "pluriannuel"), + X78(PeriodicityEnum.X, "pluriannuel"), + X79(PeriodicityEnum.X, "pluriannuel"), + X80(PeriodicityEnum.X, "pluriannuel"), + X81(PeriodicityEnum.X, "pluriannuel"), + X82(PeriodicityEnum.X, "pluriannuel"), + X83(PeriodicityEnum.X, "pluriannuel"), + X84(PeriodicityEnum.X, "pluriannuel"), + X85(PeriodicityEnum.X, "pluriannuel"), + X86(PeriodicityEnum.X, "pluriannuel"), + X87(PeriodicityEnum.X, "pluriannuel"), + X88(PeriodicityEnum.X, "pluriannuel"), + X89(PeriodicityEnum.X, "pluriannuel"), + X90(PeriodicityEnum.X, "pluriannuel"), + X91(PeriodicityEnum.X, "pluriannuel"), + X92(PeriodicityEnum.X, "pluriannuel"), + X93(PeriodicityEnum.X, "pluriannuel"), + X94(PeriodicityEnum.X, "pluriannuel"), + X95(PeriodicityEnum.X, "pluriannuel"), + X96(PeriodicityEnum.X, "pluriannuel"), + X97(PeriodicityEnum.X, "pluriannuel"), + X98(PeriodicityEnum.X, "pluriannuel"), + X99(PeriodicityEnum.X, "pluriannuel"), + S01(PeriodicityEnum.S, "1er semestre"), + S02(PeriodicityEnum.S, "2nd semestre"), + T01(PeriodicityEnum.T, "1er trimestre"), + T02(PeriodicityEnum.T, "2e trimestre"), + T03(PeriodicityEnum.T, "3e trimestre"), + T04(PeriodicityEnum.T, "4e trimestre"), + M01(PeriodicityEnum.M, "janvier"), + M02(PeriodicityEnum.M, "fÊvrier"), + M03(PeriodicityEnum.M, "mars"), + M04(PeriodicityEnum.M, "avril"), + M05(PeriodicityEnum.M, "mai"), + M06(PeriodicityEnum.M, "juin"), + M07(PeriodicityEnum.M, "juillet"), + M08(PeriodicityEnum.M, "aoÃģt"), + M09(PeriodicityEnum.M, "septembre"), + M10(PeriodicityEnum.M, "octobre"), + M11(PeriodicityEnum.M, "novembre"), + M12(PeriodicityEnum.M, "dÊcembre"), + B01(PeriodicityEnum.B, "1er bimestre"), + B02(PeriodicityEnum.B, "2e bimestre"), + B03(PeriodicityEnum.B, "3e bimestre"), + B04(PeriodicityEnum.B, "4e bimestre"), + B05(PeriodicityEnum.B, "5e bimestre"), + B06(PeriodicityEnum.B, "6e bimestre"), ; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/util/PeriodicityEnum.java b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/util/PeriodicityEnum.java index df375381..134c733e 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/util/PeriodicityEnum.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/metadata/util/PeriodicityEnum.java @@ -5,8 +5,8 @@ @Getter public enum PeriodicityEnum { - X("pluriannual"), A("annual"), S("semi-annual"), T("trimestrial"), B("bimonthly"), - M("monthly"); + X("pluriannuel"), A("annuel"), S("semi-annuel"), T("trimestriel"), B("bimensuel"), + M("mensuel"); PeriodicityEnum(String value) { this.value = value; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/CheckHabilitationController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/CheckHabilitationController.java index 36b2eba3..aa7b368a 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/CheckHabilitationController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/CheckHabilitationController.java @@ -1,30 +1,29 @@ package fr.insee.survey.datacollectionmanagement.query.controller; +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; +import fr.insee.survey.datacollectionmanagement.config.auth.user.UserProvider; +import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.query.dto.HabilitationDto; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; +import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; -import io.swagger.v3.oas.annotations.tags.Tag; - -import javax.servlet.http.HttpServletRequest; @RestController @Tag(name = "4 - Cross domain") +@RequiredArgsConstructor public class CheckHabilitationController { - static final Logger LOGGER = LoggerFactory.getLogger(CheckHabilitationController.class); + private final CheckHabilitationService checkHabilitationService; - @Autowired - private CheckHabilitationService checkHabilitationService; + private final UserProvider userProvider; @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " @@ -34,9 +33,13 @@ public class CheckHabilitationController { public ResponseEntity checkHabilitation( @RequestParam(required = false) String role, @RequestParam(required = true) String id, - @RequestParam(required = true) String campaign) { - - return checkHabilitationService.checkHabilitation(role, id,campaign); + @RequestParam(required = true) String campaign, + Authentication authentication) { + AuthUser authUser = userProvider.getUser(authentication); + HabilitationDto habDto = new HabilitationDto(); + boolean habilitated = checkHabilitationService.checkHabilitation(role, id,campaign, authUser); + habDto.setHabilitated(habilitated); + return new ResponseEntity<>(habDto, HttpStatus.OK); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MonitoringController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MonitoringController.java index ed5aa05d..a75cf1cc 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MonitoringController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MonitoringController.java @@ -1,77 +1,59 @@ package fr.insee.survey.datacollectionmanagement.query.controller; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; - import fr.insee.survey.datacollectionmanagement.config.JSONCollectionWrapper; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; -import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; import fr.insee.survey.datacollectionmanagement.query.dto.MoogFollowUpDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogProgressDto; import fr.insee.survey.datacollectionmanagement.query.service.MonitoringService; -import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "5 - Moog", description = "Enpoints for moog") +@Slf4j +@RequiredArgsConstructor public class MonitoringController { - static final Logger LOGGER = LoggerFactory.getLogger(MonitoringController.class); - - @Autowired - MonitoringService monitoringService; - - @Autowired - QuestioningService questioningService; - @Autowired - PartitioningService partitioningService; + private final MonitoringService monitoringService; - @Autowired - CampaignService campaignService; + private final CampaignService campaignService; @GetMapping(value = "/api/moog/campaigns/{idCampaign}/monitoring/progress", produces = "application/json") public JSONCollectionWrapper getDataForProgress(@PathVariable String idCampaign) { - LOGGER.info("Request GET for monitoring moog progress table for campaign : {}", idCampaign); + log.info("Request GET for monitoring moog progress table for campaign : {}", idCampaign); return monitoringService.getProgress(idCampaign); } @GetMapping(value = "/api/moog/campaigns/{idCampaign}/monitoring/follow-up", produces = "application/json") public JSONCollectionWrapper getDataToFollowUp(@PathVariable String idCampaign) { - LOGGER.info("Request GET for following table for campaign : {}", idCampaign); + log.info("Request GET for following table for campaign : {}", idCampaign); return monitoringService.getFollowUp(idCampaign); } @GetMapping(value = "/api/temp/moog/campaigns/{idCampaign}/monitoring/progress", produces = "application/json") public JSONCollectionWrapper getDataForProgressTemp(@PathVariable String idCampaign) { - LOGGER.info("Request GET for monitoring moog progress table for campaign : {}", idCampaign); - Optional campaign = campaignService.findById(idCampaign); - if (!campaign.isPresent()) { - throw new NoSuchElementException("campaign does not exist"); - } - LOGGER.info("{} partitionings found", campaign.get().getPartitionings().stream().map(Partitioning::getId) - .collect(Collectors.toList()).size()); - campaign.get().getPartitionings().forEach(part -> LOGGER.info("{} partitionig found", part.getId())); + log.info("Request GET for monitoring moog progress table for campaign : {}", idCampaign); + Campaign campaign = campaignService.findById(idCampaign); + log.info("{} partitionings found", campaign.getPartitionings().stream().map(Partitioning::getId) + .toList().size()); + campaign.getPartitionings().forEach(part -> log.info("{} partitionig found", part.getId())); return null; } @GetMapping(value = "/api/temp/moog/campaigns/{idCampaign}/monitoring/follow-up", produces = "application/json") public JSONCollectionWrapper getDataToFollowUpTemp(@PathVariable String idCampaign) { - LOGGER.info("Request GET for following table for campaign : {}", idCampaign); + log.info("Request GET for following table for campaign : {}", idCampaign); return monitoringService.getFollowUp(idCampaign); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MoogController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MoogController.java index cfa1448d..d1579513 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MoogController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MoogController.java @@ -1,30 +1,11 @@ package fr.insee.survey.datacollectionmanagement.query.controller; -import java.util.List; -import java.util.Map; -import java.util.Optional; - import fr.insee.survey.datacollectionmanagement.config.JSONCollectionWrapper; -import fr.insee.survey.datacollectionmanagement.query.dto.MoogExtractionRowDto; -import fr.insee.survey.datacollectionmanagement.questioning.service.UploadService; -import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; -import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; -import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; - import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.query.dto.MoogExtractionRowDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogQuestioningEventDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogSearchDto; import fr.insee.survey.datacollectionmanagement.query.service.MoogService; @@ -36,7 +17,22 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import org.webjars.NotFoundException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -44,57 +40,43 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "5 - Moog", description = "Enpoints for moog") @Slf4j +@RequiredArgsConstructor public class MoogController { - - @Autowired - private MoogService moogService; - - @Autowired - private ContactService contactService; - @Autowired - QuestioningEventService questioningEventService; + private final MoogService moogService; - @Autowired - QuestioningService questioningService; + private final ContactService contactService; - @Autowired - UploadService uploadService; @GetMapping(path = Constants.API_MOOG_SEARCH) - public ResponseEntity moogSearch(@RequestParam(required = false) String filter1, - @RequestParam(required = false) String filter2, - @RequestParam(defaultValue = "0", required = false) int pageNo, - @RequestParam(defaultValue = "20", required = false) int pageSize) { + public ResponseEntity> moogSearch(@RequestParam(required = false) String filter1, + @RequestParam(required = false) String filter2, + @RequestParam(defaultValue = "0", required = false) int pageNo, + @RequestParam(defaultValue = "20", required = false) int pageSize) { List listView = moogService.moogSearch(filter1); Pageable pageable = PageRequest.of(pageNo, pageSize); int start = (int) pageable.getOffset(); - int end = (int) ((start + pageable.getPageSize()) > listView.size() ? listView.size() - : (start + pageable.getPageSize())); + int end = (start + pageable.getPageSize()) > listView.size() ? listView.size() + : (start + pageable.getPageSize()); if (start <= end) { - Page page = new PageImpl( + Page page = new PageImpl<>( moogService.transformListViewToListMoogSearchDto(listView.subList(start, end)), pageable, listView.size()); return new ResponseEntity<>(page, HttpStatus.OK); } else - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + throw new IllegalArgumentException("Start must be inferior to end"); } @GetMapping(path = Constants.API_MOOG_MAIL, produces = "application/json") @Operation(summary = "Get Moog questioning events by campaign and idSu") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))), - @ApiResponse(responseCode = "404", description = "Not found") - }) - public ResponseEntity getMoogMail(@PathVariable("id") String contactId) { - Optional contact = contactService.findByIdentifier(contactId); - return contact.isPresent() ? ResponseEntity.ok().body(contact.get().getEmail()) - : ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact not found"); + public ResponseEntity getMoogMail(@PathVariable("id") String contactId) { + Contact contact = contactService.findByIdentifier(contactId); + return ResponseEntity.ok().body(contact.getEmail()); } @GetMapping(path = Constants.API_MOOG_EVENTS, produces = "application/json") @@ -103,8 +85,8 @@ public ResponseEntity getMoogMail(@PathVariable("id") String contactId) { @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = MoogQuestioningEventDto.class)))), @ApiResponse(responseCode = "400", description = "Bad Request") }) - public ResponseEntity getMoogQuestioningEvents(@PathVariable("campaign") String campaignId, - @PathVariable("id") String idSu) { + public ResponseEntity>> getMoogQuestioningEvents(@PathVariable("campaign") String campaignId, + @PathVariable("id") String idSu) { return new ResponseEntity<>(Map.of("datas", moogService.getMoogEvents(campaignId, idSu)), HttpStatus.OK); } @@ -118,21 +100,19 @@ public JSONCollectionWrapper provideDataForExtraction(@Pat @GetMapping(value = Constants.MOOG_API_CAMPAIGN_SURVEYUNITS_FOLLOWUP, produces = "application/json") public JSONCollectionWrapper displaySurveyUnitsToFollowUp(@PathVariable String idCampaign) { log.info("Request GET for su to follow up - campaign {}", idCampaign); - return new JSONCollectionWrapper(moogService.getSurveyUnitsToFollowUp(idCampaign)); + return new JSONCollectionWrapper<>(moogService.getSurveyUnitsToFollowUp(idCampaign)); } @GetMapping(value = Constants.MOOG_API_READONLY_URL, produces = "application/json") - public ResponseEntity getReadOnlyUrl(@PathVariable String idCampaign, @PathVariable String surveyUnitId){ - log.info("Request READONLY url for su {} and campaign {}",surveyUnitId, idCampaign); + public ResponseEntity getReadOnlyUrl(@PathVariable String idCampaign, @PathVariable String surveyUnitId) { + log.info("Request READONLY url for su {} and campaign {}", surveyUnitId, idCampaign); String url; try { url = moogService.getReadOnlyUrl(idCampaign, surveyUnitId); return ResponseEntity.ok().body(url); - } - catch (NotFoundException e){ - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage()); - } - catch (Exception e){ + } catch (NotFoundException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage()); + } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MyQuestioningsController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MyQuestioningsController.java index d786ac8b..0c5bc1df 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MyQuestioningsController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/MyQuestioningsController.java @@ -1,34 +1,29 @@ package fr.insee.survey.datacollectionmanagement.query.controller; -import java.util.List; - import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; -import fr.insee.survey.datacollectionmanagement.config.auth.user.User; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; +import fr.insee.survey.datacollectionmanagement.constants.AuthConstants; +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.query.dto.MyQuestioningDto; +import fr.insee.survey.datacollectionmanagement.query.service.MySurveysService; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.query.dto.MyQuestioningDto; -import fr.insee.survey.datacollectionmanagement.query.service.MySurveysService; -import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; @RestController @Tag(name = "4 - Cross domain") +@RequiredArgsConstructor public class MyQuestioningsController { - @Autowired - private MySurveysService mySurveysService; + private final MySurveysService mySurveysService; - @Autowired - ApplicationConfig config; + private final ApplicationConfig config; @GetMapping(value = Constants.API_MY_QUESTIONINGS_ID) @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -37,9 +32,9 @@ public class MyQuestioningsController { + "|| @AuthorizeMethodDecider.isAdmin() ") public List findById() { - String idec=null; + String idec; - if (config.getAuthType().equals("OIDC")) { + if (config.getAuthType().equals(AuthConstants.OIDC)) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); final Jwt jwt = (Jwt) authentication.getPrincipal(); idec=jwt.getClaimAsString(config.getIdClaim()).toUpperCase(); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/QuestioningAccreditationController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/QuestioningAccreditationController.java index 468d3534..d8b1a2bf 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/QuestioningAccreditationController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/QuestioningAccreditationController.java @@ -1,26 +1,5 @@ package fr.insee.survey.datacollectionmanagement.query.controller; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.modelmapper.ModelMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; @@ -38,33 +17,40 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.modelmapper.ModelMapper; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.List; +import java.util.Set; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "2 - Questioning", description = "Enpoints to create, update, delete and find entities around the questionings") +@Slf4j +@RequiredArgsConstructor public class QuestioningAccreditationController { - static final Logger LOGGER = LoggerFactory.getLogger(QuestioningAccreditationController.class); - - @Autowired - private QuestioningAccreditationService questioningAccreditationService; + private final QuestioningAccreditationService questioningAccreditationService; - @Autowired - private QuestioningService questioningService; + private final QuestioningService questioningService; - @Autowired - private ContactService contactService; + private final ContactService contactService; - @Autowired - private PartitioningService partitioningService; + private final PartitioningService partitioningService; - @Autowired - private ViewService viewService; + private final ViewService viewService; - @Autowired - private ModelMapper modelMapper; + private final ModelMapper modelMapper; @Operation(summary = "Search for questioning accreditations by questioning id") @GetMapping(value = Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, produces = "application/json") @@ -75,15 +61,13 @@ public class QuestioningAccreditationController { }) public ResponseEntity getQuestioningAccreditation(@PathVariable("id") Long id) { + Questioning optQuestioning = questioningService.findbyId(id); + try { - Optional optQuestioning = questioningService.findbyId(id); - if (optQuestioning.isPresent()) - return new ResponseEntity<>( - optQuestioning.get().getQuestioningAccreditations().stream().map(c -> convertToDto(c)) - .collect(Collectors.toList()), - HttpStatus.OK); - else - return new ResponseEntity<>("Questioning does not exist", HttpStatus.NOT_FOUND); + return new ResponseEntity<>( + optQuestioning.getQuestioningAccreditations().stream().map(this::convertToDto) + .toList(), HttpStatus.OK); + } catch (Exception e) { return new ResponseEntity("Error", HttpStatus.INTERNAL_SERVER_ERROR); } @@ -99,38 +83,28 @@ public ResponseEntity getQuestioningAccreditation(@PathVariable("id") Long id }) @Transactional public ResponseEntity postQuestioningAccreditation(@PathVariable("id") Long id, - @RequestBody QuestioningAccreditationDto questioningAccreditationDto) { + @RequestBody QuestioningAccreditationDto questioningAccreditationDto) { - Optional optQuestioning = null; + Questioning questioning = questioningService.findbyId(id); String idContact = questioningAccreditationDto.getIdContact(); + contactService.findByIdentifier(idContact); - // Check if questioning exists - try { - optQuestioning = questioningService.findbyId(id); - if (!optQuestioning.isPresent()) - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Questioning does not exist"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error"); - } - Questioning questioning = optQuestioning.get(); - // Check if contact exists - if (!contactService.findByIdentifier(idContact).isPresent()) - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Contact does not exist"); HttpHeaders responseHeaders = new HttpHeaders(); // save new accreditation or update existing one Set setExistingAccreditations = questioning.getQuestioningAccreditations(); - Optional part = partitioningService.findById(questioning.getIdPartitioning()); + Partitioning part = partitioningService.findById(questioning.getIdPartitioning()); + String idSu = questioning.getSurveyUnit().getIdSu(); List listContactAccreditations = setExistingAccreditations.stream() .filter(acc -> acc.getIdContact().equals(idContact) - && acc.getQuestioning().getIdPartitioning().equals(part.get().getId()) + && acc.getQuestioning().getIdPartitioning().equals(part.getId()) && acc.getQuestioning().getSurveyUnit().getIdSu().equals(idSu)) - .collect(Collectors.toList()); + .toList(); if (listContactAccreditations.isEmpty()) { // Create new accreditation @@ -142,7 +116,7 @@ public ResponseEntity postQuestioningAccreditation(@PathVariable("id") Long i // create view viewService.createView(idContact, questioning.getSurveyUnit().getIdSu(), - part.get().getCampaign().getId()); + part.getCampaign().getId()); // location header responseHeaders.set(HttpHeaders.LOCATION, @@ -152,6 +126,7 @@ public ResponseEntity postQuestioningAccreditation(@PathVariable("id") Long i return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders) .body(convertToDto(questioningAccreditation)); + } else { // update accreditation QuestioningAccreditation questioningAccreditation = listContactAccreditations.get(0); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/QuestioningController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/QuestioningController.java index a2ef5ee8..781b38b4 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/QuestioningController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/QuestioningController.java @@ -1,22 +1,5 @@ package fr.insee.survey.datacollectionmanagement.query.controller; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; @@ -31,7 +14,16 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.modelmapper.ModelMapper; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -39,19 +31,16 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Slf4j @Tag(name = "2 - Questioning", description = "Enpoints to create, update, delete and find entities around the questionings") +@RequiredArgsConstructor public class QuestioningController { - @Autowired - private QuestioningService questioningService; + private final QuestioningService questioningService; - @Autowired - private SurveyUnitService surveyUnitService; + private final SurveyUnitService surveyUnitService; - @Autowired - private PartitioningService partitioningService; + private final PartitioningService partitioningService; - @Autowired - private ModelMapper modelMapper; + private final ModelMapper modelMapper; @Operation(summary = "Search for a questioning by id") @GetMapping(value = Constants.API_QUESTIONINGS_ID, produces = "application/json") @@ -62,15 +51,9 @@ public class QuestioningController { }) public ResponseEntity getQuestioning(@PathVariable("id") Long id) { - Optional optQuestioning = null; + Questioning questioning = questioningService.findbyId(id); try { - optQuestioning = questioningService.findbyId(id); - if (optQuestioning.isPresent()) - return new ResponseEntity<>(convertToDto(optQuestioning.get()), HttpStatus.OK); - else { - log.warn("Questioning {} does not exist", id); - return new ResponseEntity<>("Not Found", HttpStatus.NOT_FOUND); - } + return new ResponseEntity<>(convertToDto(questioning), HttpStatus.OK); } catch (Exception e) { return new ResponseEntity("Error", HttpStatus.BAD_REQUEST); } @@ -83,19 +66,11 @@ public ResponseEntity getQuestioning(@PathVariable("id") Long id) { @ApiResponse(responseCode = "404", description = "NotFound") }) public ResponseEntity postQuestioning(@RequestBody QuestioningDto questioningDto) { - Optional optSu = surveyUnitService.findbyId(questioningDto.getSurveyUnitId()); + SurveyUnit su = surveyUnitService.findbyId(questioningDto.getSurveyUnitId()); + ; + partitioningService.findById(questioningDto.getIdPartitioning()); - if (!optSu.isPresent()) { - log.warn("survey unit {} does not exist", questioningDto.getSurveyUnitId()); - return new ResponseEntity<>("survey unit does not exist", HttpStatus.NOT_FOUND); - } - SurveyUnit su = optSu.get(); - - if (!partitioningService.findById(questioningDto.getIdPartitioning()).isPresent()) { - log.warn("partitioning {} does not exist", questioningDto.getIdPartitioning()); - return new ResponseEntity<>("partitioning does not exist", HttpStatus.NOT_FOUND); - } Questioning questioning = convertToEntity(questioningDto); questioning.setSurveyUnit(su); questioning = questioningService.saveQuestioning(questioning); @@ -115,19 +90,8 @@ public ResponseEntity postQuestioning(@RequestBody QuestioningDto questioning @ApiResponse(responseCode = "400", description = "Bad Request") }) public ResponseEntity getQuestioningsBySurveyUnit(@PathVariable("id") String id) { - try { - Optional optSu = surveyUnitService.findbyId(StringUtils.upperCase(id)); - if (optSu.isPresent()) - return new ResponseEntity<>( - optSu.get().getQuestionings().stream().map(q -> convertToDto(q)).collect(Collectors.toList()), - HttpStatus.OK); - else { - log.warn("survey unit {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("survey unit does not exist"); - } - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + SurveyUnit su = surveyUnitService.findbyId(StringUtils.upperCase(id)); + return new ResponseEntity<>(su.getQuestionings().stream().map(this::convertToDto).toList(), HttpStatus.OK); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/SearchContactController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/SearchContactController.java index 059e22a0..97475ba1 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/SearchContactController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/SearchContactController.java @@ -1,33 +1,20 @@ package fr.insee.survey.datacollectionmanagement.query.controller; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; import fr.insee.survey.datacollectionmanagement.query.dto.AccreditationDetailDto; import fr.insee.survey.datacollectionmanagement.query.dto.SearchContactDto; +import fr.insee.survey.datacollectionmanagement.query.service.MoogService; import fr.insee.survey.datacollectionmanagement.query.service.SearchContactService; import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; +import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; +import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningAccreditationService; -import fr.insee.survey.datacollectionmanagement.view.domain.View; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; +import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; @@ -35,7 +22,24 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -43,16 +47,18 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "4 - Cross domain") @Slf4j +@RequiredArgsConstructor public class SearchContactController { - @Autowired - private SearchContactService searchContactService; + private final SearchContactService searchContactService; + + private final QuestioningAccreditationService questioningAccreditationService; + + private final PartitioningService partitioningService; - @Autowired - private QuestioningAccreditationService questioningAccreditationService; + private final QuestioningEventService questioningEventService; - @Autowired - private PartitioningService partitioningService; + private final MoogService moogService; @GetMapping(path = Constants.API_CONTACTS_SEARCH, produces = "application/json") @Operation(summary = "Multi-criteria search contacts") @@ -60,47 +66,26 @@ public class SearchContactController { @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = SearchContactDto.class)))), @ApiResponse(responseCode = "400", description = "Bad Request") }) - public ResponseEntity searchContacts( + public ResponseEntity> searchContacts( @RequestParam(required = false) String identifier, - @RequestParam(required = false) String lastName, - @RequestParam(required = false) String firstName, + @RequestParam(required = false) String name, @RequestParam(required = false) String email, - @RequestParam(required = false) String idSu, - @RequestParam(required = false) String identificationCode, - @RequestParam(required = false) String identificationName, - @RequestParam(required = false) String source, - @RequestParam(required = false) String year, - @RequestParam(required = false) String period, - @RequestParam(defaultValue = "0") Integer pageNo, - @RequestParam(defaultValue = "10") Integer pageSize) { + @RequestParam(required = false) String city, + @RequestParam(required = false) String function, + @RequestParam(defaultValue = "0") Integer page, + @RequestParam(defaultValue = "10") Integer pageSize, + @RequestParam(defaultValue = "identifier") String sort) { log.info( - "Search contact: identifier = {}, lastName= {}, firstName= {}, email= {}, idSu= {}, identificationCode= {}, identificationName= {}, source= {}, year= {}, period= {}, pageNo= {}, pageSize= {} ", - identifier, lastName, firstName, email, idSu, identificationCode, identificationName, source, year, - period, pageNo, pageSize); + "Search contact: identifier = {}, name= {}, email= {}, page= {}, pageSize= {} ", + identifier, name, email, page, pageSize); - Pageable pageable = PageRequest.of(pageNo, pageSize); + Pageable pageable = PageRequest.of(page, pageSize, Sort.by(sort)); - List listView = searchContactService.searchContactCrossDomain(identifier, lastName, firstName, email, - idSu, identificationCode, identificationName, source, year, period, + Page pageSearchContact = searchContactService.searchContactCrossDomain(identifier, name, email, city, function, pageable); - int start = (int) pageable.getOffset(); - int end = (int) ((start + pageable.getPageSize()) > listView.size() ? listView.size() - : (start + pageable.getPageSize())); - - if (listView.isEmpty()) { - return new ResponseEntity<>(Collections.EMPTY_LIST, HttpStatus.NOT_FOUND); - } - if (start <= end) { - Page page = new PageImpl( - searchContactService.transformListViewDaoToDto(listView.subList(start, end)), pageable, - listView.size()); - return new ResponseEntity<>(page, HttpStatus.OK); - - } + return new ResponseEntity<>(pageSearchContact, HttpStatus.OK); - else - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } @@ -110,20 +95,36 @@ public ResponseEntity searchContacts( @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = AccreditationDetailDto.class)))), @ApiResponse(responseCode = "400", description = "Bad Request") }) - public ResponseEntity getContactAccreditations(@PathVariable("id") String id) { + public ResponseEntity> getContactAccreditations( + @PathVariable("id") String id, + @RequestParam(defaultValue = "false") boolean isFilterOpened) { List listAccreditations = new ArrayList<>(); List accreditations = questioningAccreditationService.findByContactIdentifier(id); for (QuestioningAccreditation questioningAccreditation : accreditations) { Questioning questioning = questioningAccreditation.getQuestioning(); - Optional part = partitioningService.findById(questioning.getIdPartitioning()); - - listAccreditations.add(new AccreditationDetailDto(part.get().getCampaign().getSurvey().getSource().getId(), - part.get().getCampaign().getSurvey().getSource().getShortWording(), - part.get().getCampaign().getSurvey().getYear(), part.get().getCampaign().getPeriod(), - part.get().getId(), questioningAccreditation.getQuestioning().getSurveyUnit().getIdSu(), - questioningAccreditation.getQuestioning().getSurveyUnit().getIdentificationName(), - questioningAccreditation.isMain())); + Partitioning part = partitioningService.findById(questioning.getIdPartitioning()); + Optional questioningEvent = questioningEventService.getLastQuestioningEvent(questioning, TypeQuestioningEvent.STATE_EVENTS); + + if (!isFilterOpened || partitioningService.isOnGoing(part, new Date())) { + SurveyUnit su = questioningAccreditation.getQuestioning().getSurveyUnit(); + Survey survey = part.getCampaign().getSurvey(); + listAccreditations.add(new AccreditationDetailDto( + survey.getSource().getId(), + survey.getId(), + survey.getSource().getShortWording(), + survey.getYear(), + part.getCampaign().getPeriod(), + part.getId(), + part.getClosingDate(), + su.getIdSu(), + su.getIdentificationName(), + questioningAccreditation.isMain(), + questioningEvent.map(QuestioningEvent::getType).orElse(null), + questioning.getId().toString(), + moogService.getReadOnlyUrl(part.getCampaign().getId(), su.getIdSu()) + )); + } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/SearchSurveyUnitController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/SearchSurveyUnitController.java new file mode 100644 index 00000000..189654fe --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/SearchSurveyUnitController.java @@ -0,0 +1,121 @@ +package fr.insee.survey.datacollectionmanagement.query.controller; + +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; +import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; +import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; +import fr.insee.survey.datacollectionmanagement.query.dto.SearchSurveyUnitContactDto; +import fr.insee.survey.datacollectionmanagement.query.dto.SurveyUnitPartitioningDto; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; +import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; +import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningAccreditationService; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; +import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.*; + +@RestController +@PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + + "|| @AuthorizeMethodDecider.isWebClient() " + + "|| @AuthorizeMethodDecider.isAdmin() ") +@Tag(name = "4 - Cross domain") +@Slf4j +@RequiredArgsConstructor +public class SearchSurveyUnitController { + + + private final ContactService contactService; + + private final QuestioningService questioningService; + + private final QuestioningAccreditationService questioningAccreditationService; + + private final PartitioningService partitioningService; + + private final QuestioningEventService questioningEventService; + + + @GetMapping(path = Constants.API_SURVEY_UNITS_CONTACTS, produces = "application/json") + @Operation(summary = "Get contacts authorised to respond to a survey for a survey unit") + public ResponseEntity> getSurveyUnitContacts( + @PathVariable("id") String id) { + + List listContactIdentifiers = new ArrayList<>(); + Set setQuestionings = questioningService.findBySurveyUnitIdSu(id); + for (Questioning questioning : setQuestionings) { + for (QuestioningAccreditation qa : questioning.getQuestioningAccreditations()) { + if (!listContactIdentifiers.contains(qa.getIdContact())) + listContactIdentifiers.add(qa.getIdContact()); + + } + } + + List listResult = new ArrayList<>(); + for (String identifier : listContactIdentifiers) { + SearchSurveyUnitContactDto searchSurveyUnitContactDto = new SearchSurveyUnitContactDto(); + Contact contact = contactService.findByIdentifier(identifier); + searchSurveyUnitContactDto.setIdentifier(identifier); + searchSurveyUnitContactDto.setCity(contact.getEmail()); + searchSurveyUnitContactDto.setEmail(contact.getEmail()); + searchSurveyUnitContactDto.setFirstName(contact.getFirstName()); + searchSurveyUnitContactDto.setLastName(contact.getLastName()); + searchSurveyUnitContactDto.setPhoneNumber(contact.getPhone()); + searchSurveyUnitContactDto.setCity(contact.getAddress() != null ? contact.getAddress().getCityName() : null); + searchSurveyUnitContactDto.setListSourcesId(questioningAccreditationService.findByContactIdentifier(identifier).stream(). + filter(qa -> qa.getQuestioning().getSurveyUnit().getIdSu().equalsIgnoreCase(id)). + map(qa -> partitioningService.findById(qa.getQuestioning().getIdPartitioning()).getCampaign().getSurvey().getSource().getId()). + distinct().toList()); + listResult.add(searchSurveyUnitContactDto); + } + + return new ResponseEntity<>(listResult, HttpStatus.OK); + + } + + + @GetMapping(path = Constants.API_SURVEY_UNITS_PARTITIONINGS, produces = "application/json") + @Operation(summary = "Get contacts authorised to respond to a survey for a survey unit") + public ResponseEntity> getSurveyUnitPartitionings( + @PathVariable("id") String id, + @RequestParam(defaultValue = "false") boolean isFilterOpened) { + + List listParts = new ArrayList<>(); + Set setQuestionings = questioningService.findBySurveyUnitIdSu(id); + for (Questioning questioning : setQuestionings) { + Partitioning part = partitioningService.findById(questioning.getIdPartitioning()); + Optional questioningEvent = questioningEventService.getLastQuestioningEvent(questioning, TypeQuestioningEvent.STATE_EVENTS); + + if (!isFilterOpened || partitioningService.isOnGoing(part, new Date())) { + Survey survey = part.getCampaign().getSurvey(); + listParts.add(new SurveyUnitPartitioningDto( + survey.getSource().getShortWording(), + survey.getYear(), + part.getCampaign().getPeriod(), + part.getCampaign().getCampaignWording(), + part.getClosingDate(), + questioningEvent.map(QuestioningEvent::getType).orElse(null) + )); + } + + } + + return new ResponseEntity<>(listParts, HttpStatus.OK); + + } + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/WebclientController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/WebclientController.java index e159b531..f5717290 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/WebclientController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/controller/WebclientController.java @@ -5,10 +5,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact.Gender; import fr.insee.survey.datacollectionmanagement.contact.dto.ContactDto; import fr.insee.survey.datacollectionmanagement.contact.service.AddressService; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.*; import fr.insee.survey.datacollectionmanagement.metadata.dto.*; import fr.insee.survey.datacollectionmanagement.metadata.service.*; @@ -33,15 +34,17 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @@ -53,49 +56,37 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Slf4j @Tag(name = "6 - Webclients", description = "Enpoints for webclients") +@RequiredArgsConstructor +@Validated public class WebclientController { - @Autowired - QuestioningService questioningService; + private final QuestioningService questioningService; - @Autowired - SurveyUnitService surveyUnitService; + private final SurveyUnitService surveyUnitService; - @Autowired - PartitioningService partitioningService; + private final PartitioningService partitioningService; - @Autowired - SourceService sourceService; + private final SourceService sourceService; - @Autowired - SurveyService surveyService; + private final SurveyService surveyService; - @Autowired - CampaignService campaignService; + private final CampaignService campaignService; - @Autowired - OwnerService ownerService; + private final OwnerService ownerService; - @Autowired - SupportService supportService; + private final SupportService supportService; - @Autowired - ContactService contactService; + private final ContactService contactService; - @Autowired - AddressService addressService; + private final AddressService addressService; - @Autowired - ViewService viewService; + private final ViewService viewService; - @Autowired - QuestioningAccreditationService questioningAccreditationService; + private final QuestioningAccreditationService questioningAccreditationService; - @Autowired - QuestioningEventService questioningEventService; + private final QuestioningEventService questioningEventService; - @Autowired - private ModelMapper modelMapper; + private final ModelMapper modelMapper; @Operation(summary = "Create or update questioning for webclients - Returns the questioning and all its accreditations") @PutMapping(value = Constants.API_WEBCLIENT_QUESTIONINGS, produces = "application/json", consumes = "application/json") @@ -121,12 +112,8 @@ public ResponseEntity putQuestioning(@RequestBody QuestioningWebclientDto que return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Missing fields"); } - Optional part = partitioningService.findById(idPartitioning); + Partitioning part = partitioningService.findById(idPartitioning); - if (!part.isPresent()) { - log.warn("Partitioning {} does not exist", idPartitioning); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Partitioning does not exist"); - } QuestioningWebclientDto questioningReturn = new QuestioningWebclientDto(); SurveyUnit su; @@ -135,10 +122,11 @@ public ResponseEntity putQuestioning(@RequestBody QuestioningWebclientDto que su = convertToEntity(questioningWebclientDto.getSurveyUnit()); // Create su if not exists or update - Optional optSuBase = surveyUnitService.findbyId(idSu); - if (optSuBase.isPresent()) { - su.setQuestionings(optSuBase.get().getQuestionings()); - } else { + try { + SurveyUnit optSuBase = surveyUnitService.findbyId(idSu); + su.setQuestionings(optSuBase.getQuestionings()); + + } catch (NotFoundException e) { log.warn("survey unit {} does not exist - Creation of the survey unit", idSu); su.setQuestionings(new HashSet<>()); @@ -165,14 +153,14 @@ public ResponseEntity putQuestioning(@RequestBody QuestioningWebclientDto que } - for (ContactAccreditationDto contactAccreditationDto : questioningWebclientDto.getContacts()){ + for (ContactAccreditationDto contactAccreditationDto : questioningWebclientDto.getContacts()) { createContactAndAccreditations(idSu, part, questioning, contactAccreditationDto); } // save questioning and su questioningService.saveQuestioning(questioning); su.getQuestionings().add(questioning); - su = surveyUnitService.saveSurveyUnitAndAddress(su); + surveyUnitService.saveSurveyUnitAndAddress(su); questioningReturn.setIdPartitioning(idPartitioning); @@ -181,7 +169,7 @@ public ResponseEntity putQuestioning(@RequestBody QuestioningWebclientDto que List listContactAccreditationDto = new ArrayList<>(); questioning.getQuestioningAccreditations().stream() .forEach(acc -> listContactAccreditationDto - .add(convertToDto(contactService.findByIdentifier(acc.getIdContact()).get(), acc.isMain()))); + .add(convertToDto(contactService.findByIdentifier(acc.getIdContact()), acc.isMain()))); questioningReturn.setContacts(listContactAccreditationDto); @@ -192,7 +180,7 @@ public ResponseEntity putQuestioning(@RequestBody QuestioningWebclientDto que } - private void createContactAndAccreditations(String idSu, Optional part, Questioning questioning, ContactAccreditationDto contactAccreditationDto) throws JsonProcessingException { + private void createContactAndAccreditations(String idSu, Partitioning part, Questioning questioning, ContactAccreditationDto contactAccreditationDto) throws JsonProcessingException { // Create contact if not exists or update JsonNode node = addWebclientAuthorNode(); @@ -202,7 +190,7 @@ private void createContactAndAccreditations(String idSu, Optional if (contactAccreditationDto.getAddress() != null) contact.setAddress(addressService.convertToEntity(contactAccreditationDto.getAddress())); contactService.updateContactAddressEvent(contact, node); - } catch (NoSuchElementException e) { + } catch (NoSuchElementException | NotFoundException e) { log.info("Creating contact with the identifier {}", contactAccreditationDto.getIdentifier()); contact = convertToEntityNewContact(contactAccreditationDto); if (contactAccreditationDto.getAddress() != null) @@ -214,12 +202,12 @@ private void createContactAndAccreditations(String idSu, Optional Set setExistingAccreditations = (questioning .getQuestioningAccreditations() != null) ? questioning.getQuestioningAccreditations() - : new HashSet<>(); + : new HashSet<>(); List listContactAccreditations = setExistingAccreditations.stream() .filter(acc -> acc.getIdContact().equals(contactAccreditationDto.getIdentifier()) - && acc.getQuestioning().getIdPartitioning().equals(part.get().getId()) + && acc.getQuestioning().getIdPartitioning().equals(part.getId()) && acc.getQuestioning().getSurveyUnit().getIdSu().equals(idSu)) .toList(); @@ -235,7 +223,7 @@ private void createContactAndAccreditations(String idSu, Optional // create view viewService.createView(contactAccreditationDto.getIdentifier(), questioning.getSurveyUnit().getIdSu(), - part.get().getCampaign().getId()); + part.getCampaign().getId()); questioning.getQuestioningAccreditations().add(questioningAccreditation); } else { @@ -253,9 +241,8 @@ private void createContactAndAccreditations(String idSu, Optional @ApiResponse(responseCode = "404", description = "Not found"), }) public ResponseEntity getQuestioning(@RequestParam(required = true) String modelName, - @RequestParam(required = true) String idPartitioning, - @RequestParam(required = true) String idSurveyUnit) - { + @RequestParam(required = true) String idPartitioning, + @RequestParam(required = true) String idSurveyUnit) { QuestioningWebclientDto questioningWebclientDto = new QuestioningWebclientDto(); @@ -273,7 +260,7 @@ public ResponseEntity getQuestioning(@RequestParam(required = true) String mo List listContactAccreditationDto = new ArrayList<>(); questioning.getQuestioningAccreditations().stream() .forEach(acc -> listContactAccreditationDto - .add(convertToDto(contactService.findByIdentifier(acc.getIdContact()).get(), acc.isMain()))); + .add(convertToDto(contactService.findByIdentifier(acc.getIdContact()), acc.isMain()))); questioningWebclientDto.setContacts(listContactAccreditationDto); return ResponseEntity.status(httpStatus).body(questioningWebclientDto); @@ -288,18 +275,16 @@ public ResponseEntity getQuestioning(@RequestParam(required = true) String mo }) public ResponseEntity getMetadata(@PathVariable("id") String id) { MetadataDto metadataDto = new MetadataDto(); + Partitioning part = partitioningService.findById(StringUtils.upperCase(id)); + try { - Optional part = partitioningService.findById(StringUtils.upperCase(id)); - if (!part.isPresent()) { - log.warn("partitioning {} does not exist", id); - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("partitioning does not exist"); - } - metadataDto.setPartitioningDto(convertToDto(part.get())); - metadataDto.setCampaignDto(convertToDto(part.get().getCampaign())); - metadataDto.setSurveyDto(convertToDto(part.get().getCampaign().getSurvey())); - metadataDto.setSourceDto(convertToDto(part.get().getCampaign().getSurvey().getSource())); - metadataDto.setOwnerDto(convertToDto(part.get().getCampaign().getSurvey().getSource().getOwner())); - metadataDto.setSupportDto(convertToDto(part.get().getCampaign().getSurvey().getSource().getSupport())); + + metadataDto.setPartitioningDto(convertToDto(part)); + metadataDto.setCampaignDto(convertToDto(part.getCampaign())); + metadataDto.setSurveyDto(convertToDto(part.getCampaign().getSurvey())); + metadataDto.setSourceDto(convertToDto(part.getCampaign().getSurvey().getSource())); + metadataDto.setOwnerDto(convertToDto(part.getCampaign().getSurvey().getSource().getOwner())); + metadataDto.setSupportDto(convertToDto(part.getCampaign().getSurvey().getSource().getSupport())); return ResponseEntity.ok().body(metadataDto); } catch (Exception e) { @@ -317,12 +302,12 @@ public ResponseEntity getMetadata(@PathVariable("id") String id) { }) @Transactional public ResponseEntity putMetadata(@PathVariable("id") String id, - @RequestBody MetadataDto metadataDto) { + @RequestBody @Valid MetadataDto metadataDto) { + if (!metadataDto.getPartitioningDto().getId().equalsIgnoreCase(id)) { + throw new NotMatchException("id and idPartitioning don't match"); + } try { - if (StringUtils.isBlank(metadataDto.getPartitioningDto().getId()) - || !metadataDto.getPartitioningDto().getId().equalsIgnoreCase(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and idPartitioning don't match"); - } + MetadataDto metadataReturn = new MetadataDto(); HttpHeaders responseHeaders = new HttpHeaders(); @@ -330,16 +315,17 @@ public ResponseEntity putMetadata(@PathVariable("id") String id, ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(id).toUriString()); HttpStatus httpStatus; - if (partitioningService.findById(id).isPresent()) { - log.info("Update partitioning with the id {}", id); + try { partitioningService.findById(id); + log.info("Update partitioning with the id {}", id); httpStatus = HttpStatus.OK; - } else { + } catch (NotFoundException e) { log.info("Create partitioning with the id {}", id); httpStatus = HttpStatus.CREATED; } + Owner owner = convertToEntity(metadataDto.getOwnerDto()); Support support = convertToEntity(metadataDto.getSupportDto()); Source source = convertToEntity(metadataDto.getSourceDto()); @@ -414,8 +400,10 @@ public ResponseEntity getMainContact( List listQa = questioning.getQuestioningAccreditations().stream() .filter(qa -> qa.isMain()).toList(); if (listQa != null && !listQa.isEmpty()) { - Contact c = contactService.findByIdentifier(listQa.get(0).getIdContact()).get(); + Contact c = contactService.findByIdentifier(listQa.get(0).getIdContact()); return ResponseEntity.status(HttpStatus.OK).body(convertToDto((c))); + + } } return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No contact found"); @@ -435,7 +423,7 @@ public ResponseEntity getMainContact( @ApiResponse(responseCode = "400", description = "Bad request") }) public ResponseEntity getState(@PathVariable("idPartitioning") String idPartitioning, - @PathVariable("idSu") String idSu) { + @PathVariable("idSu") String idSu) { Questioning questioning = questioningService.findByIdPartitioningAndSurveyUnitIdSu( idPartitioning, idSu); @@ -522,7 +510,7 @@ private JsonNode addWebclientAuthorNode() throws JsonProcessingException { @ApiResponse(responseCode = "400", description = "Bad request") }) public ResponseEntity isToExtract(@PathVariable("idPartitioning") String idPartitioning, - @PathVariable("idSu") String idSu) { + @PathVariable("idSu") String idSu) { Questioning questioning = questioningService.findByIdPartitioningAndSurveyUnitIdSu( idPartitioning, idSu); @@ -569,12 +557,10 @@ private Contact convertToEntity(ContactAccreditationDto contactAccreditationDto) Contact contact = modelMapper.map(contactAccreditationDto, Contact.class); contact.setGender(contactAccreditationDto.getCivility()); - Optional oldContact = contactService.findByIdentifier(contactAccreditationDto.getIdentifier()); - if (!oldContact.isPresent()) - throw new NoSuchElementException(); - contact.setComment(oldContact.get().getComment()); - contact.setAddress(oldContact.get().getAddress()); - contact.setContactEvents(oldContact.get().getContactEvents()); + Contact oldContact = contactService.findByIdentifier(contactAccreditationDto.getIdentifier()); + contact.setComment(oldContact.getComment()); + contact.setAddress(oldContact.getAddress()); + contact.setContactEvents(oldContact.getContactEvents()); return contact; } @@ -598,7 +584,7 @@ private SupportDto convertToDto(Support support) { private ContactDto convertToDto(Contact contact) { ContactDto contactDto = modelMapper.map(contact, ContactDto.class); - contactDto.setCivility(contact.getGender()); + contactDto.setCivility(contact.getGender().name()); return contactDto; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/AccreditationDetailDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/AccreditationDetailDto.java index b5ea085f..43561200 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/AccreditationDetailDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/AccreditationDetailDto.java @@ -1,40 +1,32 @@ package fr.insee.survey.datacollectionmanagement.query.dto; import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; +import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import java.util.Date; + @Getter @Setter +@AllArgsConstructor public class AccreditationDetailDto { private String sourceId; + + private String surveyId; private String sourceWording; private int year; private PeriodEnum period; private String partition; - private String identificationCode; + private Date partioningClosingDate; + private String surveyUnitId; private String identificationName; private boolean isMain; + private TypeQuestioningEvent lastEvent; + private String questioningId; + private String questioningUrl; - public AccreditationDetailDto( - String sourceId, - String sourceWording, - int year, - PeriodEnum period, - String partition, - String identificationCode, - String identificationName, - boolean isMain) { - super(); - this.sourceId = sourceId; - this.sourceWording = sourceWording; - this.year = year; - this.period = period; - this.partition = partition; - this.identificationCode = identificationCode; - this.identificationName = identificationName; - this.isMain = isMain; - } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SearchContactDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SearchContactDto.java index 98514500..85afbfcc 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SearchContactDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SearchContactDto.java @@ -3,6 +3,8 @@ import lombok.Getter; import lombok.Setter; +import java.util.List; + @Getter @Setter public class SearchContactDto { @@ -11,4 +13,9 @@ public class SearchContactDto { private String firstName; private String lastName; private String email; + private String phone; + private String city; + private String function; + private List listSurveyUnitNames; + private List listSourcesId; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SearchSurveyUnitContactDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SearchSurveyUnitContactDto.java new file mode 100644 index 00000000..01219e7a --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SearchSurveyUnitContactDto.java @@ -0,0 +1,19 @@ +package fr.insee.survey.datacollectionmanagement.query.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class SearchSurveyUnitContactDto { + + private String identifier; + private String firstName; + private String lastName; + private String email; + private String city; + private String phoneNumber; + private List listSourcesId; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SurveyUnitPartitioningDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SurveyUnitPartitioningDto.java new file mode 100644 index 00000000..b14fec4a --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/dto/SurveyUnitPartitioningDto.java @@ -0,0 +1,23 @@ +package fr.insee.survey.datacollectionmanagement.query.dto; + +import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; +import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.util.Date; + +@Getter +@Setter +@AllArgsConstructor +public class SurveyUnitPartitioningDto { + + private String sourceWording; + private int year; + private PeriodEnum period; + private String campaignWording; + private Date partioningClosingDate; + private TypeQuestioningEvent lastEvent; + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/repository/MonitoringRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/repository/MonitoringRepository.java index 6959780b..dd8b836c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/repository/MonitoringRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/repository/MonitoringRepository.java @@ -1,22 +1,21 @@ package fr.insee.survey.datacollectionmanagement.query.repository; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; +import fr.insee.survey.datacollectionmanagement.query.dto.MoogFollowUpDto; +import fr.insee.survey.datacollectionmanagement.query.dto.MoogRowProgressDto; +import lombok.RequiredArgsConstructor; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; -import fr.insee.survey.datacollectionmanagement.query.dto.MoogFollowUpDto; -import fr.insee.survey.datacollectionmanagement.query.dto.MoogRowProgressDto; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; @Repository +@RequiredArgsConstructor public class MonitoringRepository { - @Autowired - JdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; final String progressQuery = "SELECT COUNT(survey_unit_id_su) as total,status,batch_num FROM\n" + "(SELECT DISTINCT ON (survey_unit_id_su) survey_unit_id_su,status,event_order,batch_num FROM (SELECT event_order, campaign_id, C.status, batch_num, survey_unit_id_su FROM (SELECT campaign_id, type as status, id_partitioning as batch_num, survey_unit_id_su FROM\n" + diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/repository/MoogRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/repository/MoogRepository.java index aac44099..01bc3f14 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/repository/MoogRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/repository/MoogRepository.java @@ -1,31 +1,28 @@ package fr.insee.survey.datacollectionmanagement.query.repository; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - import fr.insee.survey.datacollectionmanagement.contact.domain.Address; import fr.insee.survey.datacollectionmanagement.contact.service.AddressService; -import fr.insee.survey.datacollectionmanagement.contact.service.impl.AddressServiceImpl; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.query.dto.MoogExtractionRowDto; +import fr.insee.survey.datacollectionmanagement.query.dto.MoogQuestioningEventDto; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; -import fr.insee.survey.datacollectionmanagement.query.dto.MoogQuestioningEventDto; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; @Repository +@RequiredArgsConstructor +@Slf4j public class MoogRepository { - @Autowired - JdbcTemplate jdbcTemplate; + private final JdbcTemplate jdbcTemplate; - @Autowired - AddressService addressService; + private final AddressService addressService; final String getEventsQuery = "SELECT qe.id, date, type, survey_unit_id_su, campaign_id " + " FROM questioning_event qe join questioning q on qe.questioning_id=q.id join partitioning p on q.id_partitioning=p.id " @@ -106,7 +103,6 @@ public MoogExtractionRowDto mapRow(ResultSet rs, int rowNum) throws SQLException MoogExtractionRowDto ev = new MoogExtractionRowDto(); ev.setAddress("addresse non connue"); - Optional
address = addressService.findById(rs.getLong("address")); ev.setStatus(rs.getString("status")); ev.setDateInfo(rs.getString("dateinfo")); @@ -114,9 +110,14 @@ public MoogExtractionRowDto mapRow(ResultSet rs, int rowNum) throws SQLException ev.setIdContact(rs.getString("id_contact")); ev.setLastname(rs.getString("lastname")); ev.setFirstname(rs.getString("firstname")); - if (address.isPresent()) { - ev.setAddress(address.get().toStringMoog()); + try { + Address address = addressService.findById(rs.getLong("address")); + ev.setAddress(address.toStringMoog()); } + catch (NotFoundException e){ + log.info("Address not found"); + } + ev.setBatchNumber(rs.getString("batch_num")); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/CheckHabilitationService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/CheckHabilitationService.java index 4e56a527..b4f4002c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/CheckHabilitationService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/CheckHabilitationService.java @@ -1,15 +1,12 @@ package fr.insee.survey.datacollectionmanagement.query.service; -import fr.insee.survey.datacollectionmanagement.query.dto.HabilitationDto; -import org.apache.coyote.Response; -import org.springframework.http.ResponseEntity; +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; @Service public interface CheckHabilitationService { - ResponseEntity checkHabilitation(String role, String idSu, String campaign); + boolean checkHabilitation(String role, String idSu, String campaign, AuthUser authUser); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/MoogService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/MoogService.java index 850cae20..d7eeec41 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/MoogService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/MoogService.java @@ -1,16 +1,15 @@ package fr.insee.survey.datacollectionmanagement.query.service; -import java.util.Collection; -import java.util.List; - import fr.insee.survey.datacollectionmanagement.config.JSONCollectionWrapper; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.query.dto.MoogExtractionRowDto; -import org.springframework.stereotype.Service; - import fr.insee.survey.datacollectionmanagement.query.dto.MoogQuestioningEventDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogSearchDto; import fr.insee.survey.datacollectionmanagement.view.domain.View; -import org.webjars.NotFoundException; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; @Service public interface MoogService { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/SearchContactService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/SearchContactService.java index bc88a287..c7a450cf 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/SearchContactService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/SearchContactService.java @@ -1,41 +1,26 @@ package fr.insee.survey.datacollectionmanagement.query.service; -import java.util.List; - -import org.springframework.data.domain.Pageable; - import fr.insee.survey.datacollectionmanagement.query.dto.SearchContactDto; -import fr.insee.survey.datacollectionmanagement.view.domain.View; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; public interface SearchContactService { /** * Search contact according to diffeent parameters - * @param identifier - * @param lastName - * @param firstName - * @param email - * @param idSu - * @param identificationCode - * @param identificationName - * @param source - * @param year - * @param period + * @param identifier contact identifier + * @param name (first name or and lastName) + * @param email contact email + * @param city contact city + * @param function contact function + * @return */ - List searchContactCrossDomain( + Page searchContactCrossDomain( String identifier, - String lastName, - String firstName, + String name, String email, - String idSu, - String identificationCode, - String identificationName, - String source, - String year, - String period, + String city, + String function, Pageable pageable); - - List transformListViewDaoToDto(List subList); - } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImpl.java deleted file mode 100644 index 6561ff6d..00000000 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImpl.java +++ /dev/null @@ -1,136 +0,0 @@ -package fr.insee.survey.datacollectionmanagement.query.service.impl; - -import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; -import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; -import fr.insee.survey.datacollectionmanagement.query.dto.HabilitationDto; -import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; -import fr.insee.survey.datacollectionmanagement.user.domain.User; -import fr.insee.survey.datacollectionmanagement.user.service.UserService; -import fr.insee.survey.datacollectionmanagement.view.service.ViewService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.jwt.Jwt; -import org.springframework.stereotype.Service; - -import javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; - -@Service -public class CheckHabilitationServiceImpl implements CheckHabilitationService { - - static final Logger LOGGER = LoggerFactory.getLogger(CheckHabilitationServiceImpl.class); - - @Autowired - ApplicationConfig applicationConfig; - - @Autowired - private ViewService viewService; - - @Autowired - CampaignService campaignService; - - @Autowired - UserService userService; - - @Override - public ResponseEntity checkHabilitation(String role, String idSu, String campaignId) { - - HabilitationDto resp = new HabilitationDto(); - - //noauth - if (!applicationConfig.getAuthType().equals("OIDC")) { - resp.setHabilitated(true); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - final Jwt jwt = (Jwt) authentication.getPrincipal(); - List roles = jwt.getClaimAsStringList(applicationConfig.getRoleClaim()); - String idec=jwt.getClaimAsString(applicationConfig.getIdClaim()).toUpperCase(); - - //admin - if(isUserInRole(roles, applicationConfig.getRoleAdmin())){ - LOGGER.info("Check habilitation of admin {} for accessing survey-unit {} of campaign {} resulted in true",idec,idSu,campaignId); - resp.setHabilitated(true); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - - //respondents - if (role == null || role.isBlank() || role.equals(Constants.INTERVIEWER) ) - { - if(isUserInRole(roles, applicationConfig.getRoleRespondent())) { - boolean habilitated = viewService.countViewByIdentifierIdSuCampaignId(idec, idSu, campaignId) != 0; - LOGGER.info("Check habilitation of interviewer {} for accessing survey-unit {} of campaign {} resulted in {}", idec, idSu, campaignId, habilitated); - resp.setHabilitated(habilitated); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - LOGGER.warn("Check habilitation of interviewer {} for accessing survey-unit {} of campaign {} - no respondent habilitation found in token - check habilitation: false", idec, idSu, campaignId); - resp.setHabilitated(false); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - - - // internal users - Optional user= userService.findByIdentifier(idec); - if(role.equals(Constants.REVIEWER) ) { - if(isUserInRole(roles, applicationConfig.getRoleInternalUser())) { - if (user.isPresent()) { - String userRole; - //List accreditedSources = new ArrayList<>(); - userRole = user.get().getRole().toString(); - if (userRole.equals(User.UserRoleType.assistance)) { - resp.setHabilitated(false); - LOGGER.warn("User '{}' has assistance profile - check habilitation: false", idec); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - /*accreditedSources = userService.findAccreditedSources(user.get().getIdentifier()); - Optional campaign = campaignService.findById(campaignId); - if (campaign.isPresent()) { - String sourceSearched = campaign.get().getSurvey().getSource().getId(); - if (accreditedSources.contains(sourceSearched)) { - LOGGER.info("User {} with profile {} - accreditation found for campaign {} - Check habilitation:true", idec, userRole, campaignId); - resp.setHabilitated(true); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - LOGGER.warn("User {} with profile {} - has no accreditation for campaign {} - Check habilitation:false", idec, userRole, campaignId); - resp.setHabilitated(false); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - LOGGER.warn("Check habilitation of user {} for accessing survey-unit {} of campaign {} - campaign doesn't exist - check habilitation:false", idec, idSu, campaign); - resp.setHabilitated(false); - return new ResponseEntity<>(resp, HttpStatus.OK);*/ - resp.setHabilitated(true); - LOGGER.warn("User '{}' has {} profile - check habilitation: true", idec, userRole); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - - resp.setHabilitated(false); - LOGGER.warn("User '{}' doesn't exists", idec); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - resp.setHabilitated(false); - LOGGER.warn("User {} - internal user habilitation not found in token - Check habilitation:false", idec); - return new ResponseEntity<>(resp, HttpStatus.OK); - } - - resp.setHabilitated(false); - LOGGER.warn("Only '{}' ans '{}' are accepted as a role in query argument", Constants.REVIEWER, Constants.INTERVIEWER); - return new ResponseEntity<>(resp, HttpStatus.OK); - - } - - private boolean isUserInRole(List roles, List role) { - - return role.stream().anyMatch(r -> roles.contains(r)); - } - -} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplNoAuth.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplNoAuth.java new file mode 100644 index 00000000..5f660495 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplNoAuth.java @@ -0,0 +1,21 @@ +package fr.insee.survey.datacollectionmanagement.query.service.impl; + +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; +import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@ConditionalOnExpression("'${fr.insee.datacollectionmanagement.auth.mode}' ne 'OIDC'") +@Slf4j +public class CheckHabilitationServiceImplNoAuth implements CheckHabilitationService { + + @Override + public boolean checkHabilitation(String role, String idSu, String campaignId, AuthUser authUser) { + return true; + } + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplOidc.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplOidc.java new file mode 100644 index 00000000..7a6b39a8 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/CheckHabilitationServiceImplOidc.java @@ -0,0 +1,89 @@ +package fr.insee.survey.datacollectionmanagement.query.service.impl; + +import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; +import fr.insee.survey.datacollectionmanagement.config.auth.user.AuthUser; +import fr.insee.survey.datacollectionmanagement.constants.AuthConstants; +import fr.insee.survey.datacollectionmanagement.constants.CheckHabilitationsRoles; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; +import fr.insee.survey.datacollectionmanagement.user.domain.User; +import fr.insee.survey.datacollectionmanagement.user.service.UserService; +import fr.insee.survey.datacollectionmanagement.view.service.ViewService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@ConditionalOnProperty(name = "fr.insee.datacollectionmanagement.auth.mode", havingValue = AuthConstants.OIDC) +@Slf4j +public class CheckHabilitationServiceImplOidc implements CheckHabilitationService { + + private final ApplicationConfig applicationConfig; + + private final ViewService viewService; + + private final UserService userService; + + @Override + public boolean checkHabilitation(String role, String idSu, String campaignId, AuthUser authUser) { + + String userId = authUser.getId().toUpperCase(); + + //admin + if (isUserInRole(authUser.getRoles(), applicationConfig.getRoleAdmin())) { + log.info("Check habilitation of admin {} for accessing survey-unit {} of campaign {} resulted in true", userId, idSu, campaignId); + return true; + } + + //respondents + if (role == null || role.isBlank() || role.equals(CheckHabilitationsRoles.INTERVIEWER)) { + if (isUserInRole(authUser.getRoles(), applicationConfig.getRoleRespondent())) { + boolean habilitated = viewService.countViewByIdentifierIdSuCampaignId(userId.toUpperCase(), idSu, campaignId) != 0; + log.info("Check habilitation of interviewer {} for accessing survey-unit {} of campaign {} resulted in {}", userId, idSu, campaignId, habilitated); + return habilitated; + } + log.warn("Check habilitation of interviewer {} for accessing survey-unit {} of campaign {} - no respondent habilitation found in token - check habilitation: false", userId, idSu, campaignId); + return false; + } + + + // internal users + if (!role.equals(CheckHabilitationsRoles.REVIEWER)) { + log.warn("User {} - internal user habilitation not found in token - Check habilitation:false", userId); + return false; + } + User user; + try { + user = userService.findByIdentifier(userId); + } catch (NotFoundException e) { + log.warn("User '{}' doesn't exists", userId); + return false; + } + + + if (isUserInRole(authUser.getRoles(), applicationConfig.getRoleInternalUser())) { + String userRole = user.getRole().toString(); + if (userRole.equals(User.UserRoleType.ASSISTANCE.toString())) { + log.warn("User '{}' has assistance profile - check habilitation: false", userId); + return false; + } + log.warn("User '{}' has {} profile - check habilitation: true", userId, userRole); + return true; + + + } + log.warn("Only '{}' and '{}' are accepted as a role in query argument", CheckHabilitationsRoles.REVIEWER, CheckHabilitationsRoles.INTERVIEWER); + return false; + + } + + private boolean isUserInRole(List roles, List role) { + + return role.stream().anyMatch(roles::contains); + } + +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MonitoringServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MonitoringServiceImpl.java index 7b3502d3..e02d7fee 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MonitoringServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MonitoringServiceImpl.java @@ -1,23 +1,22 @@ package fr.insee.survey.datacollectionmanagement.query.service.impl; -import java.util.HashMap; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import fr.insee.survey.datacollectionmanagement.config.JSONCollectionWrapper; import fr.insee.survey.datacollectionmanagement.query.dto.MoogFollowUpDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogProgressDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogRowProgressDto; import fr.insee.survey.datacollectionmanagement.query.repository.MonitoringRepository; import fr.insee.survey.datacollectionmanagement.query.service.MonitoringService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; @Service +@RequiredArgsConstructor public class MonitoringServiceImpl implements MonitoringService { - @Autowired - MonitoringRepository monitoringRepository; + private final MonitoringRepository monitoringRepository; @Override public JSONCollectionWrapper getProgress(String idCampaign) { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MoogServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MoogServiceImpl.java index f443ce84..562d5aef 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MoogServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MoogServiceImpl.java @@ -1,60 +1,47 @@ package fr.insee.survey.datacollectionmanagement.query.service.impl; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; import fr.insee.survey.datacollectionmanagement.config.JSONCollectionWrapper; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; -import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; -import fr.insee.survey.datacollectionmanagement.query.dto.MoogExtractionRowDto; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; -import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; import fr.insee.survey.datacollectionmanagement.query.domain.MoogCampaign; +import fr.insee.survey.datacollectionmanagement.query.dto.MoogExtractionRowDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogQuestioningEventDto; import fr.insee.survey.datacollectionmanagement.query.dto.MoogSearchDto; import fr.insee.survey.datacollectionmanagement.query.repository.MoogRepository; import fr.insee.survey.datacollectionmanagement.query.service.MoogService; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import fr.insee.survey.datacollectionmanagement.view.domain.View; import fr.insee.survey.datacollectionmanagement.view.service.ViewService; -import org.webjars.NotFoundException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.*; @Service @Slf4j +@RequiredArgsConstructor public class MoogServiceImpl implements MoogService { public static final String READONLY_QUESTIONNAIRE = "/readonly/questionnaire/"; public static final String UNITE_ENQUETEE = "/unite-enquetee/"; - @Autowired - private ViewService viewService; + private final ViewService viewService; - @Autowired - private ContactService contactService; + private final ContactService contactService; - @Autowired - private CampaignService campaignService; + private final CampaignService campaignService; - @Autowired - private MoogRepository moogRepository; + private final MoogRepository moogRepository; - @Autowired - QuestioningService questioningService; + private final QuestioningService questioningService; - @Autowired - PartitioningService partitioningService; - - @Autowired - ApplicationConfig applicationConfig; + private final ApplicationConfig applicationConfig; @Override public List moogSearch(String field) { @@ -69,28 +56,22 @@ public List transformListViewToListMoogSearchDto(List listV List listResult = new ArrayList<>(); for (View view : listView) { MoogSearchDto moogSearchDto = new MoogSearchDto(); - Optional c = contactService.findByIdentifier(view.getIdentifier()); - Optional camp = campaignService.findById(view.getCampaignId()); - if (!camp.isPresent()) { - throw new NoSuchElementException("campaign does not exist"); - } - if (!c.isPresent()) { - throw new NoSuchElementException("contact does not exist"); - } - MoogCampaign moogCampaign = new MoogCampaign(); + Contact c = contactService.findByIdentifier(view.getIdentifier()); + Campaign camp = campaignService.findById(view.getCampaignId()); + MoogCampaign moogCampaign = new MoogCampaign(); moogCampaign.setId(view.getCampaignId()); - moogCampaign.setLabel(camp.get().getCampaignWording()); + moogCampaign.setLabel(camp.getCampaignWording()); moogCampaign - .setCollectionEndDate(camp.get().getPartitionings().iterator().next().getClosingDate().getTime()); + .setCollectionEndDate(camp.getPartitionings().iterator().next().getClosingDate().getTime()); moogCampaign - .setCollectionStartDate(camp.get().getPartitionings().iterator().next().getOpeningDate().getTime()); + .setCollectionStartDate(camp.getPartitionings().iterator().next().getOpeningDate().getTime()); moogSearchDto.setIdContact(view.getIdentifier()); - moogSearchDto.setAddress(c.get().getAddress().getZipCode().concat(" ").concat(c.get().getAddress().getCityName())); + moogSearchDto.setAddress(c.getAddress().getZipCode().concat(" ").concat(c.getAddress().getCityName())); moogSearchDto.setIdSu(view.getIdSu()); moogSearchDto.setCampaign(moogCampaign); - moogSearchDto.setFirstName(c.get().getFirstName()); - moogSearchDto.setLastname(c.get().getLastName()); - moogSearchDto.setSource(camp.get().getSurvey().getSource().getId()); + moogSearchDto.setFirstName(c.getFirstName()); + moogSearchDto.setLastname(c.getLastName()); + moogSearchDto.setSource(camp.getSurvey().getSource().getId()); listResult.add(moogSearchDto); } return listResult; @@ -101,15 +82,12 @@ public List getMoogEvents(String campaign, String idSu) List moogEvents = moogRepository.getEventsByIdSuByCampaign(campaign, idSu); - Optional camp = campaignService.findById(campaign); - if (!camp.isPresent()) { - throw new NoSuchElementException("campaign does not exist"); - } + Campaign camp = campaignService.findById(campaign); MoogCampaign moogCampaign = new MoogCampaign(); moogCampaign.setId(campaign); - moogCampaign.setLabel(camp.get().getCampaignWording()); - moogCampaign.setCollectionEndDate(camp.get().getPartitionings().iterator().next().getClosingDate().getTime()); - moogCampaign.setCollectionStartDate(camp.get().getPartitionings().iterator().next().getOpeningDate().getTime()); + moogCampaign.setLabel(camp.getCampaignWording()); + moogCampaign.setCollectionEndDate(camp.getPartitionings().iterator().next().getClosingDate().getTime()); + moogCampaign.setCollectionStartDate(camp.getPartitionings().iterator().next().getOpeningDate().getTime()); MoogSearchDto surveyUnit = new MoogSearchDto(); surveyUnit.setCampaign(moogCampaign); moogEvents.stream().forEach(e -> e.setSurveyUnit(surveyUnit)); @@ -128,11 +106,8 @@ public Collection getSurveyUnitsToFollowUp(String idCampai @Override public String getReadOnlyUrl(String idCampaign, String surveyUnitId) throws NotFoundException { - Optional campaign = campaignService.findById(idCampaign); - if (!campaign.isPresent()) { - throw new NotFoundException("Campaign not found"); - } - Set setParts = campaign.get().getPartitionings(); + Campaign campaign = campaignService.findById(idCampaign); + Set setParts = campaign.getPartitionings(); Questioning questioning = null; for (Partitioning part : setParts){ Questioning qTemp = questioningService.findByIdPartitioningAndSurveyUnitIdSu(part.getId(), surveyUnitId); @@ -147,7 +122,7 @@ public String getReadOnlyUrl(String idCampaign, String surveyUnitId) throws NotF } String msg = "0 questioning found for campaign "+idCampaign+" and survey unit "+ surveyUnitId; log.error(msg); - throw new NotFoundException(msg); + throw new NotFoundException(msg); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MySurveysServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MySurveysServiceImpl.java index 7fbdf6eb..aa55bd8c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MySurveysServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/MySurveysServiceImpl.java @@ -1,18 +1,5 @@ package fr.insee.survey.datacollectionmanagement.query.service.impl; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; -import lombok.extern.slf4j.Slf4j; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; @@ -23,23 +10,29 @@ import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningAccreditationService; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; @Service @Slf4j +@RequiredArgsConstructor public class MySurveysServiceImpl implements MySurveysService { - @Autowired - private QuestioningAccreditationService questioningAccreditationService; + private final QuestioningAccreditationService questioningAccreditationService; - @Autowired - private PartitioningService partitioningService; + private final PartitioningService partitioningService; - @Autowired - private QuestioningEventService questioningEventService; + private final QuestioningEventService questioningEventService; - @Autowired - QuestioningService questioningService; + private final QuestioningService questioningService; @Override @@ -50,29 +43,28 @@ public List getListMySurveys(String id) { for (QuestioningAccreditation questioningAccreditation : accreditations) { MyQuestioningDto surveyDto = new MyQuestioningDto(); Questioning questioning = questioningAccreditation.getQuestioning(); - Optional part = partitioningService.findById(questioning.getIdPartitioning()); - if (part.isPresent()) { - Survey survey = part.get().getCampaign().getSurvey(); - String surveyUnitId = questioning.getSurveyUnit().getIdSu(); - surveyDto.setSurveyWording(survey.getLongWording()); - surveyDto.setSurveyObjectives(survey.getLongObjectives()); - surveyDto.setAccessUrl( - questioningService.getAccessUrl(questioning, surveyUnitId)); - surveyDto.setIdentificationCode(surveyUnitId); - surveyDto.setOpeningDate(new Timestamp(part.get().getOpeningDate().getTime())); - surveyDto.setClosingDate(new Timestamp(part.get().getClosingDate().getTime())); - surveyDto.setReturnDate(new Timestamp(part.get().getReturnDate().getTime())); - surveyDto.setMandatoryMySurveys(part.get().getCampaign().getSurvey().getSource().getMandatoryMySurveys()); - - Optional questioningEvent = questioningEventService.getLastQuestioningEvent( - questioning, TypeQuestioningEvent.MY_QUESTIONINGS_EVENTS); - if (questioningEvent.isPresent()) { - surveyDto.setQuestioningStatus(questioningEvent.get().getType().name()); - surveyDto.setQuestioningDate(new Timestamp(questioningEvent.get().getDate().getTime())); - } else { - log.debug("No questioningEvents found for questioning {} for identifier {}", - questioning.getId(), id); - } + Partitioning part = partitioningService.findById(questioning.getIdPartitioning()); + Survey survey = part.getCampaign().getSurvey(); + String surveyUnitId = questioning.getSurveyUnit().getIdSu(); + surveyDto.setSurveyWording(survey.getLongWording()); + surveyDto.setSurveyObjectives(survey.getLongObjectives()); + surveyDto.setAccessUrl( + questioningService.getAccessUrl(questioning, surveyUnitId)); + surveyDto.setIdentificationCode(surveyUnitId); + surveyDto.setOpeningDate(new Timestamp(part.getOpeningDate().getTime())); + surveyDto.setClosingDate(new Timestamp(part.getClosingDate().getTime())); + surveyDto.setReturnDate(new Timestamp(part.getReturnDate().getTime())); + surveyDto.setMandatoryMySurveys(part.getCampaign().getSurvey().getSource().getMandatoryMySurveys()); + + Optional questioningEvent = questioningEventService.getLastQuestioningEvent( + questioning, TypeQuestioningEvent.MY_QUESTIONINGS_EVENTS); + if (questioningEvent.isPresent()) { + surveyDto.setQuestioningStatus(questioningEvent.get().getType().name()); + surveyDto.setQuestioningDate(new Timestamp(questioningEvent.get().getDate().getTime())); + } else { + log.debug("No questioningEvents found for questioning {} for identifier {}", + questioning.getId(), id); + } listSurveys.add(surveyDto); @@ -83,5 +75,4 @@ public List getListMySurveys(String id) { } - } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/SearchContactServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/SearchContactServiceImpl.java index de8f6218..02378afa 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/SearchContactServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/query/service/impl/SearchContactServiceImpl.java @@ -1,216 +1,66 @@ package fr.insee.survey.datacollectionmanagement.query.service.impl; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; -import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; +import fr.insee.survey.datacollectionmanagement.metadata.service.PartitioningService; import fr.insee.survey.datacollectionmanagement.query.dto.SearchContactDto; import fr.insee.survey.datacollectionmanagement.query.service.SearchContactService; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; -import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; -import fr.insee.survey.datacollectionmanagement.view.domain.View; -import fr.insee.survey.datacollectionmanagement.view.service.ViewService; -import lombok.EqualsAndHashCode; +import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningAccreditationService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; @Service -@EqualsAndHashCode +@RequiredArgsConstructor public class SearchContactServiceImpl implements SearchContactService { - @Autowired - private ContactService contactService; + private final ContactService contactService; - @Autowired - private SurveyUnitService surveyUnitService; + private final PartitioningService partioningService; - @Autowired - private CampaignService campaignService; + private final QuestioningAccreditationService questioningAccreditationService; - @Autowired - @EqualsAndHashCode.Exclude - private ViewService viewService;; @Override - public List searchContactCrossDomain( + public Page searchContactCrossDomain( String identifier, - String lastName, - String firstName, + String name, String email, - String idSu, - String identificationCode, - String identificationName, - String source, - String year, - String period, + String city, + String function, Pageable pageable) { - List listView = new ArrayList<>(); - boolean alwaysEmpty = true; + List listSearchContact = new ArrayList<>(); - if (!StringUtils.isEmpty(identifier)) { - View contactView = viewService.findFirstViewByIdentifier(identifier); - if (contactView != null) - listView.add(contactView); - alwaysEmpty = false; - } + Page pageContact = contactService.findByParameters(identifier, name, email,city, function, pageable); - if (!StringUtils.isEmpty(idSu)) { - if (listView.isEmpty() && alwaysEmpty) { - listView = viewService.findViewByIdSu(idSu); - alwaysEmpty = false; - } else if (!alwaysEmpty) { - listView = listView.stream().filter(v -> viewService.findViewByIdSu(idSu).contains(v)) - .collect(Collectors.toList()); - } + for (Contact c : pageContact) { + listSearchContact.add(transformContactTSearchContactDto(c)); } - if (!StringUtils.isEmpty(source) && !StringUtils.isEmpty(year) && !StringUtils.isEmpty(period)) { - if (listView.isEmpty() && alwaysEmpty) { - List listCampains = campaignService.findbySourceYearPeriod(source, Integer.parseInt(year), - period); - for (Campaign campain : listCampains) { - listView.addAll(viewService.findViewByCampaignId(campain.getId())); - } - - alwaysEmpty = false; - } else if (!alwaysEmpty) { - List listCampains = campaignService.findbySourceYearPeriod(source, Integer.parseInt(year), - period); - List listViewC = new ArrayList<>(); - for (Campaign c : listCampains) { - listViewC - .addAll(listView.stream() - .filter(v -> viewService.findViewByCampaignId(c.getId()).contains(v)) - .collect(Collectors.toList())); - } - listView = listViewC; - } - } - if ((!StringUtils.isEmpty(source) || !StringUtils.isEmpty(period)) && StringUtils.isEmpty(year)) { - if (listView.isEmpty() && alwaysEmpty) { - List listCampains = campaignService.findbySourcePeriod(source, period); - for (Campaign campain : listCampains) { - listView.addAll(viewService.findViewByCampaignId(campain.getId())); - } - - alwaysEmpty = false; - } else if (!alwaysEmpty) { - List listCampains = campaignService.findbySourcePeriod(source, period); - List listViewC = new ArrayList<>(); - for (Campaign c : listCampains) { - listViewC - .addAll(listView.stream() - .filter(v -> viewService.findViewByCampaignId(c.getId()).contains(v)) - .collect(Collectors.toList())); - } - listView = listViewC; - } - } - - if (!StringUtils.isEmpty(lastName)) { - if (listView.isEmpty() && alwaysEmpty) { - List listC = contactService.findByLastName(lastName); - for (Contact c : listC) { - listView.add(viewService.findFirstViewByIdentifier(c.getIdentifier())); - } - alwaysEmpty = false; - } else if (!alwaysEmpty) - - listView = listView.stream() - .filter(v -> lastName - .equalsIgnoreCase(contactService.findByIdentifier(v.getIdentifier()).get().getLastName())) - .collect(Collectors.toList()); - } - - if (!StringUtils.isEmpty(firstName)) { - if (listView.isEmpty() && alwaysEmpty) { - List listC = contactService.findByFirstName(firstName); - for (Contact c : listC) { - listView.add(viewService.findFirstViewByIdentifier(c.getIdentifier())); - } - alwaysEmpty = false; - } else if (!alwaysEmpty) - - listView = listView.stream() - .filter(v -> firstName - .equalsIgnoreCase(contactService.findByIdentifier(v.getIdentifier()).get().getFirstName())) - .collect(Collectors.toList()); - } - - if (!StringUtils.isEmpty(email)) { - if (listView.isEmpty() && alwaysEmpty) { - List listC = contactService.findByEmail(email); - for (Contact c : listC) { - listView.add(viewService.findFirstViewByIdentifier(c.getIdentifier())); - } - alwaysEmpty = false; - } else if (!alwaysEmpty) - - listView = listView.stream().filter( - v -> email.equalsIgnoreCase(contactService.findByIdentifier(v.getIdentifier()).get().getEmail())) - .collect(Collectors.toList()); - } - - if (!StringUtils.isEmpty(identificationCode)) { - if (listView.isEmpty() && alwaysEmpty) { - List listSurveyUnits = surveyUnitService.findbyIdentificationCode(identificationCode); - for (SurveyUnit s : listSurveyUnits) { - listView.addAll(viewService.findViewByIdSu(s.getIdSu())); - } - alwaysEmpty = false; - } else if (!alwaysEmpty) { - List listSurveyUnits = surveyUnitService.findbyIdentificationCode(identificationCode); - for (SurveyUnit s : listSurveyUnits) { - listView = listView.stream() - .filter(v -> identificationCode.equalsIgnoreCase(s.getIdentificationCode())) - .collect(Collectors.toList()); - } - - } - } - - if (!StringUtils.isEmpty(identificationName)) { - if (listView.isEmpty() && alwaysEmpty) { - List listSurveyUnits = surveyUnitService.findbyIdentificationName(identificationName); - for (SurveyUnit s : listSurveyUnits) { - listView.addAll(viewService.findViewByIdSu(s.getIdSu())); - } - alwaysEmpty = false; - } else if (!alwaysEmpty) { - List listSurveyUnits = surveyUnitService.findbyIdentificationCode(identificationCode); - for (SurveyUnit s : listSurveyUnits) { - listView = listView.stream() - .filter(v -> identificationName.equalsIgnoreCase(s.getIdentificationName())) - .collect(Collectors.toList()); - } - - } - } - return listView; + return new PageImpl<>(listSearchContact, pageable, pageContact.getTotalElements()); } - @Override - public List transformListViewDaoToDto(List listView) { - List listResult = new ArrayList<>(); - for (View v : listView) { - - SearchContactDto searchContact = new SearchContactDto(); - Contact c = contactService.findByIdentifier(v.getIdentifier()).get(); - searchContact.setIdentifier(c.getIdentifier()); - searchContact.setFirstName(c.getFirstName()); - searchContact.setLastName(c.getLastName()); - searchContact.setEmail(c.getEmail()); - - listResult.add(searchContact); - } - return listResult; + private SearchContactDto transformContactTSearchContactDto(Contact c) { + SearchContactDto searchContact = new SearchContactDto(); + searchContact.setIdentifier(c.getIdentifier()); + searchContact.setFirstName(c.getFirstName()); + searchContact.setLastName(c.getLastName()); + searchContact.setEmail(c.getEmail()); + searchContact.setPhone(c.getPhone()); + searchContact.setCity(c.getAddress() != null ? c.getAddress().getCityName() : ""); + searchContact.setFunction(c.getFunction()); + List listAccreditations = questioningAccreditationService.findByContactIdentifier(c.getIdentifier()); + searchContact.setListSurveyUnitNames(listAccreditations.stream().map(a -> a.getQuestioning().getSurveyUnit().getIdSu()).distinct().toList()); + searchContact.setListSourcesId(listAccreditations.stream(). + map(a -> + partioningService.findById(a.getQuestioning().getIdPartitioning()).getCampaign().getSurvey().getSource().getId()).distinct().toList()); + return searchContact; } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestioningEventController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestioningEventController.java index ac670055..9d30c2dc 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestioningEventController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestioningEventController.java @@ -1,37 +1,13 @@ package fr.insee.survey.datacollectionmanagement.questioning.controller; -import java.text.ParseException; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import fr.insee.survey.datacollectionmanagement.questioning.domain.Upload; -import fr.insee.survey.datacollectionmanagement.questioning.service.UploadService; -import org.modelmapper.ModelMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Upload; import fr.insee.survey.datacollectionmanagement.questioning.dto.QuestioningEventDto; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; +import fr.insee.survey.datacollectionmanagement.questioning.service.UploadService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; @@ -40,27 +16,39 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.text.ParseException; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "2 - Questioning", description = "Enpoints to create, update, delete and find entities around the questionings") +@Slf4j +@RequiredArgsConstructor public class QuestioningEventController { - static final Logger LOGGER = LoggerFactory.getLogger(QuestioningEventController.class); + private final QuestioningEventService questioningEventService; - @Autowired - private QuestioningEventService questioningEventService; + private final QuestioningService questioningService; - @Autowired - private QuestioningService questioningService; + private final UploadService uploadService; - @Autowired - UploadService uploadService; - - @Autowired - private ModelMapper modelMapper; + private final ModelMapper modelMapper; @Operation(summary = "Search for a questioning event by questioning id") @GetMapping(value = Constants.API_QUESTIONING_ID_QUESTIONING_EVENTS, produces = "application/json") @@ -70,18 +58,12 @@ public class QuestioningEventController { @ApiResponse(responseCode = "400", description = "Bad Request") }) public ResponseEntity findQuestioningEventsByQuestioning(@PathVariable("id") Long id) { - try { - Optional questioning = questioningService.findbyId(id); - if (questioning.isPresent()) { - Set setQe = questioning.get().getQuestioningEvents(); - return ResponseEntity.status(HttpStatus.OK) - .body(setQe.stream() - .map(q -> convertToDto(q)).collect(Collectors.toList())); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("questioning not found"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + Questioning questioning = questioningService.findbyId(id); + Set setQe = questioning.getQuestioningEvents(); + return ResponseEntity.status(HttpStatus.OK) + .body(setQe.stream() + .map(this::convertToDto).toList()); + } @Operation(summary = "Create a questioning event") @@ -91,24 +73,22 @@ public ResponseEntity findQuestioningEventsByQuestioning(@PathVariable("id") @ApiResponse(responseCode = "400", description = "Bad request") }) public ResponseEntity postQuestioningEvent(@Parameter(description = "questioning id") Long id, - @RequestBody QuestioningEventDto questioningEventDto) { + @RequestBody QuestioningEventDto questioningEventDto) { + Questioning questioning = questioningService.findbyId(id); + try { - Optional optQuestioning = questioningService.findbyId(id); - if (optQuestioning.isPresent()) { - Questioning questioning = optQuestioning.get(); - QuestioningEvent questioningEvent = convertToEntity(questioningEventDto); - QuestioningEvent newQuestioningEvent = questioningEventService.saveQuestioningEvent(questioningEvent); - Set setQuestioningEvents = questioning.getQuestioningEvents(); - setQuestioningEvents.add(newQuestioningEvent); - questioning.setQuestioningEvents(setQuestioningEvents); - questioningService.saveQuestioning(questioning); - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.set(HttpHeaders.LOCATION, - ServletUriComponentsBuilder.fromCurrentRequest().toUriString()); - return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders) - .body(convertToDto(newQuestioningEvent)); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Questioning does not exist"); + QuestioningEvent questioningEvent = convertToEntity(questioningEventDto); + QuestioningEvent newQuestioningEvent = questioningEventService.saveQuestioningEvent(questioningEvent); + Set setQuestioningEvents = questioning.getQuestioningEvents(); + setQuestioningEvents.add(newQuestioningEvent); + questioning.setQuestioningEvents(setQuestioningEvents); + questioningService.saveQuestioning(questioning); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set(HttpHeaders.LOCATION, + ServletUriComponentsBuilder.fromCurrentRequest().toUriString()); + return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders) + .body(convertToDto(newQuestioningEvent)); + } catch (ParseException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); } @@ -123,21 +103,20 @@ public ResponseEntity postQuestioningEvent(@Parameter(description = "question @ApiResponse(responseCode = "400", description = "Bad Request") }) public ResponseEntity deleteQuestioningEvent(@PathVariable("id") Long id) { + QuestioningEvent questioningEvent = questioningEventService.findbyId(id); + try { - Optional questioningEvent = questioningEventService.findbyId(id); - if (questioningEvent.isPresent()) { - Upload upload = (questioningEvent.get().getUpload() != null ? questioningEvent.get().getUpload() : null); - Questioning quesitoning = questioningEvent.get().getQuestioning(); - quesitoning.setQuestioningEvents(quesitoning.getQuestioningEvents().stream() - .filter(qe -> !qe.equals(questioningEvent.get())).collect(Collectors.toSet())); - questioningService.saveQuestioning(quesitoning); - questioningEventService.deleteQuestioningEvent(id); - if(upload!=null && questioningEventService.findbyIdUpload(upload.getId()).size()==0 ){ - uploadService.delete(upload); - } - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Questioning event deleted"); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Questioning event does not exist"); + Upload upload = (questioningEvent.getUpload() != null ? questioningEvent.getUpload() : null); + Questioning quesitoning = questioningEvent.getQuestioning(); + quesitoning.setQuestioningEvents(quesitoning.getQuestioningEvents().stream() + .filter(qe -> !qe.equals(questioningEvent)).collect(Collectors.toSet())); + questioningService.saveQuestioning(quesitoning); + questioningEventService.deleteQuestioningEvent(id); + if (upload != null && questioningEventService.findbyIdUpload(upload.getId()).size() == 0) { + uploadService.delete(upload); + } + return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Questioning event deleted"); + } catch (Exception e) { return new ResponseEntity("Error", HttpStatus.BAD_REQUEST); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/SurveyUnitController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/SurveyUnitController.java index c3b4666c..01504ff5 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/SurveyUnitController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/SurveyUnitController.java @@ -1,35 +1,8 @@ package fr.insee.survey.datacollectionmanagement.questioning.controller; -import java.text.ParseException; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.modelmapper.ModelMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; import fr.insee.survey.datacollectionmanagement.questioning.dto.SurveyUnitDto; import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; @@ -39,7 +12,21 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.modelmapper.ModelMapper; +import org.springframework.data.domain.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.util.List; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -47,20 +34,17 @@ + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "2 - Questioning", description = "Enpoints to create, update, delete and find entities around the questionings") @Slf4j +@RequiredArgsConstructor +@Validated public class SurveyUnitController { - static final Logger LOGGER = LoggerFactory.getLogger(SurveyUnitController.class); - - @Autowired - private SurveyUnitService surveyUnitService; - - @Autowired - private ModelMapper modelMapper; + private final SurveyUnitService surveyUnitService; + private final ModelMapper modelMapper; @Operation(summary = "Search for a survey units, paginated") @GetMapping(value = Constants.API_SURVEY_UNITS, produces = "application/json") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SurveyUnitDto.class))), + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SurveyUnitPage.class))), @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Bad Request") }) @@ -70,7 +54,27 @@ public Page getSurveyUnits( @RequestParam(defaultValue = "idSu") String sort) { Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); Page pageC = surveyUnitService.findAll(pageable); - List listSuDto = pageC.stream().map(c -> convertToDto(c)).collect(Collectors.toList()); + List listSuDto = pageC.stream().map(this::convertToDto).toList(); + return new SurveyUnitPage(listSuDto, pageable, pageC.getTotalElements()); + } + + @Operation(summary = "Multi-criteria search survey-unit") + @GetMapping(value = Constants.API_SURVEY_UNITS_SEARCH, produces = "application/json") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SurveyUnitPage.class))), + @ApiResponse(responseCode = "404", description = "Not found"), + @ApiResponse(responseCode = "400", description = "Bad Request") + }) + public Page searchSurveyUnits( + @RequestParam(required = false) String idSu, + @RequestParam(required = false) String identificationCode, + @RequestParam(required = false) String identificationName, + @RequestParam(defaultValue = "0") Integer page, + @RequestParam(defaultValue = "20") Integer size, + @RequestParam(defaultValue = "id_su") String sort) { + Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); + Page pageC = surveyUnitService.findByParameters(idSu, identificationCode, identificationName, pageable); + List listSuDto = pageC.stream().map(this::convertToDto).toList(); return new SurveyUnitPage(listSuDto, pageable, pageC.getTotalElements()); } @@ -81,17 +85,9 @@ public Page getSurveyUnits( @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Bad Request") }) - public ResponseEntity findSurveyUnit(@PathVariable("id") String id) { - - try { - Optional surveyUnit = surveyUnitService.findbyId(StringUtils.upperCase(id)); - if (surveyUnit.isPresent()) - return ResponseEntity.status(HttpStatus.OK).body(convertToDto(surveyUnit.get())); - else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("survey unit not found"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity findSurveyUnit(@PathVariable("id") String id) { + SurveyUnit surveyUnit = surveyUnitService.findbyId(StringUtils.upperCase(id)); + return ResponseEntity.status(HttpStatus.OK).body(convertToDto(surveyUnit)); } @@ -102,10 +98,9 @@ public ResponseEntity findSurveyUnit(@PathVariable("id") String id) { @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = SurveyUnitDto.class))), @ApiResponse(responseCode = "400", description = "Bad request") }) - public ResponseEntity putSurveyUnit(@PathVariable("id") String id, @RequestBody SurveyUnitDto surveyUnitDto) { - if (StringUtils.isBlank(surveyUnitDto.getIdSu()) || !surveyUnitDto.getIdSu().equalsIgnoreCase(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and idSu don't match"); - + public ResponseEntity putSurveyUnit(@PathVariable("id") String id, @RequestBody @Valid SurveyUnitDto surveyUnitDto) { + if (!surveyUnitDto.getIdSu().equalsIgnoreCase(id)) { + throw new NotMatchException("id and idSu don't match"); } SurveyUnit surveyUnit; @@ -114,18 +109,17 @@ public ResponseEntity putSurveyUnit(@PathVariable("id") String id, @RequestBo responseHeaders.set(HttpHeaders.LOCATION, ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(surveyUnitDto.getIdSu()).toUriString()); - try { - surveyUnit = convertToEntity(surveyUnitDto); - } catch (ParseException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Impossible to parse survey unit"); - } + surveyUnit = convertToEntity(surveyUnitDto); - if (surveyUnitService.findbyId(surveyUnitDto.getIdSu()).isPresent()) + try { + surveyUnitService.findbyId(surveyUnitDto.getIdSu()); responseStatus = HttpStatus.OK; - else { - LOGGER.info("Creating survey with the id {}", surveyUnitDto.getIdSu()); + + } catch (NotFoundException e) { + log.info("Creating survey with the id {}", surveyUnitDto.getIdSu()); responseStatus = HttpStatus.CREATED; } + return ResponseEntity.status(responseStatus) .body(convertToDto(surveyUnitService.saveSurveyUnitAndAddress(surveyUnit))); @@ -138,19 +132,18 @@ public ResponseEntity putSurveyUnit(@PathVariable("id") String id, @RequestBo @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Bad request") }) - public ResponseEntity deleteSurveyUnit(@PathVariable("id") String id) { + public ResponseEntity deleteSurveyUnit(@PathVariable("id") String id) { + SurveyUnit surveyUnit = surveyUnitService.findbyId(StringUtils.upperCase(id)); + try { - Optional surveyUnit = surveyUnitService.findbyId(StringUtils.upperCase(id)); - if (surveyUnit.isPresent()) { - if (!surveyUnit.get().getQuestionings().isEmpty()) { - log.warn("Some questionings exist for the survey unit {}, the survey unit can't be deleted", id); - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body("Some questionings exist for this survey unit, the survey unit can't be deleted"); - } - surveyUnitService.deleteSurveyUnit(id); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Survey unit deleted"); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("survey unit not found"); + if (!surveyUnit.getQuestionings().isEmpty()) { + log.warn("Some questionings exist for the survey unit {}, the survey unit can't be deleted", id); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body("Some questionings exist for this survey unit, the survey unit can't be deleted"); + } + surveyUnitService.deleteSurveyUnit(id); + return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Survey unit deleted"); + } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); } @@ -160,7 +153,7 @@ private SurveyUnitDto convertToDto(SurveyUnit surveyUnit) { return modelMapper.map(surveyUnit, SurveyUnitDto.class); } - private SurveyUnit convertToEntity(SurveyUnitDto surveyUnitDto) throws ParseException { + private SurveyUnit convertToEntity(SurveyUnitDto surveyUnitDto) { return modelMapper.map(surveyUnitDto, SurveyUnit.class); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/UploadController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/UploadController.java index 1b576908..ef41592c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/UploadController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/controller/UploadController.java @@ -4,22 +4,20 @@ import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.exception.RessourceNotValidatedException; import fr.insee.survey.datacollectionmanagement.query.domain.ResultUpload; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.Upload; import fr.insee.survey.datacollectionmanagement.questioning.dto.UploadDto; -import fr.insee.survey.datacollectionmanagement.questioning.service.UploadService; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; +import fr.insee.survey.datacollectionmanagement.questioning.service.UploadService; import io.swagger.v3.oas.annotations.tags.Tag; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import java.util.Optional; import java.util.stream.Collectors; @RestController @@ -27,27 +25,21 @@ + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "5 - Moog", description = "Enpoints for moog") +@Slf4j +@RequiredArgsConstructor public class UploadController { - static final Logger LOGGER = LoggerFactory.getLogger(UploadController.class); - @Autowired - UploadService moogUploadService; + private final UploadService moogUploadService; - @Autowired - QuestioningEventService questioningEventService; + private final QuestioningEventService questioningEventService; - @Autowired - QuestioningService questioningService; + private final QuestioningService questioningService; @DeleteMapping(value = Constants.MOOG_API_UPLOADS_ID) public ResponseEntity deleteOneUpload(@PathVariable Long id) { - LOGGER.info("Request DELETE for upload n° {}", id); + log.info("Request DELETE for upload n° {}", id); - Optional upOpt = moogUploadService.findById(id); - if(!upOpt.isPresent()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Upload does not exist"); - } - Upload up = upOpt.get(); + Upload up = moogUploadService.findById(id); up.getQuestioningEvents().stream().forEach(q -> { Questioning quesitoning = q.getQuestioning(); quesitoning.setQuestioningEvents(quesitoning.getQuestioningEvents().stream() @@ -64,14 +56,14 @@ public ResponseEntity deleteOneUpload(@PathVariable Long id) { @GetMapping(value = Constants.MOOG_API_CAMPAIGN_UPLOADS, produces = "application/json") public JSONCollectionWrapper displayAllUploads(@PathVariable String idCampaign) { - LOGGER.info("Request GET for uploads"); + log.info("Request GET for uploads"); return new JSONCollectionWrapper(moogUploadService.findAllByIdCampaign(idCampaign)); } @PostMapping(value = Constants.MOOG_API_CAMPAIGN_UPLOADS, produces = "application/json") public ResultUpload addQuestioningEventViaUpload(@PathVariable String idCampaign, @RequestBody UploadDto request) throws RessourceNotValidatedException { - LOGGER.info("Request POST to add an upload"); + log.info("Request POST to add an upload"); ResultUpload retourInfo = moogUploadService.save(idCampaign, request); return retourInfo; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/EventOrder.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/EventOrder.java index aee1dff6..13fd490c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/EventOrder.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/EventOrder.java @@ -1,12 +1,14 @@ package fr.insee.survey.datacollectionmanagement.questioning.domain; -import javax.persistence.Entity; -import javax.persistence.Id; -import lombok.Data; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.Setter; @Entity -@Data +@Getter +@Setter public class EventOrder { @Id diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Operator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Operator.java index 19177c57..23ee1cb2 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Operator.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Operator.java @@ -1,17 +1,20 @@ package fr.insee.survey.datacollectionmanagement.questioning.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import lombok.Data; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.Setter; @Entity -@Data +@Getter +@Setter public class Operator { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "operator_seq") private Long id; private String firstName; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/OperatorService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/OperatorService.java index 03f145a0..79f49095 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/OperatorService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/OperatorService.java @@ -1,22 +1,17 @@ package fr.insee.survey.datacollectionmanagement.questioning.domain; -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import jakarta.persistence.*; +import lombok.*; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; +import java.util.Set; @Entity -@Data +@Getter +@Setter public class OperatorService { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "operator_service_seq") private Long id; private String name; private String mail; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Questioning.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Questioning.java index d2d91a67..28d37a24 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Questioning.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Questioning.java @@ -1,33 +1,22 @@ package fr.insee.survey.datacollectionmanagement.questioning.domain; -import java.util.Set; +import jakarta.persistence.*; +import lombok.*; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.ToString; +import java.util.Set; @Entity -@Data -@NoArgsConstructor +@Getter +@Setter@NoArgsConstructor @Table(indexes = { - @Index(name = "idPartitioning_index", columnList = "idPartitioning") + @Index(name = "idPartitioning_index", columnList = "idPartitioning"), + @Index(name = "surveyUnitId_index", columnList = "survey_unit_id_su") + }) public class Questioning { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "questioning_seq") private Long id; @NonNull @@ -36,18 +25,12 @@ public class Questioning { private String idPartitioning; @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set questioningAccreditations; @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set questioningEvents; - @OneToOne(fetch = FetchType.EAGER) - @EqualsAndHashCode.Exclude - @ToString.Exclude + @ManyToOne(fetch = FetchType.EAGER) @NonNull private SurveyUnit surveyUnit; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/QuestioningAccreditation.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/QuestioningAccreditation.java index 58508454..b7add662 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/QuestioningAccreditation.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/QuestioningAccreditation.java @@ -1,21 +1,13 @@ package fr.insee.survey.datacollectionmanagement.questioning.domain; -import java.util.Date; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.*; +import lombok.*; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; +import java.util.Date; @Entity -@Data +@Getter +@Setter @NoArgsConstructor @Table(indexes = { @Index(name = "idContact_index", columnList = "idContact"), @@ -24,7 +16,7 @@ public class QuestioningAccreditation { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "questioning_accreditation_seq") private Long id; private boolean isMain; @@ -33,8 +25,7 @@ public class QuestioningAccreditation { @NonNull private String idContact; - @OneToOne - @EqualsAndHashCode.Exclude + @ManyToOne private Questioning questioning; @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/QuestioningEvent.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/QuestioningEvent.java index 6ac4c3c4..aac2ce8f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/QuestioningEvent.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/QuestioningEvent.java @@ -1,33 +1,33 @@ package fr.insee.survey.datacollectionmanagement.questioning.domain; -import java.util.Date; - -import javax.persistence.*; - import com.fasterxml.jackson.annotation.JsonManagedReference; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; - import com.fasterxml.jackson.databind.JsonNode; -import com.vladmihalcea.hibernate.type.json.JsonBinaryType; - import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; -import lombok.Data; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +import java.util.Date; @Entity -@Data -@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) +@Getter +@Setter +@Table(indexes = { + @Index(name = "idQuestioning_index", columnList = "questioning_id") +}) public class QuestioningEvent { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "questioning_event_seq") private Long id; private Date date; @Enumerated(EnumType.STRING) private TypeQuestioningEvent type; - @OneToOne + @ManyToOne private Questioning questioning; @ManyToOne(fetch = FetchType.EAGER) @@ -35,7 +35,7 @@ public class QuestioningEvent { @JsonManagedReference private Upload upload; - @Type(type = "jsonb") + @JdbcTypeCode(SqlTypes.JSON) @Column(columnDefinition = "jsonb") private JsonNode payload; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/SurveyUnit.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/SurveyUnit.java index b01033a8..a9059796 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/SurveyUnit.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/SurveyUnit.java @@ -1,22 +1,18 @@ package fr.insee.survey.datacollectionmanagement.questioning.domain; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; -import lombok.Data; +import java.util.Set; @Entity -@Data +@Getter +@Setter @Table(indexes = { - @Index(name = "identificationName_index", columnList = "identificationName"), @Index(name = "identificationCode_index", columnList = "identificationCode") + @Index(name = "identificationName_index", columnList = "identificationName"), + @Index(name = "identificationCode_index", columnList = "identificationCode"), + @Index(name = "surveyUnitAddress_index", columnList = "survey_unit_address_id") }) public class SurveyUnit { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/SurveyUnitAddress.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/SurveyUnitAddress.java index 44c819c3..6876dc2d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/SurveyUnitAddress.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/SurveyUnitAddress.java @@ -1,19 +1,21 @@ package fr.insee.survey.datacollectionmanagement.questioning.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; - +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import lombok.Getter; import lombok.Setter; + + @Entity @Getter @Setter public class SurveyUnitAddress { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "survey_unit_address_seq") private Long id; private String streetNumber; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Upload.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Upload.java index f4eb58ad..061ce594 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Upload.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/domain/Upload.java @@ -2,11 +2,10 @@ import com.fasterxml.jackson.annotation.JsonBackReference; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; -import javax.persistence.*; import java.util.List; @Entity diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/dto/QuestioningAccreditationDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/dto/QuestioningAccreditationDto.java index 8c5b4d4f..51c7469f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/dto/QuestioningAccreditationDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/dto/QuestioningAccreditationDto.java @@ -1,19 +1,15 @@ package fr.insee.survey.datacollectionmanagement.questioning.dto; -import java.util.Date; - -import javax.persistence.Id; - import com.fasterxml.jackson.annotation.JsonIgnore; - import lombok.Getter; import lombok.Setter; +import java.util.Date; + @Getter @Setter public class QuestioningAccreditationDto { - @Id @JsonIgnore private Long id; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/dto/SurveyUnitDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/dto/SurveyUnitDto.java index 7f1c0f93..805b2cc1 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/dto/SurveyUnitDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/dto/SurveyUnitDto.java @@ -1,12 +1,14 @@ package fr.insee.survey.datacollectionmanagement.questioning.dto; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @Getter @Setter public class SurveyUnitDto { - + + @NotBlank private String idSu; private String identificationCode; private String identificationName; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/repository/SurveyUnitRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/repository/SurveyUnitRepository.java index 7491487e..427c15a3 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/repository/SurveyUnitRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/repository/SurveyUnitRepository.java @@ -1,18 +1,30 @@ package fr.insee.survey.datacollectionmanagement.questioning.repository; -import java.util.List; - +import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; +import java.util.List; public interface SurveyUnitRepository extends JpaRepository { - public List findAllByIdentificationCode(String identificationCode); + List findAllByIdentificationCode(String identificationCode); + + List findByIdentificationNameIgnoreCase(String identificationName); + + @Query(nativeQuery = true, value = """ + SELECT * + FROM survey_unit su + WHERE (:id_su is null or upper(su.id_su) like upper(concat('%', :id_su, '%'))) + AND (:identification_name is null or upper(su.identification_name) like upper(concat('%', :identification_name, '%'))) + AND (:identification_code is null or upper(su.identification_code) like upper(concat('%', :identification_code, '%'))) + """) + Page findByParameters(@Param("id_su") String idSu, @Param("identification_code") String identificationCode, @Param("identification_name") String identificationName, Pageable pageable); - public List findByIdentificationNameIgnoreCase(String identificationName); @Query(nativeQuery = true, value = "SELECT * FROM survey_unit ORDER BY random() LIMIT 1") - public SurveyUnit findRandomSurveyUnit(); + SurveyUnit findRandomSurveyUnit(); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningAccreditationService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningAccreditationService.java index 44f41819..ed780ea8 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningAccreditationService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningAccreditationService.java @@ -1,39 +1,22 @@ package fr.insee.survey.datacollectionmanagement.questioning.service; -import java.util.List; -import java.util.Optional; -import java.util.Set; - +import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; +import java.util.List; public interface QuestioningAccreditationService { - public List findByContactIdentifier(String id); - - public Set findBySurveyUnit(SurveyUnit su); - - public List findIdContactsByPartitionigAccredications(String idPartitioning); - - public List findIdPartitioningsByContactAccreditations(String idContact); - - public List findIdContactsByIdSource(String idSource); - - public List findIdContactsByYear(Integer year); - - public List findIdContactsByPeriod(String period); + List findByContactIdentifier(String id); - public List findIdContactsBySourceYearPeriod(String idSource, Integer year, String period); - public Page findAll(Pageable pageable); + Page findAll(Pageable pageable); - public Optional findById(Long id); + QuestioningAccreditation findById(Long id); - public QuestioningAccreditation saveQuestioningAccreditation(QuestioningAccreditation questioningAccreditation); + QuestioningAccreditation saveQuestioningAccreditation(QuestioningAccreditation questioningAccreditation); - public void deleteAccreditation(QuestioningAccreditation c); + void deleteAccreditation(QuestioningAccreditation c); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningEventService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningEventService.java index 0fd890e3..654da18d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningEventService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningEventService.java @@ -1,18 +1,17 @@ package fr.insee.survey.datacollectionmanagement.questioning.service; -import java.util.List; -import java.util.Optional; - -import org.springframework.stereotype.Service; - import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; @Service public interface QuestioningEventService { - public Optional findbyId(Long id); + public QuestioningEvent findbyId(Long id); public QuestioningEvent saveQuestioningEvent(QuestioningEvent questioningEvent); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningService.java index 743679c4..cd35e88d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/QuestioningService.java @@ -1,19 +1,17 @@ package fr.insee.survey.datacollectionmanagement.questioning.service; -import java.util.Optional; -import java.util.Set; - +import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; +import java.util.Set; public interface QuestioningService { public Page findAll(Pageable pageable); - public Optional findbyId(Long id); + public Questioning findbyId(Long id); public Questioning saveQuestioning(Questioning questioning); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/SurveyUnitService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/SurveyUnitService.java index 6c1ae94a..8af5edca 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/SurveyUnitService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/SurveyUnitService.java @@ -1,16 +1,14 @@ package fr.insee.survey.datacollectionmanagement.questioning.service; -import java.util.List; -import java.util.Optional; - +import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; +import java.util.List; public interface SurveyUnitService { - public Optional findbyId(String idSu); + public SurveyUnit findbyId(String idSu); public List findbyIdentificationCode(String identificationCode); @@ -18,6 +16,8 @@ public interface SurveyUnitService { public Page findAll(Pageable pageable); + public Page findByParameters(String idSu, String identificationCode, String identificationName, Pageable pageable); + public SurveyUnit saveSurveyUnit(SurveyUnit surveyUnit); public SurveyUnit saveSurveyUnitAndAddress(SurveyUnit surveyUnit); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/UploadService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/UploadService.java index 2677b925..4709defc 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/UploadService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/UploadService.java @@ -8,14 +8,13 @@ import java.util.Date; import java.util.List; -import java.util.Optional; @Service public interface UploadService { public ResultUpload save(String idCampaign, UploadDto uploadDto) throws RessourceNotValidatedException; - public Optional findById(long id); + public Upload findById(long id); public List findAllByIdCampaign(String idCampaign); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/EventOrderServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/EventOrderServiceImpl.java index d60d5d11..34a3ba1c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/EventOrderServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/EventOrderServiceImpl.java @@ -1,21 +1,18 @@ package fr.insee.survey.datacollectionmanagement.questioning.service.impl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import fr.insee.survey.datacollectionmanagement.questioning.domain.EventOrder; import fr.insee.survey.datacollectionmanagement.questioning.repository.EventOrderRepository; import fr.insee.survey.datacollectionmanagement.questioning.service.EventOrderService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; @Service +@Slf4j +@RequiredArgsConstructor public class EventOrderServiceImpl implements EventOrderService { - static final Logger LOGGER = LoggerFactory.getLogger(EventOrderServiceImpl.class); - - @Autowired - EventOrderRepository eventOrderRepository; + private final EventOrderRepository eventOrderRepository; public EventOrder saveAndFlush(EventOrder order) { return eventOrderRepository.saveAndFlush(order); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningAccreditationServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningAccreditationServiceImpl.java index 8dde7efe..dbc2cf30 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningAccreditationServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningAccreditationServiceImpl.java @@ -1,26 +1,25 @@ package fr.insee.survey.datacollectionmanagement.questioning.service.impl; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningAccreditationRepository; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningAccreditationService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; @Service +@RequiredArgsConstructor public class QuestioningAccreditationServiceImpl implements QuestioningAccreditationService { - @Autowired - private QuestioningAccreditationRepository questioningAccreditationRepository; + private final QuestioningAccreditationRepository questioningAccreditationRepository; public List findByContactIdentifier(String id) { return questioningAccreditationRepository.findByIdContact(id); @@ -34,44 +33,14 @@ public Set findBySurveyUnit(SurveyUnit su) { return setReturn; } - @Override - public List findIdContactsByPartitionigAccredications(String idPartitioning) { - return questioningAccreditationRepository.findIdContactsByPartitionigAccredications(idPartitioning); - } - - @Override - public List findIdPartitioningsByContactAccreditations(String idContact) { - return questioningAccreditationRepository.findIdPartitioningsByContactAccreditations(idContact); - } - - @Override - public List findIdContactsByIdSource(String idSource) { - return questioningAccreditationRepository.findIdContactsByIdSource(idSource); - } - - @Override - public List findIdContactsByYear(Integer year) { - return questioningAccreditationRepository.findIdContactsByYear(year); - } - - @Override - public List findIdContactsByPeriod(String period) { - return questioningAccreditationRepository.findIdContactsByPeriod(period); - } - - @Override - public List findIdContactsBySourceYearPeriod(String source, Integer year, String period) { - return questioningAccreditationRepository.findIdContactsBySourceYearPeriod(source, year, period); - } - @Override public Page findAll(Pageable pageable) { return questioningAccreditationRepository.findAll(pageable); } @Override - public Optional findById(Long id) { - return questioningAccreditationRepository.findById(id); + public QuestioningAccreditation findById(Long id) { + return questioningAccreditationRepository.findById(id).orElseThrow(()-> new NotFoundException(String.format("QuestioningAccreditation %s not found", id))); } @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningEventServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningEventServiceImpl.java index f61b9733..42b5743f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningEventServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningEventServiceImpl.java @@ -1,32 +1,29 @@ package fr.insee.survey.datacollectionmanagement.questioning.service.impl; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningEventRepository; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; import fr.insee.survey.datacollectionmanagement.questioning.util.LastQuestioningEventComparator; import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; @Service +@RequiredArgsConstructor public class QuestioningEventServiceImpl implements QuestioningEventService { - @Autowired - LastQuestioningEventComparator lastQuestioningEventComparator; + private final LastQuestioningEventComparator lastQuestioningEventComparator; - @Autowired - QuestioningEventRepository questioningEventRepository; + private final QuestioningEventRepository questioningEventRepository; @Override - public Optional findbyId(Long id) { - return questioningEventRepository.findById(id); + public QuestioningEvent findbyId(Long id) { + return questioningEventRepository.findById(id).orElseThrow(() -> new NotFoundException(String.format("QuestioningEvent %s not found", id))); } @Override @@ -42,20 +39,16 @@ public void deleteQuestioningEvent(Long id) { @Override public Optional getLastQuestioningEvent(Questioning questioning, - List events) { + List events) { List listQuestioningEvent = questioning.getQuestioningEvents().stream() - .filter(qe -> events.contains(qe.getType())) - .collect(Collectors.toList()); - Collections.sort(listQuestioningEvent, lastQuestioningEventComparator); + .filter(qe -> events.contains(qe.getType())).sorted(lastQuestioningEventComparator).toList(); return listQuestioningEvent.stream().findFirst(); } @Override - public List findbyIdUpload(Long id){ - List listQuestioningEvent = questioningEventRepository.findAll().stream().filter(qe -> qe.getUpload()!= null && qe.getUpload().getId().equals(id)).collect(Collectors.toList()); - - return listQuestioningEvent; + public List findbyIdUpload(Long id) { + return questioningEventRepository.findAll().stream().filter(qe -> qe.getUpload() != null && qe.getUpload().getId().equals(id)).toList(); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImpl.java index 70a34d43..bce0bfd7 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/QuestioningServiceImpl.java @@ -1,14 +1,7 @@ package fr.insee.survey.datacollectionmanagement.questioning.service.impl; -import java.util.Optional; -import java.util.Set; - import fr.insee.survey.datacollectionmanagement.config.ApplicationConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; @@ -17,24 +10,26 @@ import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningEventService; import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.Set; @Service +@RequiredArgsConstructor public class QuestioningServiceImpl implements QuestioningService { - @Autowired - private QuestioningRepository questioningRepository; + private final QuestioningRepository questioningRepository; - @Autowired - private SurveyUnitService surveyUnitService; + private final SurveyUnitService surveyUnitService; - @Autowired - private QuestioningEventService questioningEventService; + private final QuestioningEventService questioningEventService; - @Autowired - private QuestioningAccreditationService questioningAccreditationService; + private final QuestioningAccreditationService questioningAccreditationService; - @Autowired - ApplicationConfig applicationConfig; + private final ApplicationConfig applicationConfig; @Override public Page findAll(Pageable pageable) { @@ -42,8 +37,8 @@ public Page findAll(Pageable pageable) { } @Override - public Optional findbyId(Long id) { - return questioningRepository.findById(id); + public Questioning findbyId(Long id) { + return questioningRepository.findById(id).orElseThrow(() -> new NotFoundException(String.format("Questioning %s not found", id))); } @Override @@ -85,14 +80,14 @@ public Set findBySurveyUnitIdSu(String idSu) { @Override public String getAccessUrl(Questioning questioning, String surveyUnitId) { - return applicationConfig.getQuestioningUrl() + "/questionnaire/" + questioning.getModelName() - + "/unite-enquetee/" + surveyUnitId; - } + return applicationConfig.getQuestioningUrl() + "/questionnaire/" + questioning.getModelName() + + "/unite-enquetee/" + surveyUnitId; + } @Override public Questioning findByIdPartitioningAndSurveyUnitIdSu(String idPartitioning, - String surveyUnitIdSu) { + String surveyUnitIdSu) { return questioningRepository.findByIdPartitioningAndSurveyUnitIdSu(idPartitioning, surveyUnitIdSu); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/SurveyUnitServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/SurveyUnitServiceImpl.java index fabd6ed9..37dbd70a 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/SurveyUnitServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/SurveyUnitServiceImpl.java @@ -1,32 +1,30 @@ package fr.insee.survey.datacollectionmanagement.questioning.service.impl; -import java.util.List; -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitAddressRepository; import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitRepository; import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; @Service @Slf4j +@RequiredArgsConstructor public class SurveyUnitServiceImpl implements SurveyUnitService { - @Autowired - private SurveyUnitRepository surveyUnitRepository; + private final SurveyUnitRepository surveyUnitRepository; - @Autowired - private SurveyUnitAddressRepository surveyUnitAddressRepository; + private final SurveyUnitAddressRepository surveyUnitAddressRepository; @Override - public Optional findbyId(String idSu) { - return surveyUnitRepository.findById(idSu); + public SurveyUnit findbyId(String idSu) { + return surveyUnitRepository.findById(idSu).orElseThrow(() -> new NotFoundException(String.format("SurveyUnit %s not found", idSu))); } @Override @@ -44,6 +42,11 @@ public Page findAll(Pageable pageable) { return surveyUnitRepository.findAll(pageable); } + @Override + public Page findByParameters(String idSu, String identificationCode, String identificationName, Pageable pageable) { + return surveyUnitRepository.findByParameters(idSu, identificationCode, identificationName, pageable); + } + @Override public SurveyUnit saveSurveyUnit(SurveyUnit surveyUnit) { return surveyUnitRepository.save(surveyUnit); @@ -53,18 +56,19 @@ public SurveyUnit saveSurveyUnit(SurveyUnit surveyUnit) { public SurveyUnit saveSurveyUnitAndAddress(SurveyUnit surveyUnit) { if (surveyUnit.getSurveyUnitAddress() != null) { - - Optional existingSurveyUnit = findbyId(surveyUnit.getIdSu()); - if (existingSurveyUnit.isPresent()) { - if (existingSurveyUnit.get().getSurveyUnitAddress() != null) { - surveyUnit.getSurveyUnitAddress().setId(existingSurveyUnit.get().getSurveyUnitAddress().getId()); + try { + SurveyUnit existingSurveyUnit = findbyId(surveyUnit.getIdSu()); + if (existingSurveyUnit.getSurveyUnitAddress() != null) { + surveyUnit.getSurveyUnitAddress().setId(existingSurveyUnit.getSurveyUnitAddress().getId()); } - } else - log.info("Survey unit does not exist"); - + } catch (NotFoundException e) { + log.debug("Survey unit does not exist"); + } surveyUnitAddressRepository.save(surveyUnit.getSurveyUnitAddress()); + } return surveyUnitRepository.save(surveyUnit); + } @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/UploadServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/UploadServiceImpl.java index 4b33251a..a2f9b937 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/UploadServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/service/impl/UploadServiceImpl.java @@ -1,6 +1,7 @@ package fr.insee.survey.datacollectionmanagement.questioning.service.impl; import com.fasterxml.jackson.databind.ObjectMapper; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.exception.RessourceNotValidatedException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; @@ -17,29 +18,26 @@ import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import fr.insee.survey.datacollectionmanagement.questioning.service.UploadService; import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.minidev.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; -import java.util.stream.Collectors; @Service @Slf4j +@RequiredArgsConstructor public class UploadServiceImpl implements UploadService { - @Autowired - UploadRepository uploadRepository; + private final UploadRepository uploadRepository; - @Autowired - QuestioningEventService questioningEventService; + private final QuestioningEventService questioningEventService; - @Autowired - CampaignService campaignService; + private final CampaignService campaignService; + + private final QuestioningService questioningService; - @Autowired - QuestioningService questioningService; @Override public ResultUpload save(String idCampaign, UploadDto uploadDto) throws RessourceNotValidatedException { @@ -62,20 +60,17 @@ public ResultUpload save(String idCampaign, UploadDto uploadDto) throws Ressourc try { QuestioningEvent qe = new QuestioningEvent(); - Optional campaign = campaignService.findById(idCampaign); - if (!campaign.isPresent()) { - throw new RessourceNotValidatedException("Campaign", idCampaign); - } - Set setParts = campaign.get().getPartitionings(); + Campaign campaign = campaignService.findById(idCampaign); + Set setParts = campaign.getPartitionings(); if (setParts.isEmpty()) { throw new RessourceNotValidatedException("No partitionings found for campaign ", idCampaign); } - + Set questionings = questioningService.findBySurveyUnitIdSu(mmDto.getIdSu()); - List listIdParts = campaignService.findById(idCampaign).get().getPartitionings().stream().map(Partitioning::getId).toList(); + List listIdParts = campaignService.findById(idCampaign).getPartitionings().stream().map(Partitioning::getId).toList(); Optional quest = questionings.stream().filter(q -> listIdParts.contains(q.getIdPartitioning()) && q.getQuestioningAccreditations().stream().map(QuestioningAccreditation::getIdContact) - .collect(Collectors.toList()).contains(mmDto.getIdContact())).findFirst(); + .toList().contains(mmDto.getIdContact())).findFirst(); qe.setUpload(up); qe.setType(TypeQuestioningEvent.valueOf(mmDto.getStatus())); @@ -86,7 +81,7 @@ public ResultUpload save(String idCampaign, UploadDto uploadDto) throws Ressourc qe.setPayload(objectMapper.readTree(jo.toString())); qe.setDate(today); liste.add(questioningEventService.saveQuestioningEvent(qe)); - if(quest.isPresent()){ + if (quest.isPresent()) { quest.get().getQuestioningEvents().add(qe); questioningService.saveQuestioning(quest.get()); } @@ -97,33 +92,34 @@ public ResultUpload save(String idCampaign, UploadDto uploadDto) throws Ressourc result.addIdKo(identifier, "RessourceNotFound or unprocessable request"); } } - if (result.getListIdOK().size() == 0) { + if (result.getListIdOK().isEmpty()) { delete(up); return result; } up.setQuestioningEvents(liste); - up = saveAndFlush(up); + saveAndFlush(up); return result; } @Override - public Optional findById(long id) { - return uploadRepository.findById(id); + public Upload findById(long id) { + return uploadRepository.findById(id).orElseThrow(()-> new NotFoundException(String.format("Upload %s not found", id))); } @Override public List findAllByIdCampaign(String idCampaign) { - Optional campaign = campaignService.findById(idCampaign); + Campaign campaign = campaignService.findById(idCampaign); - List partitioningIds = campaign.get().getPartitionings().stream().map(Partitioning::getId).collect(Collectors.toList()); + List partitioningIds = campaign.getPartitionings().stream().map(Partitioning::getId).toList(); // Keeps the uploads which first managementMonitoringInfo belongs to the survey return uploadRepository.findAll().stream().filter(upload -> !upload.getQuestioningEvents().isEmpty()) .filter(upload -> partitioningIds.contains(upload.getQuestioningEvents().stream().findFirst().get().getQuestioning().getIdPartitioning() )) - .collect(Collectors.toList()); + .toList(); + } @@ -139,19 +135,26 @@ public Upload saveAndFlush(Upload up) { @Override public boolean checkUploadDate(String idCampaign, Date date) { - Optional campaign = campaignService.findById(idCampaign); - Long timestamp = date.getTime(); - Long start = campaign.get().getPartitionings().stream().map(Partitioning::getOpeningDate) - .collect(Collectors.toList()).stream() - .min(Comparator.comparing(Date::getTime)).get().getTime(); - Long end = campaign.get().getPartitionings().stream().map(Partitioning::getClosingDate) - .collect(Collectors.toList()).stream() - .max(Comparator.comparing(Date::getTime)).get().getTime(); - return (start < timestamp && timestamp < end); + Campaign campaign = campaignService.findById(idCampaign); + long timestamp = date.getTime(); + Optional openingDate = campaign.getPartitionings().stream().map(Partitioning::getOpeningDate) + .toList().stream() + .min(Comparator.comparing(Date::getTime)); + Optional closingDate = campaign.getPartitionings().stream().map(Partitioning::getClosingDate) + .toList().stream() + .max(Comparator.comparing(Date::getTime)); + if (openingDate.isPresent() && closingDate.isPresent()) { + long start = openingDate.get().getTime(); + long end = closingDate.get().getTime(); + return (start < timestamp && timestamp < end); + + + } + return false; } @Override public void removeEmptyUploads() { - uploadRepository.findByQuestioningEventsIsEmpty().forEach(u -> uploadRepository.delete(u)); + uploadRepository.findByQuestioningEventsIsEmpty().forEach(uploadRepository::delete); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/LastQuestioningEventComparator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/LastQuestioningEventComparator.java index bf62161f..8ba70685 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/LastQuestioningEventComparator.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/LastQuestioningEventComparator.java @@ -1,19 +1,18 @@ package fr.insee.survey.datacollectionmanagement.questioning.util; -import java.util.Comparator; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - import fr.insee.survey.datacollectionmanagement.questioning.domain.EventOrder; import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; import fr.insee.survey.datacollectionmanagement.questioning.service.EventOrderService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.Comparator; @Component +@RequiredArgsConstructor public class LastQuestioningEventComparator implements Comparator { - @Autowired - private EventOrderService eventOrderService; + private final EventOrderService eventOrderService; @Override public int compare(QuestioningEvent o1, QuestioningEvent o2) { diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/TypeQuestioningEvent.java b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/TypeQuestioningEvent.java index 67b40825..b27b32c3 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/TypeQuestioningEvent.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/questioning/util/TypeQuestioningEvent.java @@ -22,8 +22,7 @@ public enum TypeQuestioningEvent { HC, INITLA, PARTIELINT, - PND, - FOLLOWUP); + PND); public static final List FOLLOWUP_EVENTS = Arrays.asList( VALINT, diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/SourceAccreditationController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/SourceAccreditationController.java index b1cd0147..55097b32 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/SourceAccreditationController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/SourceAccreditationController.java @@ -16,20 +16,20 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.modelmapper.ModelMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -38,24 +38,20 @@ + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "7-User", description = "Enpoints to create, update, delete and find users, their events and accreditations") +@Slf4j +@RequiredArgsConstructor +@Validated public class SourceAccreditationController { - static final Logger LOGGER = LoggerFactory.getLogger(SourceAccreditationController.class); + private final SourceAccreditationService sourceAccreditationService; - @Autowired - private SourceAccreditationService sourceAccreditationService; + private final SourceService sourceService; - @Autowired - private SourceService sourceService; + private final UserService userService; - @Autowired - private UserService userService; + private final ViewService viewService; - @Autowired - private ViewService viewService; - - @Autowired - private ModelMapper modelMapper; + private final ModelMapper modelMapper; @Operation(summary = "Search for source accreditations by source id") @GetMapping(value = Constants.API_SOURCE_ID_SOURCE_ACCREDITATIONS, produces = "application/json") @@ -65,16 +61,12 @@ public class SourceAccreditationController { @ApiResponse(responseCode = "400", description = "Bad Request") }) public ResponseEntity getSourceAccreditation(@PathVariable("id") String id) { + Source source = sourceService.findById(id); try { - Optional optSource = sourceService.findById(id); - if (optSource.isPresent()) - return new ResponseEntity<>( - optSource.get().getSourceAccreditations().stream().map(c -> convertToDto(c)) - .collect(Collectors.toList()), - HttpStatus.OK); - else - return new ResponseEntity<>("Source does not exist", HttpStatus.NOT_FOUND); + return ResponseEntity.ok().body(source.getSourceAccreditations().stream().map(c -> convertToDto(c)) + .collect(Collectors.toList())); + } catch (Exception e) { return new ResponseEntity("Error", HttpStatus.INTERNAL_SERVER_ERROR); } @@ -90,25 +82,11 @@ public ResponseEntity getSourceAccreditation(@PathVariable("id") String id) { }) @Transactional public ResponseEntity postSourceAccreditation(@PathVariable("id") String id, - @RequestBody SourceAccreditationDto sourceAccreditationDto) { - - Optional optSource = null; + @Valid @RequestBody SourceAccreditationDto sourceAccreditationDto) { + Source source = sourceService.findById(id);; String idUser = sourceAccreditationDto.getIdUser(); - - // Check if questioning exists - try { - optSource = sourceService.findById(id); - if (!optSource.isPresent()) - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Source does not exist"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error"); - } - Source source = optSource.get(); - - // Check if contact exists - if (!userService.findByIdentifier(idUser).isPresent()) - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User does not exist"); + userService.findByIdentifier(idUser); HttpHeaders responseHeaders = new HttpHeaders(); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserController.java index c8abf72f..1e86beb0 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserController.java @@ -1,42 +1,39 @@ package fr.insee.survey.datacollectionmanagement.user.controller; import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.exception.NotMatchException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; import fr.insee.survey.datacollectionmanagement.metadata.service.SourceService; import fr.insee.survey.datacollectionmanagement.user.domain.SourceAccreditation; import fr.insee.survey.datacollectionmanagement.user.domain.User; import fr.insee.survey.datacollectionmanagement.user.dto.UserDto; -import fr.insee.survey.datacollectionmanagement.user.exception.RoleException; import fr.insee.survey.datacollectionmanagement.user.service.SourceAccreditationService; import fr.insee.survey.datacollectionmanagement.user.service.UserService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.modelmapper.ModelMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.*; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import java.text.ParseException; import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; @RestController @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " @@ -44,55 +41,50 @@ " || @AuthorizeMethodDecider.isAdmin() ") @Tag(name = "7-User", description = "Enpoints to create, update, delete and find users, their events and accreditations") @Slf4j +@Validated +@RequiredArgsConstructor public class UserController { - static final Logger LOGGER = LoggerFactory.getLogger(UserController.class); + private final UserService userService; + private final SourceService sourceService; - @Autowired - UserService userService; + private final SourceAccreditationService sourceAccreditationService; - @Autowired - SourceService sourceService; - - @Autowired - SourceAccreditationService sourceAccreditationService; - - @Autowired - ModelMapper modelMapper; + private final ModelMapper modelMapper; @Operation(summary = "Search for users, paginated") @GetMapping(value = Constants.API_USERS_ALL, produces = "application/json") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = UserController.UserPage.class))) }) - public ResponseEntity getUsers( + public ResponseEntity getUsers( @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer size, @RequestParam(defaultValue = "identifier") String sort) { Pageable pageable = PageRequest.of(page, size, Sort.by(sort)); Page pageC = userService.findAll(pageable); - List listC = pageC.stream().map(c -> convertToDto(c)).collect(Collectors.toList()); + List listC = pageC.stream().map(this::convertToDto).toList(); return ResponseEntity.ok().body(new UserController.UserPage(listC, pageable, pageC.getTotalElements())); } - @Operation(summary = "Search for a user by its id") - @GetMapping(value = Constants.API_USERS_ID, produces = "application/json") + @Operation(summary = "Search for users, without pagination") + @GetMapping(value = Constants.API_USERS_ALL_NO_PAGINATION, produces = "application/json") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = UserDto.class))), - @ApiResponse(responseCode = "404", description = "Not found"), - @ApiResponse(responseCode = "400", description = "Bad Request") + @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = UserDto.class )))) }) - public ResponseEntity getUser(@PathVariable("id") String id) { - Optional user = userService.findByIdentifier(StringUtils.upperCase(id)); - try { - if (user.isPresent()) - return ResponseEntity.ok().body(convertToDto(user.get())); - else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("user does not exist"); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); - } + public ResponseEntity getUsersNotPaginated() { + List users = userService.findAll(); + List listUsers = users.stream().map(this::convertToDto).toList(); + return ResponseEntity.ok().body(listUsers); + } + + @Operation(summary = "Search for a user by its id") + @GetMapping(value = Constants.API_USERS_ID, produces = "application/json") + public ResponseEntity getUser(@PathVariable("id") String id) { + User user = userService.findByIdentifier(id); + return ResponseEntity.ok().body(convertToDto(user)); + } @@ -103,9 +95,9 @@ public ResponseEntity getUser(@PathVariable("id") String id) { @ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = UserDto.class))), @ApiResponse(responseCode = "400", description = "Bad request") }) - public ResponseEntity putUser(@PathVariable("id") String id, @RequestBody UserDto userDto) { - if (StringUtils.isBlank(userDto.getIdentifier()) || !userDto.getIdentifier().equalsIgnoreCase(id)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("id and user identifier don't match"); + public ResponseEntity putUser(@PathVariable("id") String id, @Valid @RequestBody UserDto userDto) { + if (!userDto.getIdentifier().equalsIgnoreCase(id)) { + throw new NotMatchException("id and user identifier don't match"); } User user; HttpHeaders responseHeaders = new HttpHeaders(); @@ -117,23 +109,17 @@ public ResponseEntity putUser(@PathVariable("id") String id, @RequestBody Use } catch (ParseException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Impossible to parse user"); - } - catch (RoleException e){ - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body("Role not recognized: only [" + Stream.of(User.UserRoleType.values()) - .map(User.UserRoleType::name).collect(Collectors.joining(", ")) + "] are possible"); + } catch (NotFoundException e) { + log.info("Creating user with the identifier {}", userDto.getIdentifier()); + user = convertToEntityNewUser(userDto); - } - catch (NoSuchElementException e) { - LOGGER.info("Creating user with the identifier {}", userDto.getIdentifier()); - user = convertToEntityNewContact(userDto); - - User userCreate = userService.createUserEvent(user, null); + User userCreate = userService.createUser(user, null); return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders).body(convertToDto(userCreate)); } - LOGGER.info("Updating user with the identifier {}", userDto.getIdentifier()); - User userUpdate = userService.updateUserEvent(user, null); + log.info("Updating user with the identifier {}", userDto.getIdentifier()); + User userUpdate = userService.updateUser(user, null); + return ResponseEntity.ok().headers(responseHeaders).body(convertToDto(userUpdate)); } @@ -146,26 +132,23 @@ public ResponseEntity putUser(@PathVariable("id") String id, @RequestBody Use @ApiResponse(responseCode = "400", description = "Bad Request") }) @Transactional - public ResponseEntity deleteUser(@PathVariable("id") String id) { + public ResponseEntity deleteUser(@PathVariable("id") String id) { + User user = userService.findByIdentifier(id); + try { - Optional user = userService.findByIdentifier(id); - if (user.isPresent()) { - userService.deleteContactAddressEvent(user.get()); - - sourceAccreditationService.findByUserIdentifier(id).stream().forEach(acc -> { - Source source = sourceService.findById(acc.getSource().getId()).get(); - Set newSet = source.getSourceAccreditations(); - newSet.removeIf(a -> a.getId().equals(acc.getId())); - source.setSourceAccreditations(newSet); - sourceService.insertOrUpdateSource(source); - sourceAccreditationService.deleteAccreditation(acc); - - }); - log.info("Delete user {}", id); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("User deleted"); - } else { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User does not exist"); - } + userService.deleteUserAndEvents(user); + + sourceAccreditationService.findByUserIdentifier(id).stream().forEach(acc -> { + Source source = sourceService.findById(acc.getSource().getId()); + Set newSet = source.getSourceAccreditations(); + newSet.removeIf(a -> a.getId().equals(acc.getId())); + source.setSourceAccreditations(newSet); + sourceService.insertOrUpdateSource(source); + sourceAccreditationService.deleteAccreditation(acc); + + }); + log.info("Delete user {}", id); + return ResponseEntity.status(HttpStatus.NO_CONTENT).body("User deleted"); } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); } @@ -178,43 +161,37 @@ public ResponseEntity deleteUser(@PathVariable("id") String id) { @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Bad Request") }) - public ResponseEntity getUserSources(@PathVariable("id") String id){ - Optional user = userService.findByIdentifier(id); - if (user.isPresent()) { - List accreditedSources= userService.findAccreditedSources(id); - return ResponseEntity.status(HttpStatus.OK).body(accreditedSources); - } - else { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User does not exist"); - } + public ResponseEntity getUserSources(@PathVariable("id") String id) { + userService.findByIdentifier(id); + List accreditedSources = userService.findAccreditedSources(id); + return ResponseEntity.status(HttpStatus.OK).body(accreditedSources); } + private User convertToEntity(UserDto userDto) throws ParseException { - private User convertToEntity(UserDto userDto) throws ParseException, NoSuchElementException, RoleException { + User oldUser = userService.findByIdentifier(userDto.getIdentifier()); User user = modelMapper.map(userDto, User.class); - - Optional oldUser = userService.findByIdentifier(userDto.getIdentifier()); - if (!oldUser.isPresent()) { - throw new NoSuchElementException(); - } - if(user.getRole()==null){ - throw new RoleException("Role missing or not recognized. Only [" + Stream.of(User.UserRoleType.values()).map(User.UserRoleType::name).collect(Collectors.joining(", ")) + "] are possible"); - } - user.setUserEvents(oldUser.get().getUserEvents()); + user.setRole(User.UserRoleType.valueOf(userDto.getRole())); + user.setUserEvents(oldUser.getUserEvents()); return user; } - private User convertToEntityNewContact(UserDto userDto) { + private User convertToEntityNewUser(UserDto userDto) { User user = modelMapper.map(userDto, User.class); + user.setRole(User.UserRoleType.valueOf(userDto.getRole())); return user; } private UserDto convertToDto(User user) { - UserDto userDto = modelMapper.map(user, UserDto.class); + + List accreditedSources = userService.findAccreditedSources(user.getIdentifier()); + UserDto userDto= modelMapper.map(user, UserDto.class); + userDto.setAccreditedSources(accreditedSources); return userDto; } + class UserPage extends PageImpl { private static final long serialVersionUID = 656181199902518234L; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserEventController.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserEventController.java index dff884f1..e8052ae2 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserEventController.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/controller/UserEventController.java @@ -2,7 +2,6 @@ import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.exception.EventException; import fr.insee.survey.datacollectionmanagement.user.domain.User; import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent; import fr.insee.survey.datacollectionmanagement.user.dto.UserEventDto; @@ -15,37 +14,36 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.modelmapper.ModelMapper; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; -@RestController(value="UserEvents") +@RestController(value = "UserEvents") @PreAuthorize("@AuthorizeMethodDecider.isInternalUser() " + "|| @AuthorizeMethodDecider.isWebClient() " + "|| @AuthorizeMethodDecider.isAdmin() ") @Slf4j @Tag(name = "7-User", description = "Enpoints to create, update, delete and find users, their events and accreditations") +@RequiredArgsConstructor +@Validated public class UserEventController { - @Autowired - private ModelMapper modelMapper; + private final ModelMapper modelMapper; - @Autowired - UserService userService; + private final UserService userService; - @Autowired - UserEventService userEventService; + private final UserEventService userEventService; @Operation(summary = "Search for userEvents by user's id") @GetMapping(value = Constants.API_USERS_ID_USEREVENTS, produces = "application/json") @@ -54,17 +52,13 @@ public class UserEventController { @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Internal servor error") }) - public ResponseEntity getUserUserEvents(@PathVariable("id") String identifier) { - try { - - Optional optUser = userService.findByIdentifier(identifier); - if (optUser.isPresent()) { - return ResponseEntity.status(HttpStatus.OK) - .body(optUser.get().getUserEvents().stream().map(ce -> convertToDto(ce)) - .collect(Collectors.toList())); + public ResponseEntity getUserUserEvents(@PathVariable("id") String identifier) { + User user = userService.findByIdentifier(identifier); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User does not exist"); + try { + return ResponseEntity.status(HttpStatus.OK) + .body(user.getUserEvents().stream().map(this::convertToDto) + .toList()); } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); } @@ -78,30 +72,21 @@ public ResponseEntity getUserUserEvents(@PathVariable("id") String identifier @ApiResponse(responseCode = "400", description = "Bad request"), @ApiResponse(responseCode = "404", description = "Not found") }) - public ResponseEntity postUserEvent(@RequestBody UserEventDto userEventDto) { - try { + public ResponseEntity postUserEvent(@Valid @RequestBody UserEventDto userEventDto) { + + User user = userService.findByIdentifier(userEventDto.getIdentifier()); + UserEvent userEvent = convertToEntity(userEventDto); + UserEvent newUserEvent = userEventService.saveUserEvent(userEvent); + Set setUserEvents = user.getUserEvents(); + setUserEvents.add(newUserEvent); + user.setUserEvents(setUserEvents); + userService.saveUser(user); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set(HttpHeaders.LOCATION, + ServletUriComponentsBuilder.fromCurrentRequest().toUriString()); + return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders) + .body(convertToDto(newUserEvent)); - Optional optUser = userService.findByIdentifier(userEventDto.getIdentifier()); - if (optUser.isPresent()) { - User user = optUser.get(); - UserEvent userEvent = convertToEntity(userEventDto); - UserEvent newUserEvent = userEventService.saveUserEvent(userEvent); - Set setUserEvents = user.getUserEvents(); - setUserEvents.add(newUserEvent); - user.setUserEvents(setUserEvents); - userService.saveUser(user); - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.set(HttpHeaders.LOCATION, - ServletUriComponentsBuilder.fromCurrentRequest().toUriString()); - return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders) - .body(convertToDto(newUserEvent)); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User does not exist"); - } catch (EventException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body("Event not recognized: only [" + Stream.of(UserEvent.UserEventType.values()) - .map(UserEvent.UserEventType::name).collect(Collectors.joining(", ")) + "] are possible"); - } } @@ -112,19 +97,17 @@ public ResponseEntity postUserEvent(@RequestBody UserEventDto userEventDto) { @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "400", description = "Bad Request") }) - public ResponseEntity deleteUserEvent(@PathVariable("id") Long id) { + public ResponseEntity deleteUserEvent(@PathVariable("id") Long id) { + UserEvent userEvent = userEventService.findById(id); + try { - Optional optUserEvent = userEventService.findById(id); - if (optUserEvent.isPresent()) { - UserEvent userEvent = optUserEvent.get(); - User user = userEvent.getUser(); - user.setUserEvents(user.getUserEvents().stream().filter(ue -> !ue.equals(userEvent)) - .collect(Collectors.toSet())); - userService.saveUser(user); - userEventService.deleteUserEvent(id); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("User event deleted"); - } else - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User event does not exist"); + User user = userEvent.getUser(); + user.setUserEvents(user.getUserEvents().stream().filter(ue -> !ue.equals(userEvent)) + .collect(Collectors.toSet())); + userService.saveUser(user); + userEventService.deleteUserEvent(id); + return ResponseEntity.status(HttpStatus.NO_CONTENT).body("User event deleted"); + } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Error"); @@ -137,10 +120,7 @@ private UserEventDto convertToDto(UserEvent userEvent) { return ueDto; } - private UserEvent convertToEntity(UserEventDto userEventDto) throws EventException { - UserEvent userEvent = modelMapper.map(userEventDto, UserEvent.class); - if (userEvent.getType() == null) - throw new EventException("User event not recognized"); - return userEvent; + private UserEvent convertToEntity(UserEventDto userEventDto) { + return modelMapper.map(userEventDto, UserEvent.class); } } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/SourceAccreditation.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/SourceAccreditation.java index b268336d..14f90737 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/SourceAccreditation.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/SourceAccreditation.java @@ -2,24 +2,19 @@ import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.OneToOne; +import jakarta.persistence.*; +import lombok.*; + import java.util.Date; @Entity -@Data +@Getter +@Setter @NoArgsConstructor public class SourceAccreditation { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "source_accreditation_seq") private Long id; private Date creationDate; @@ -28,7 +23,6 @@ public class SourceAccreditation { private String idUser; @OneToOne - @EqualsAndHashCode.Exclude private Source source; @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/User.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/User.java index cb3d71ac..102d04aa 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/User.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/User.java @@ -1,30 +1,38 @@ package fr.insee.survey.datacollectionmanagement.user.domain; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; -import javax.persistence.*; +import java.util.Date; import java.util.Set; @Entity -@Data +@Getter +@Setter @Table(name = "InternalUsers") public class User { public enum UserRoleType { - responsable, gestionnaire, assistance + ADMINISTRATEUR, RESPONSABLE, GESTIONNAIRE, ASSISTANCE } @Id private String identifier; - + private String name; + private String firstName; + private String organization; + private Date creationDate; + private String creationAuthor; + + @JdbcTypeCode(SqlTypes.INTEGER) + @Enumerated(EnumType.ORDINAL) private UserRoleType role; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @EqualsAndHashCode.Exclude - @ToString.Exclude private Set userEvents; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/UserEvent.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/UserEvent.java index f476d497..178b78c4 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/UserEvent.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/domain/UserEvent.java @@ -1,38 +1,38 @@ package fr.insee.survey.datacollectionmanagement.user.domain; import com.fasterxml.jackson.databind.JsonNode; -import com.vladmihalcea.hibernate.type.json.JsonBinaryType; +import jakarta.persistence.*; import lombok.*; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; -import javax.persistence.*; import java.util.Date; @Entity -@Data +@Getter +@Setter @NoArgsConstructor -@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) public class UserEvent { public enum UserEventType { - create, update, delete + CREATE, UPDATE, DELETE } @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_event_seq") private Long id; private Date eventDate; + @NonNull + @Enumerated(EnumType.ORDINAL) + @JdbcTypeCode(SqlTypes.INTEGER) private UserEventType type; @ManyToOne - @EqualsAndHashCode.Exclude - @ToString.Exclude private User user; - @Type(type = "jsonb") + @JdbcTypeCode(SqlTypes.JSON) @Column(columnDefinition = "jsonb") private JsonNode payload; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/SourceAccreditationDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/SourceAccreditationDto.java index 58e79bc7..6396d3bf 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/SourceAccreditationDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/SourceAccreditationDto.java @@ -2,22 +2,22 @@ import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; -import javax.persistence.Id; import java.util.Date; @Getter @Setter public class SourceAccreditationDto { - @Id @JsonIgnore private Long id; - private Date creationDate; + @NotBlank(message = "creationAuthor can't be empty") private String creationAuthor; + @NotBlank(message = "idUser can't be empty") private String idUser; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserDto.java index 169f357e..5697fee1 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserDto.java @@ -1,15 +1,28 @@ package fr.insee.survey.datacollectionmanagement.user.dto; +import fr.insee.survey.datacollectionmanagement.user.validation.UserRoleValid; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; +import java.util.Date; +import java.util.List; + @Getter @Setter public class UserDto{ - + @NotBlank private String identifier; + @UserRoleValid private String role; + private String name; + private String firstName; + private String organization; + private List accreditedSources; + private Date creationDate; + private String creationAuthor; + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserEventDto.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserEventDto.java index 6db17514..f266060d 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserEventDto.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/dto/UserEventDto.java @@ -1,6 +1,8 @@ package fr.insee.survey.datacollectionmanagement.user.dto; import com.fasterxml.jackson.databind.JsonNode; +import fr.insee.survey.datacollectionmanagement.user.validation.UserEventTypeValid; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -11,8 +13,10 @@ public class UserEventDto { private Long id; + @NotBlank(message = "identifier can't be blank") private String identifier; private Date eventDate; + @UserEventTypeValid private String type; private JsonNode payload; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/repository/SourceAccreditationRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/repository/SourceAccreditationRepository.java index b186c3c8..56313733 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/repository/SourceAccreditationRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/repository/SourceAccreditationRepository.java @@ -7,5 +7,5 @@ public interface SourceAccreditationRepository extends JpaRepository { - public List findByIdUser(String idUser); + List findByIdUser(String idUser); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/repository/UserRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/repository/UserRepository.java index 18a0dcb8..5083ff41 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/repository/UserRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/repository/UserRepository.java @@ -6,7 +6,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.PagingAndSortingRepository; +import java.util.Optional; + public interface UserRepository extends PagingAndSortingRepository, JpaRepository { Page findAll(Pageable pageable); + + Optional findByIdentifierIgnoreCase(String identifier); } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/SourceAccreditationService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/SourceAccreditationService.java index 47c76772..5ae9150f 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/SourceAccreditationService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/SourceAccreditationService.java @@ -6,7 +6,6 @@ import org.springframework.data.domain.Pageable; import java.util.List; -import java.util.Optional; public interface SourceAccreditationService { @@ -14,7 +13,7 @@ public interface SourceAccreditationService { public Page findAll(Pageable pageable); - public Optional findById(Long id); + public SourceAccreditation findById(Long id); public SourceAccreditation saveSourceAccreditation(SourceAccreditation sourceAccreditation); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserEventService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserEventService.java index 61388842..8fd8898e 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserEventService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserEventService.java @@ -8,7 +8,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import java.util.Optional; import java.util.Set; @Service @@ -16,7 +15,7 @@ public interface UserEventService { public Page findAll(Pageable pageable); - public Optional findById(Long id); + public UserEvent findById(Long id); public UserEvent saveUserEvent(UserEvent userEvent); diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserService.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserService.java index 34df6b61..54b7e33c 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserService.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/UserService.java @@ -2,13 +2,13 @@ import com.fasterxml.jackson.databind.JsonNode; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.user.domain.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; -import java.util.Optional; @Service public interface UserService { @@ -21,13 +21,15 @@ public interface UserService { */ public Page findAll(Pageable pageable); + public List findAll(); + /** * Find a user by its identifier. * * @param identifier * @return Optional user found */ - public Optional findByIdentifier(String identifier) ; + public User findByIdentifier(String identifier) ; /** * Update an existing user , or creates a new one @@ -43,11 +45,11 @@ public interface UserService { */ public void deleteUser(String identifier); - public User createUserEvent(User user, JsonNode payload); + public User createUser(User user, JsonNode payload); - public User updateUserEvent(User user, JsonNode payload); + public User updateUser(User user, JsonNode payload) throws NotFoundException; - public void deleteContactAddressEvent(User user); + public void deleteUserAndEvents(User user); List findAccreditedSources(String identifier); } \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/SourceAccreditationServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/SourceAccreditationServiceImpl.java index d40c4ec3..e41a94e4 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/SourceAccreditationServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/SourceAccreditationServiceImpl.java @@ -1,21 +1,21 @@ package fr.insee.survey.datacollectionmanagement.user.service.impl; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.user.domain.SourceAccreditation; import fr.insee.survey.datacollectionmanagement.user.repository.SourceAccreditationRepository; import fr.insee.survey.datacollectionmanagement.user.service.SourceAccreditationService; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; -import java.util.Optional; @Service +@RequiredArgsConstructor public class SourceAccreditationServiceImpl implements SourceAccreditationService { - @Autowired - private SourceAccreditationRepository sourceAccreditationRepository; + private final SourceAccreditationRepository sourceAccreditationRepository; public List findByUserIdentifier(String id) { return sourceAccreditationRepository.findByIdUser(id); @@ -27,8 +27,8 @@ public Page findAll(Pageable pageable) { } @Override - public Optional findById(Long id) { - return sourceAccreditationRepository.findById(id); + public SourceAccreditation findById(Long id) { + return sourceAccreditationRepository.findById(id).orElseThrow(()-> new NotFoundException(String.format("SourceAccreditation %s not found", id))); } @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserEventServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserEventServiceImpl.java index 49f0254c..b5f323bd 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserEventServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserEventServiceImpl.java @@ -2,24 +2,24 @@ import com.fasterxml.jackson.databind.JsonNode; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.user.domain.User; import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent; import fr.insee.survey.datacollectionmanagement.user.repository.UserEventRepository; import fr.insee.survey.datacollectionmanagement.user.service.UserEventService; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.Date; -import java.util.Optional; import java.util.Set; @Service +@RequiredArgsConstructor public class UserEventServiceImpl implements UserEventService { - @Autowired - private UserEventRepository userEventRepository; + private final UserEventRepository userEventRepository; @Override public Page findAll(Pageable pageable) { @@ -27,8 +27,8 @@ public Page findAll(Pageable pageable) { } @Override - public Optional findById(Long id) { - return userEventRepository.findById(id); + public UserEvent findById(Long id) { + return userEventRepository.findById(id).orElseThrow(()-> new NotFoundException(String.format("QuestioningAccreditation %s not found", id))); } @Override diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserServiceImpl.java index 03383970..c18071bd 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/service/impl/UserServiceImpl.java @@ -1,6 +1,7 @@ package fr.insee.survey.datacollectionmanagement.user.service.impl; import com.fasterxml.jackson.databind.JsonNode; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; import fr.insee.survey.datacollectionmanagement.user.domain.SourceAccreditation; import fr.insee.survey.datacollectionmanagement.user.domain.User; @@ -9,25 +10,22 @@ import fr.insee.survey.datacollectionmanagement.user.service.SourceAccreditationService; import fr.insee.survey.datacollectionmanagement.user.service.UserEventService; import fr.insee.survey.datacollectionmanagement.user.service.UserService; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.*; -import java.util.stream.Collectors; @Service +@RequiredArgsConstructor public class UserServiceImpl implements UserService { - @Autowired - UserEventService userEventService; + private final UserEventService userEventService; - @Autowired - UserRepository userRepository; + private final UserRepository userRepository; - @Autowired - SourceAccreditationService sourceAccreditationService; + private final SourceAccreditationService sourceAccreditationService; @Override public Page findAll(Pageable pageable) { @@ -35,8 +33,13 @@ public Page findAll(Pageable pageable) { } @Override - public Optional findByIdentifier(String identifier) { - return userRepository.findById(identifier); + public List findAll() { + return userRepository.findAll(); + } + + @Override + public User findByIdentifier(String identifier) { + return userRepository.findByIdentifierIgnoreCase(identifier).orElseThrow(()-> new NotFoundException(String.format("User %s not found", identifier))); } @Override @@ -51,21 +54,21 @@ public void deleteUser(String identifier) { @Override - public User createUserEvent(User user, JsonNode payload) { + public User createUser(User user, JsonNode payload) { - UserEvent newUserEvent = userEventService.createUserEvent(user, UserEvent.UserEventType.create, + UserEvent newUserEvent = userEventService.createUserEvent(user, UserEvent.UserEventType.CREATE, payload); user.setUserEvents(new HashSet<>(Arrays.asList(newUserEvent))); return saveUser(user); } @Override - public User updateUserEvent(User user, JsonNode payload) { + public User updateUser(User user, JsonNode payload) { - User existingUser = findByIdentifier(user.getIdentifier()).get(); + User existingUser = findByIdentifier(user.getIdentifier()); Set setUserEventsUser = existingUser.getUserEvents(); - UserEvent userEventUpdate = userEventService.createUserEvent(user, UserEvent.UserEventType.update, + UserEvent userEventUpdate = userEventService.createUserEvent(user, UserEvent.UserEventType.UPDATE, payload); setUserEventsUser.add(userEventUpdate); user.setUserEvents(setUserEventsUser); @@ -73,7 +76,7 @@ public User updateUserEvent(User user, JsonNode payload) { } @Override - public void deleteContactAddressEvent(User user) { + public void deleteUserAndEvents(User user) { deleteUser(user.getIdentifier()); } @@ -82,8 +85,8 @@ public List findAccreditedSources(String identifier){ List accreditedSources = new ArrayList<>(); List accreditations = sourceAccreditationService.findByUserIdentifier(identifier); - List accSource = accreditations.stream().map(SourceAccreditation::getSource).collect(Collectors.toList()); - accSource.stream().forEach(acc -> accreditedSources.add(acc.getId())); + List accSource = accreditations.stream().map(SourceAccreditation::getSource).toList(); + accSource.forEach(acc -> accreditedSources.add(acc.getId())); return accreditedSources; } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValid.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValid.java new file mode 100644 index 00000000..e115ea35 --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValid.java @@ -0,0 +1,26 @@ +package fr.insee.survey.datacollectionmanagement.user.validation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +@Target({FIELD, PARAMETER, METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = UserEventTypeValidator.class) +public @interface UserEventTypeValid { + //error message + String message() default "Type missing or not recognized. Only CREATE, UPDATE, DELETE are valid"; + + //represents group of constraints + Class[] groups() default {}; + + //represents additional information about annotation + Class[] payload() default {}; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValidator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValidator.java new file mode 100644 index 00000000..dac2ba8f --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserEventTypeValidator.java @@ -0,0 +1,23 @@ +package fr.insee.survey.datacollectionmanagement.user.validation; + +import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.util.Arrays; + +public class UserEventTypeValidator implements ConstraintValidator { + + + @Override + public void initialize(UserEventTypeValid constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (value == null) + return false; + return Arrays.stream(UserEvent.UserEventType.values()).anyMatch(v -> value.equalsIgnoreCase(v.name())); + } +} \ No newline at end of file diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValid.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValid.java new file mode 100644 index 00000000..75f97f5f --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValid.java @@ -0,0 +1,26 @@ +package fr.insee.survey.datacollectionmanagement.user.validation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +@Target({FIELD, PARAMETER, METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = UserRoleValidator.class) +public @interface UserRoleValid { + //error message + String message() default "Role missing or not recognized. Only RESPONSABLE, GESTIONNAIRE, ASSISTANCE are valid"; + + //represents group of constraints + Class[] groups() default {}; + + //represents additional information about annotation + Class[] payload() default {}; +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValidator.java b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValidator.java new file mode 100644 index 00000000..a57b620d --- /dev/null +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/user/validation/UserRoleValidator.java @@ -0,0 +1,23 @@ +package fr.insee.survey.datacollectionmanagement.user.validation; + +import fr.insee.survey.datacollectionmanagement.user.domain.User; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.util.Arrays; + +public class UserRoleValidator implements ConstraintValidator { + + + @Override + public void initialize(UserRoleValid constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if(value == null) + return false; + return Arrays.stream(User.UserRoleType.values()).anyMatch(v -> value.equalsIgnoreCase(v.name())); + } +} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/util/Dataloader.java b/src/main/java/fr/insee/survey/datacollectionmanagement/util/Dataloader.java deleted file mode 100644 index bb91ff6c..00000000 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/util/Dataloader.java +++ /dev/null @@ -1,694 +0,0 @@ -package fr.insee.survey.datacollectionmanagement.util; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; - -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jeasy.random.EasyRandom; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; - -import com.github.javafaker.Animal; -import com.github.javafaker.Faker; -import com.github.javafaker.Name; - -import fr.insee.survey.datacollectionmanagement.contact.domain.Address; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact.Gender; -import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; -import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; -import fr.insee.survey.datacollectionmanagement.contact.repository.AddressRepository; -import fr.insee.survey.datacollectionmanagement.contact.repository.ContactEventRepository; -import fr.insee.survey.datacollectionmanagement.contact.repository.ContactRepository; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Owner; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Support; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; -import fr.insee.survey.datacollectionmanagement.metadata.repository.CampaignRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.OwnerRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.PartitioningRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SourceRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SupportRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SurveyRepository; -import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; -import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; -import fr.insee.survey.datacollectionmanagement.questioning.domain.EventOrder; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Operator; -import fr.insee.survey.datacollectionmanagement.questioning.domain.OperatorService; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnitAddress; -import fr.insee.survey.datacollectionmanagement.questioning.repository.EventOrderRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.OperatorRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.OperatorServiceRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningAccreditationRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningEventRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitAddressRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitRepository; -import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; -import fr.insee.survey.datacollectionmanagement.view.domain.View; -import fr.insee.survey.datacollectionmanagement.view.repository.ViewRepository; - -@Component -public class Dataloader { - - private static final Logger LOGGER = LogManager.getLogger(Dataloader.class); - - @Autowired - private ContactRepository contactRepository; - - @Autowired - private AddressRepository addressRepository; - - @Autowired - private ContactEventRepository contactEventRepository; - - @Autowired - private OwnerRepository ownerRepository; - - @Autowired - private SupportRepository supportRepository; - - @Autowired - private SourceRepository sourceRepository; - - @Autowired - private SurveyRepository surveyRepository; - - @Autowired - private SurveyUnitRepository surveyUnitRepository; - - @Autowired - private SurveyUnitAddressRepository surveyUnitAddressRepository; - - @Autowired - private OperatorServiceRepository operatorServiceRepository; - - @Autowired - private OperatorRepository operatorRepository; - - @Autowired - private QuestioningRepository questioningRepository; - - @Autowired - private QuestioningAccreditationRepository questioningAccreditationRepository; - - @Autowired - private CampaignRepository campaignRepository; - - @Autowired - private PartitioningRepository partitioningRepository; - - @Autowired - private EventOrderRepository orderRepository; - - @Autowired - private QuestioningEventRepository questioningEventRepository; - - @Autowired - private ViewRepository viewRepository; - - @PostConstruct - public void init() { - - Faker faker = new Faker(); - EasyRandom generator = new EasyRandom(); - - initOrder(); -// initContact(faker); -// initMetadata(faker, generator); -// initQuestionning(faker, generator); - // initView(); -// initSurveyUnitAddressAndOperators(faker); - - } - - private void initSurveyUnitAddressAndOperators(Faker faker) { - if (surveyUnitAddressRepository.count() == 0) { - for (SurveyUnit su : surveyUnitRepository.findAll()) { - SurveyUnitAddress a = new SurveyUnitAddress(); - com.github.javafaker.Address fakeAddress = faker.address(); - - a.setCountryName(fakeAddress.country()); - a.setStreetNumber(fakeAddress.buildingNumber()); - a.setStreetName(fakeAddress.streetName()); - a.setZipCode(fakeAddress.zipCode()); - a.setCityName(fakeAddress.cityName()); - su.setSurveyUnitAddress(a); - surveyUnitRepository.save(su); - } - } - - if (operatorServiceRepository.count() == 0) { - Set setOpConj = new HashSet<>(); - OperatorService operatorServiceConj = new OperatorService(); - operatorServiceConj.setName("Conjoncture"); - operatorServiceConj.setMail("conjoncture@Cocorico.fr"); - for (int i = 0; i < 9; i++) { - setOpConj.add(createOperator(faker)); - } - operatorServiceConj.setOperators(setOpConj); - operatorServiceRepository.save(operatorServiceConj); - - Set setOpLogement = new HashSet<>(); - OperatorService operatorServiceLogement = new OperatorService(); - operatorServiceLogement.setName("Logement"); - operatorServiceLogement.setMail("logement@Cocorico.fr"); - operatorServiceRepository.save(operatorServiceLogement); - for (int i = 0; i < 9; i++) { - setOpLogement.add(createOperator(faker)); - } - operatorServiceLogement.setOperators(setOpLogement); - operatorServiceRepository.save(operatorServiceLogement); - - Set setOpEmploi = new HashSet<>(); - OperatorService operatorServiceEmploi = new OperatorService(); - operatorServiceEmploi.setName("Emploi"); - operatorServiceEmploi.setMail("emploi@Cocorico.fr"); - operatorServiceRepository.save(operatorServiceEmploi); - for (int i = 0; i < 9; i++) { - setOpEmploi.add(createOperator(faker)); - } - operatorServiceEmploi.setOperators(setOpEmploi); - operatorServiceRepository.save(operatorServiceEmploi); - - Set setOpPrix = new HashSet<>(); - OperatorService operatorServicePrix = new OperatorService(); - operatorServicePrix.setName("Prix"); - operatorServicePrix.setMail("prix@Cocorico.fr"); - operatorServiceRepository.save(operatorServicePrix); - for (int i = 0; i < 9; i++) { - setOpPrix.add(createOperator(faker)); - } - operatorServicePrix.setOperators(setOpPrix); - operatorServiceRepository.save(operatorServicePrix); - } - - if (operatorServiceRepository.count() == 0) { - for (SurveyUnit su : surveyUnitRepository.findAll()) { - SurveyUnitAddress a = new SurveyUnitAddress(); - com.github.javafaker.Address fakeAddress = faker.address(); - - a.setCountryName(fakeAddress.country()); - a.setStreetNumber(fakeAddress.buildingNumber()); - a.setStreetName(fakeAddress.streetName()); - a.setZipCode(fakeAddress.zipCode()); - a.setCityName(fakeAddress.cityName()); - su.setSurveyUnitAddress(a); - surveyUnitRepository.save(su); - } - } - - } - - private Operator createOperator(Faker faker) { - Operator operator = new Operator(); - Name n = faker.name(); - String name = n.lastName(); - String firstName = n.firstName(); - operator.setLastName(name); - operator.setFirstName(firstName); - operator.setPhoneNumber(faker.phoneNumber().phoneNumber()); - return operatorRepository.save(operator); - } - - private void initOrder() { - - Long nbExistingOrders = orderRepository.count(); - LOGGER.info("{} orders in database", nbExistingOrders); - - if (nbExistingOrders !=8 ) { - // Creating table order - LOGGER.info("loading eventorder data"); - orderRepository.deleteAll(); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("8"), TypeQuestioningEvent.REFUSAL.toString(), 8)); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("7"), TypeQuestioningEvent.VALINT.toString(), 7)); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("6"), TypeQuestioningEvent.VALPAP.toString(), 6)); - orderRepository.saveAndFlush(new EventOrder(Long.parseLong("5"), TypeQuestioningEvent.HC.toString(), 5)); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("4"), TypeQuestioningEvent.PARTIELINT.toString(), 4)); - orderRepository.saveAndFlush(new EventOrder(Long.parseLong("3"), TypeQuestioningEvent.WASTE.toString(), 3)); - orderRepository.saveAndFlush(new EventOrder(Long.parseLong("2"), TypeQuestioningEvent.PND.toString(), 2)); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("1"), TypeQuestioningEvent.INITLA.toString(), 1)); - } - } - - private void initContact(Faker faker) { - - List listContact = new ArrayList<>(); - List
listAddresses = new ArrayList<>(); - Long nbExistingContacts = contactRepository.count(); - - LOGGER.info("{} contacts exist in database", nbExistingContacts); - - int nbContacts = 1000000; - - for (Long i = nbExistingContacts; i < nbContacts; i++) { - long start = System.currentTimeMillis(); - - final Contact c = new Contact(); - final Address a = new Address(); - - Name n = faker.name(); - String name = n.lastName(); - String firstName = n.firstName(); - com.github.javafaker.Address fakeAddress = faker.address(); - - a.setCountryName(fakeAddress.country()); - a.setStreetNumber(fakeAddress.buildingNumber()); - a.setStreetName(fakeAddress.streetName()); - a.setZipCode(fakeAddress.zipCode()); - a.setCityName(fakeAddress.cityName()); - // addressRepository.save(a); - listAddresses.add(a); - - c.setIdentifier(RandomStringUtils.randomAlphanumeric(7).toUpperCase()); - c.setLastName(name); - c.setFirstName(firstName); - c.setPhone(faker.phoneNumber().phoneNumber()); - c.setGender(Gender.valueOf(faker.demographic().sex())); - c.setFunction(faker.job().title()); - c.setComment(faker.beer().name()); - c.setEmail(firstName.toLowerCase() + "." + name.toLowerCase() + "@cocorico.fr"); - c.setAddress(a); - listContact.add(c); - // contactRepository.save(c); - - if ((i + 1) % 10000 == 0) { - addressRepository.saveAll(listAddresses); - contactRepository.saveAll(listContact); - listAddresses = new ArrayList<>(); - listContact = new ArrayList<>(); - long end = System.currentTimeMillis(); - - // LOGGER.info("It took {}ms to execute save() for 100 contacts.", (end - - // start)); - - LOGGER.info("It took {}ms to execute saveAll() for 10000 contacts.", (end - start)); - } - - } - - Long nbContactEvents = contactEventRepository.count(); - - for (Long j = nbContactEvents; j < 300; j++) { - Contact contact = contactRepository.findRandomContact(); - ContactEvent contactEvent = new ContactEvent(); - contactEvent.setType(ContactEventType.create); - contactEvent.setEventDate(new Date()); - contactEvent.setContact(contact); - contactEventRepository.save(contactEvent); - Set setContactEvents = new HashSet<>(); - setContactEvents.add(contactEvent); - contact.setContactEvents(setContactEvents); - contactRepository.save(contact); - } - // addressRepository.saveAll(listAddresses); - // contactRepository.saveAll(listContact); - // long end = System.currentTimeMillis(); - // - // LOGGER.info("It took {}ms to execute save() for {} contacts.", (end - start), - // (nbContacts - nbExistingContacts)); - - // LOGGER.info("It took {}ms to execute saveAll() for {} contacts.", (end - - // start), (nbContacts - nbExistingContacts)); - - } - - private void initMetadata(Faker faker, EasyRandom generator2) { - - int year = 2023; - - Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.YEAR, year); - calendar.set(Calendar.MONTH, Calendar.DECEMBER); - calendar.set(Calendar.DAY_OF_MONTH, 31); - Date dateEndOfYear = calendar.getTime(); - - Owner ownerInsee = new Owner(); - ownerInsee.setId("insee"); - ownerInsee.setLabel("Insee"); - Set setSourcesInsee = new HashSet<>(); - - Owner ownerAgri = new Owner(); - ownerAgri.setId("agri"); - ownerAgri.setLabel("SSM Agriculture"); - Set setSourcesSsp = new HashSet<>(); - - Support supportInseeHdf = new Support(); - supportInseeHdf.setId("inseehdf"); - supportInseeHdf.setLabel("Insee Hauts-de-France"); - Set setSourcesSupportInsee = new HashSet<>(); - - Support supportSsne = new Support(); - supportSsne.setId("ssne"); - supportSsne.setLabel("Insee Normandie - SSNE"); - Set setSourcesSupportSsne = new HashSet<>(); - - LOGGER.info("{} campaigns exist in database", campaignRepository.count()); - - while (sourceRepository.count() < 10) { - - Source source = new Source(); - - String nameSource = "LOAD"+String.valueOf((char)(sourceRepository.count() + 'A')); - - if (!StringUtils.contains(nameSource, " ") && sourceRepository.findById(nameSource).isEmpty()) { - - source.setId(nameSource); - source.setLongWording("Have you ever heard about " + nameSource + " ?"); - source.setShortWording("Source about " + nameSource); - source.setPeriodicity(PeriodicityEnum.M); - sourceRepository.save(source); - Set setSurveys = new HashSet<>(); - Integer i = new Random().nextInt(); - if (i % 2 == 0) - setSourcesInsee.add(source); - else { - setSourcesSsp.add(source); - } - - for (int j = 0; j < 4; j++) { - - Survey survey = new Survey(); - String id = nameSource + (year - j); - survey.setId(id); - survey.setYear(year - j); - survey.setLongObjectives("The purpose of this survey is to find out everything you can about " - + nameSource - + ". Your response is essential to ensure the quality and reliability of the results of this survey."); - survey.setShortObjectives("All about " + id); - survey.setCommunication("Communication around " + id); - survey.setSpecimenUrl("http://specimenUrl/" + id); - survey.setDiffusionUrl("http://diffusion/" + id); - survey.setCnisUrl("http://cnis/" + id); - survey.setNoticeUrl("http://notice/" + id); - survey.setVisaNumber(year + RandomStringUtils.randomAlphanumeric(6).toUpperCase()); - survey.setLongWording("Survey " + nameSource + " " + (year - j)); - survey.setShortWording(id); - survey.setSampleSize(Integer.parseInt(RandomStringUtils.randomNumeric(5))); - setSurveys.add(survey); - surveyRepository.save(survey); - Set setCampaigns = new HashSet<>(); - - for (int k = 0; k < 12; k++) { - Campaign campaign = new Campaign(); - int month = k + 1; - String period = month<10? "M0" + month:"M"+month; - campaign.setYear(year - j); - campaign.setPeriod(PeriodEnum.valueOf(period)); - campaign.setId(nameSource + (year - j) + period); - campaign.setCampaignWording( - "Campaign about " + nameSource + " in " + (year - j) + " and period " + period); - setCampaigns.add(campaign); - campaignRepository.save(campaign); - Set setParts = new HashSet<>(); - - for (int l = 0; l < 3; l++) { - - Partitioning part = new Partitioning(); - part.setId(nameSource + (year - j) + "M" + month + "-00" + l); - Date openingDate = faker.date().past(90, 0, TimeUnit.DAYS); - Date closingDate = faker.date().between(openingDate, dateEndOfYear); - Date returnDate = faker.date().between(openingDate, closingDate); - Date today = new Date(); - - part.setOpeningDate(openingDate); - part.setClosingDate(closingDate); - part.setReturnDate(returnDate); - setParts.add(part); - part.setCampaign(campaign); - partitioningRepository.save(part); - } - campaign.setSurvey(survey); - campaign.setPartitionings(setParts); - campaignRepository.save(campaign); - - } - survey.setSource(source); - survey.setCampaigns(setCampaigns); - surveyRepository.save(survey); - } - source.setSurveys(setSurveys); - sourceRepository.save(source); - ownerInsee.setSources(setSourcesInsee); - ownerAgri.setSources(setSourcesSsp); - ownerRepository.saveAll(Arrays.asList(new Owner[] { - ownerInsee, ownerAgri - })); - - supportInseeHdf.setSources(setSourcesSupportInsee); - supportSsne.setSources(setSourcesSupportSsne); - supportRepository.saveAll(Arrays.asList(new Support[] { - supportInseeHdf, supportSsne - })); - } - - } - - } - - private void initQuestionning(Faker faker, EasyRandom generator) { - - Long nbExistingQuestionings = questioningRepository.count(); - - LOGGER.info("{} questionings exist in database", nbExistingQuestionings); - - long start = System.currentTimeMillis(); - Questioning qu; - QuestioningEvent qe; - Set setQuestioning; - QuestioningAccreditation accreditation; - Set questioningAccreditations; - String fakeSiren; - Random qeRan = new Random(); - - LOGGER.info("{} survey units exist in database", surveyUnitRepository.count()); - - for (Long i = surveyUnitRepository.count(); i < 500000; i++) { - SurveyUnit su = new SurveyUnit(); - fakeSiren = RandomStringUtils.randomNumeric(9); - - su.setIdSu(fakeSiren); - su.setIdentificationName(faker.company().name()); - su.setIdentificationCode(fakeSiren); - surveyUnitRepository.save(su); - - } - for (Long i = nbExistingQuestionings; i < 500000; i++) { - qu = new Questioning(); - qe = new QuestioningEvent(); - List qeList = new ArrayList<>(); - questioningAccreditations = new HashSet<>(); - - setQuestioning = new HashSet<>(); - qu.setModelName("m" + RandomStringUtils.randomNumeric(2)); - qu.setIdPartitioning(partitioningRepository.findRandomPartitioning().getId()); - SurveyUnit su = surveyUnitRepository.findRandomSurveyUnit(); - qu.setSurveyUnit(su); - questioningRepository.save(qu); - setQuestioning.add(qu); - su.setQuestionings(setQuestioning); - - // questioning events - // everybody in INITLA - Optional part = partitioningRepository.findById(qu.getIdPartitioning()); - Date eventDate = faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()); - qe.setType(TypeQuestioningEvent.INITLA); - qe.setDate(eventDate); - qe.setQuestioning(qu); - qeList.add(qe); - - int qeProfile = qeRan.nextInt(10); - - switch (qeProfile) { - case 0: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.REFUSAL, qu)); - break; - case 1: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PND, qu)); - break; - case 2: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - break; - case 3: - case 4: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - case 5: - case 6: - case 7: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - } - - qeList.stream().forEach(questEvent -> questioningEventRepository.save(questEvent)); - - for (int j = 0; j < 4; j++) { - accreditation = new QuestioningAccreditation(); - accreditation.setIdContact(contactRepository.findRandomIdentifierContact()); - accreditation.setQuestioning(qu); - questioningAccreditations.add(accreditation); - questioningAccreditationRepository.save(accreditation); - } - qu.setQuestioningAccreditations(questioningAccreditations); - questioningRepository.save(qu); - if (i % 100 == 0) { - long end = System.currentTimeMillis(); - LOGGER.info("It took {}ms to execute save() for 100 questionings.", (end - start)); - start = System.currentTimeMillis(); - } - - } - } - - private void initQuestioningEvents(Faker faker, EasyRandom generator) { - - Long nbExistingQuestioningEvents = questioningEventRepository.count(); - - if (nbExistingQuestioningEvents == 0) { - List listQu = questioningRepository.findAll(); - Random qeRan = new Random(); - - for (Questioning qu : listQu) { - - QuestioningEvent qe = new QuestioningEvent(); - List qeList = new ArrayList<>(); - // questioning events - // everybody in INITLA - Optional part = partitioningRepository.findById(qu.getIdPartitioning()); - Date eventDate = faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()); - qe.setType(TypeQuestioningEvent.INITLA); - qe.setDate(eventDate); - qe.setQuestioning(qu); - qeList.add(qe); - - int qeProfile = qeRan.nextInt(10); - - switch (qeProfile) { - case 0: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.REFUSAL, qu)); - break; - case 1: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PND, qu)); - break; - case 2: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - break; - case 3: - case 4: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - case 5: - case 6: - case 7: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - } - - qeList.stream().forEach(questEvent -> questioningEventRepository.save(questEvent)); - - } - } - - } - - private void initView() { - if (viewRepository.count() == 0) { - - List listAccreditations = questioningAccreditationRepository.findAll(); - listAccreditations.stream().forEach(a -> { - Partitioning p = partitioningRepository.findById(a.getQuestioning().getIdPartitioning()).orElse(null); - View view = new View(); - view.setIdentifier(contactRepository.findById(a.getIdContact()).orElse(null).getIdentifier()); - view.setCampaignId(p.getCampaign().getId()); - view.setIdSu(a.getQuestioning().getSurveyUnit().getIdSu()); - viewRepository.save(view); - }); - - Iterable listContacts = contactRepository.findAll(); - for (Contact contact : listContacts) { - if (viewRepository.findByIdentifier(contact.getIdentifier()).isEmpty()) { - View view = new View(); - view.setIdentifier(contact.getIdentifier()); - viewRepository.save(view); - - } - } - } - } - -} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/util/DataloaderPoc.java b/src/main/java/fr/insee/survey/datacollectionmanagement/util/DataloaderPoc.java deleted file mode 100644 index 17045cbe..00000000 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/util/DataloaderPoc.java +++ /dev/null @@ -1,694 +0,0 @@ -package fr.insee.survey.datacollectionmanagement.util; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; - -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jeasy.random.EasyRandom; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; - -import com.github.javafaker.Animal; -import com.github.javafaker.Faker; -import com.github.javafaker.Name; - -import fr.insee.survey.datacollectionmanagement.contact.domain.Address; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; -import fr.insee.survey.datacollectionmanagement.contact.domain.Contact.Gender; -import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; -import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent.ContactEventType; -import fr.insee.survey.datacollectionmanagement.contact.repository.AddressRepository; -import fr.insee.survey.datacollectionmanagement.contact.repository.ContactEventRepository; -import fr.insee.survey.datacollectionmanagement.contact.repository.ContactRepository; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Owner; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Support; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; -import fr.insee.survey.datacollectionmanagement.metadata.repository.CampaignRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.OwnerRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.PartitioningRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SourceRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SupportRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SurveyRepository; -import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; -import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; -import fr.insee.survey.datacollectionmanagement.questioning.domain.EventOrder; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Operator; -import fr.insee.survey.datacollectionmanagement.questioning.domain.OperatorService; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnitAddress; -import fr.insee.survey.datacollectionmanagement.questioning.repository.EventOrderRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.OperatorRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.OperatorServiceRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningAccreditationRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningEventRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitAddressRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitRepository; -import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; -import fr.insee.survey.datacollectionmanagement.view.domain.View; -import fr.insee.survey.datacollectionmanagement.view.repository.ViewRepository; - -@Component -@Profile("poc") -public class DataloaderPoc { - - private static final Logger LOGGER = LogManager.getLogger(DataloaderPoc.class); - - @Autowired - private ContactRepository contactRepository; - - @Autowired - private AddressRepository addressRepository; - - @Autowired - private ContactEventRepository contactEventRepository; - - @Autowired - private OwnerRepository ownerRepository; - - @Autowired - private SupportRepository supportRepository; - - @Autowired - private SourceRepository sourceRepository; - - @Autowired - private SurveyRepository surveyRepository; - - @Autowired - private SurveyUnitRepository surveyUnitRepository; - - @Autowired - private SurveyUnitAddressRepository surveyUnitAddressRepository; - - @Autowired - private OperatorServiceRepository operatorServiceRepository; - - @Autowired - private OperatorRepository operatorRepository; - - @Autowired - private QuestioningRepository questioningRepository; - - @Autowired - private QuestioningAccreditationRepository questioningAccreditationRepository; - - @Autowired - private CampaignRepository campaignRepository; - - @Autowired - private PartitioningRepository partitioningRepository; - - @Autowired - private EventOrderRepository orderRepository; - - @Autowired - private QuestioningEventRepository questioningEventRepository; - - @Autowired - private ViewRepository viewRepository; - - @PostConstruct - public void init() { - - Faker faker = new Faker(); - EasyRandom generator = new EasyRandom(); - -// initOrder(); -// initContact(faker); -// initMetadata(faker, generator); - initQuestionning(faker, generator); - // initView(); - initSurveyUnitAddressAndOperators(faker); - - } - - private void initSurveyUnitAddressAndOperators(Faker faker) { - if (surveyUnitAddressRepository.count() == 0) { - for (SurveyUnit su : surveyUnitRepository.findAll()) { - SurveyUnitAddress a = new SurveyUnitAddress(); - com.github.javafaker.Address fakeAddress = faker.address(); - - a.setCountryName(fakeAddress.country()); - a.setStreetNumber(fakeAddress.buildingNumber()); - a.setStreetName(fakeAddress.streetName()); - a.setZipCode(fakeAddress.zipCode()); - a.setCityName(fakeAddress.cityName()); - su.setSurveyUnitAddress(a); - surveyUnitRepository.save(su); - } - } - - if (operatorServiceRepository.count() == 0) { - Set setOpConj = new HashSet<>(); - OperatorService operatorServiceConj = new OperatorService(); - operatorServiceConj.setName("Conjoncture"); - operatorServiceConj.setMail("conjoncture@Cocorico.fr"); - for (int i = 0; i < 9; i++) { - setOpConj.add(createOperator(faker)); - } - operatorServiceConj.setOperators(setOpConj); - operatorServiceRepository.save(operatorServiceConj); - - Set setOpLogement = new HashSet<>(); - OperatorService operatorServiceLogement = new OperatorService(); - operatorServiceLogement.setName("Logement"); - operatorServiceLogement.setMail("logement@Cocorico.fr"); - operatorServiceRepository.save(operatorServiceLogement); - for (int i = 0; i < 9; i++) { - setOpLogement.add(createOperator(faker)); - } - operatorServiceLogement.setOperators(setOpLogement); - operatorServiceRepository.save(operatorServiceLogement); - - Set setOpEmploi = new HashSet<>(); - OperatorService operatorServiceEmploi = new OperatorService(); - operatorServiceEmploi.setName("Emploi"); - operatorServiceEmploi.setMail("emploi@Cocorico.fr"); - operatorServiceRepository.save(operatorServiceEmploi); - for (int i = 0; i < 9; i++) { - setOpEmploi.add(createOperator(faker)); - } - operatorServiceEmploi.setOperators(setOpEmploi); - operatorServiceRepository.save(operatorServiceEmploi); - - Set setOpPrix = new HashSet<>(); - OperatorService operatorServicePrix = new OperatorService(); - operatorServicePrix.setName("Prix"); - operatorServicePrix.setMail("prix@Cocorico.fr"); - operatorServiceRepository.save(operatorServicePrix); - for (int i = 0; i < 9; i++) { - setOpPrix.add(createOperator(faker)); - } - operatorServicePrix.setOperators(setOpPrix); - operatorServiceRepository.save(operatorServicePrix); - } - - if (operatorServiceRepository.count() == 0) { - for (SurveyUnit su : surveyUnitRepository.findAll()) { - SurveyUnitAddress a = new SurveyUnitAddress(); - com.github.javafaker.Address fakeAddress = faker.address(); - - a.setCountryName(fakeAddress.country()); - a.setStreetNumber(fakeAddress.buildingNumber()); - a.setStreetName(fakeAddress.streetName()); - a.setZipCode(fakeAddress.zipCode()); - a.setCityName(fakeAddress.cityName()); - su.setSurveyUnitAddress(a); - surveyUnitRepository.save(su); - } - } - - } - - private Operator createOperator(Faker faker) { - Operator operator = new Operator(); - Name n = faker.name(); - String name = n.lastName(); - String firstName = n.firstName(); - operator.setLastName(name); - operator.setFirstName(firstName); - operator.setPhoneNumber(faker.phoneNumber().phoneNumber()); - return operatorRepository.save(operator); - } - - private void initOrder() { - - Long nbExistingOrders = orderRepository.count(); - LOGGER.info("{} orders in database", nbExistingOrders); - - if (nbExistingOrders == 0) { - // Creating table order - LOGGER.info("loading eventorder data"); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("8"), TypeQuestioningEvent.REFUSAL.toString(), 8)); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("7"), TypeQuestioningEvent.VALINT.toString(), 7)); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("6"), TypeQuestioningEvent.VALPAP.toString(), 6)); - orderRepository.saveAndFlush(new EventOrder(Long.parseLong("5"), TypeQuestioningEvent.HC.toString(), 5)); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("4"), TypeQuestioningEvent.PARTIELINT.toString(), 4)); - orderRepository.saveAndFlush(new EventOrder(Long.parseLong("3"), TypeQuestioningEvent.WASTE.toString(), 3)); - orderRepository.saveAndFlush(new EventOrder(Long.parseLong("2"), TypeQuestioningEvent.PND.toString(), 2)); - orderRepository - .saveAndFlush(new EventOrder(Long.parseLong("1"), TypeQuestioningEvent.INITLA.toString(), 1)); - } - } - - private void initContact(Faker faker) { - - List listContact = new ArrayList<>(); - List
listAddresses = new ArrayList<>(); - Long nbExistingContacts = contactRepository.count(); - - LOGGER.info("{} contacts exist in database", nbExistingContacts); - - int nbContacts = 1000000; - - for (Long i = nbExistingContacts; i < nbContacts; i++) { - long start = System.currentTimeMillis(); - - final Contact c = new Contact(); - final Address a = new Address(); - - Name n = faker.name(); - String name = n.lastName(); - String firstName = n.firstName(); - com.github.javafaker.Address fakeAddress = faker.address(); - - a.setCountryName(fakeAddress.country()); - a.setStreetNumber(fakeAddress.buildingNumber()); - a.setStreetName(fakeAddress.streetName()); - a.setZipCode(fakeAddress.zipCode()); - a.setCityName(fakeAddress.cityName()); - // addressRepository.save(a); - listAddresses.add(a); - - c.setIdentifier(RandomStringUtils.randomAlphanumeric(7).toUpperCase()); - c.setLastName(name); - c.setFirstName(firstName); - c.setPhone(faker.phoneNumber().phoneNumber()); - c.setGender(Gender.valueOf(faker.demographic().sex())); - c.setFunction(faker.job().title()); - c.setComment(faker.beer().name()); - c.setEmail(firstName.toLowerCase() + "." + name.toLowerCase() + "@cocorico.fr"); - c.setAddress(a); - listContact.add(c); - // contactRepository.save(c); - - if ((i + 1) % 10000 == 0) { - addressRepository.saveAll(listAddresses); - contactRepository.saveAll(listContact); - listAddresses = new ArrayList<>(); - listContact = new ArrayList<>(); - long end = System.currentTimeMillis(); - - // LOGGER.info("It took {}ms to execute save() for 100 contacts.", (end - - // start)); - - LOGGER.info("It took {}ms to execute saveAll() for 10000 contacts.", (end - start)); - } - - } - - Long nbContactEvents = contactEventRepository.count(); - - for (Long j = nbContactEvents; j < 300; j++) { - Contact contact = contactRepository.findRandomContact(); - ContactEvent contactEvent = new ContactEvent(); - contactEvent.setType(ContactEventType.create); - contactEvent.setEventDate(new Date()); - contactEvent.setContact(contact); - contactEventRepository.save(contactEvent); - Set setContactEvents = new HashSet<>(); - setContactEvents.add(contactEvent); - contact.setContactEvents(setContactEvents); - contactRepository.save(contact); - } - // addressRepository.saveAll(listAddresses); - // contactRepository.saveAll(listContact); - // long end = System.currentTimeMillis(); - // - // LOGGER.info("It took {}ms to execute save() for {} contacts.", (end - start), - // (nbContacts - nbExistingContacts)); - - // LOGGER.info("It took {}ms to execute saveAll() for {} contacts.", (end - - // start), (nbContacts - nbExistingContacts)); - - } - - private void initMetadata(Faker faker, EasyRandom generator2) { - - int year = 2023; - - Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.YEAR, year); - calendar.set(Calendar.MONTH, Calendar.DECEMBER); - calendar.set(Calendar.DAY_OF_MONTH, 31); - Date dateEndOfYear = calendar.getTime(); - - Owner ownerInsee = new Owner(); - ownerInsee.setId("insee"); - ownerInsee.setLabel("Insee"); - Set setSourcesInsee = new HashSet<>(); - - Owner ownerAgri = new Owner(); - ownerAgri.setId("agri"); - ownerAgri.setLabel("SSM Agriculture"); - Set setSourcesSsp = new HashSet<>(); - - Support supportInseeHdf = new Support(); - supportInseeHdf.setId("inseehdf"); - supportInseeHdf.setLabel("Insee Hauts-de-France"); - Set setSourcesSupportInsee = new HashSet<>(); - - Support supportSsne = new Support(); - supportSsne.setId("ssne"); - supportSsne.setLabel("Insee Normandie - SSNE"); - Set setSourcesSupportSsne = new HashSet<>(); - - LOGGER.info("{} campaigns exist in database", campaignRepository.count()); - - while (sourceRepository.count() < 10) { - - Source source = new Source(); - - String nameSource = "LOAD"+String.valueOf((char)(sourceRepository.count() + 'A')); - - if (!StringUtils.contains(nameSource, " ") && sourceRepository.findById(nameSource).isEmpty()) { - - source.setId(nameSource); - source.setLongWording("Have you ever heard about " + nameSource + " ?"); - source.setShortWording("Source about " + nameSource); - source.setPeriodicity(PeriodicityEnum.M); - sourceRepository.save(source); - Set setSurveys = new HashSet<>(); - Integer i = new Random().nextInt(); - if (i % 2 == 0) - setSourcesInsee.add(source); - else { - setSourcesSsp.add(source); - } - - for (int j = 0; j < 4; j++) { - - Survey survey = new Survey(); - String id = nameSource + (year - j); - survey.setId(id); - survey.setYear(year - j); - survey.setLongObjectives("The purpose of this survey is to find out everything you can about " - + nameSource - + ". Your response is essential to ensure the quality and reliability of the results of this survey."); - survey.setShortObjectives("All about " + id); - survey.setCommunication("Communication around " + id); - survey.setSpecimenUrl("http://specimenUrl/" + id); - survey.setDiffusionUrl("http://diffusion/" + id); - survey.setCnisUrl("http://cnis/" + id); - survey.setNoticeUrl("http://notice/" + id); - survey.setVisaNumber(year + RandomStringUtils.randomAlphanumeric(6).toUpperCase()); - survey.setLongWording("Survey " + nameSource + " " + (year - j)); - survey.setShortWording(id); - survey.setSampleSize(Integer.parseInt(RandomStringUtils.randomNumeric(5))); - setSurveys.add(survey); - surveyRepository.save(survey); - Set setCampaigns = new HashSet<>(); - - for (int k = 0; k < 12; k++) { - Campaign campaign = new Campaign(); - int month = k + 1; - String period = month<10? "M0" + month:"M"+month; - campaign.setYear(year - j); - campaign.setPeriod(PeriodEnum.valueOf(period)); - campaign.setId(nameSource + (year - j) + period); - campaign.setCampaignWording( - "Campaign about " + nameSource + " in " + (year - j) + " and period " + period); - setCampaigns.add(campaign); - campaignRepository.save(campaign); - Set setParts = new HashSet<>(); - - for (int l = 0; l < 3; l++) { - - Partitioning part = new Partitioning(); - part.setId(nameSource + (year - j) + "M" + month + "-00" + l); - Date openingDate = faker.date().past(90, 0, TimeUnit.DAYS); - Date closingDate = faker.date().between(openingDate, dateEndOfYear); - Date returnDate = faker.date().between(openingDate, closingDate); - Date today = new Date(); - - part.setOpeningDate(openingDate); - part.setClosingDate(closingDate); - part.setReturnDate(returnDate); - setParts.add(part); - part.setCampaign(campaign); - partitioningRepository.save(part); - } - campaign.setSurvey(survey); - campaign.setPartitionings(setParts); - campaignRepository.save(campaign); - - } - survey.setSource(source); - survey.setCampaigns(setCampaigns); - surveyRepository.save(survey); - } - source.setSurveys(setSurveys); - sourceRepository.save(source); - ownerInsee.setSources(setSourcesInsee); - ownerAgri.setSources(setSourcesSsp); - ownerRepository.saveAll(Arrays.asList(new Owner[] { - ownerInsee, ownerAgri - })); - - supportInseeHdf.setSources(setSourcesSupportInsee); - supportSsne.setSources(setSourcesSupportSsne); - supportRepository.saveAll(Arrays.asList(new Support[] { - supportInseeHdf, supportSsne - })); - } - - } - - } - - private void initQuestionning(Faker faker, EasyRandom generator) { - - Long nbExistingQuestionings = questioningRepository.count(); - - LOGGER.info("{} questionings exist in database", nbExistingQuestionings); - - long start = System.currentTimeMillis(); - Questioning qu; - QuestioningEvent qe; - Set setQuestioning; - QuestioningAccreditation accreditation; - Set questioningAccreditations; - String fakeSiren; - Random qeRan = new Random(); - - LOGGER.info("{} survey units exist in database", surveyUnitRepository.count()); - - for (Long i = surveyUnitRepository.count(); i < 500000; i++) { - SurveyUnit su = new SurveyUnit(); - fakeSiren = RandomStringUtils.randomNumeric(9); - - su.setIdSu(fakeSiren); - su.setIdentificationName(faker.company().name()); - su.setIdentificationCode(fakeSiren); - surveyUnitRepository.save(su); - - } - for (Long i = nbExistingQuestionings; i < 500000; i++) { - qu = new Questioning(); - qe = new QuestioningEvent(); - List qeList = new ArrayList<>(); - questioningAccreditations = new HashSet<>(); - - setQuestioning = new HashSet<>(); - qu.setModelName("m" + RandomStringUtils.randomNumeric(2)); - qu.setIdPartitioning(partitioningRepository.findRandomPartitioning().getId()); - SurveyUnit su = surveyUnitRepository.findRandomSurveyUnit(); - qu.setSurveyUnit(su); - questioningRepository.save(qu); - setQuestioning.add(qu); - su.setQuestionings(setQuestioning); - - // questioning events - // everybody in INITLA - Optional part = partitioningRepository.findById(qu.getIdPartitioning()); - Date eventDate = faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()); - qe.setType(TypeQuestioningEvent.INITLA); - qe.setDate(eventDate); - qe.setQuestioning(qu); - qeList.add(qe); - - int qeProfile = qeRan.nextInt(10); - - switch (qeProfile) { - case 0: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.REFUSAL, qu)); - break; - case 1: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PND, qu)); - break; - case 2: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - break; - case 3: - case 4: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - case 5: - case 6: - case 7: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - } - - qeList.stream().forEach(questEvent -> questioningEventRepository.save(questEvent)); - - for (int j = 0; j < 4; j++) { - accreditation = new QuestioningAccreditation(); - accreditation.setIdContact(contactRepository.findRandomIdentifierContact()); - accreditation.setQuestioning(qu); - questioningAccreditations.add(accreditation); - questioningAccreditationRepository.save(accreditation); - } - qu.setQuestioningAccreditations(questioningAccreditations); - questioningRepository.save(qu); - if (i % 100 == 0) { - long end = System.currentTimeMillis(); - LOGGER.info("It took {}ms to execute save() for 100 questionings.", (end - start)); - start = System.currentTimeMillis(); - } - - } - } - - private void initQuestioningEvents(Faker faker, EasyRandom generator) { - - Long nbExistingQuestioningEvents = questioningEventRepository.count(); - - if (nbExistingQuestioningEvents == 0) { - List listQu = questioningRepository.findAll(); - Random qeRan = new Random(); - - for (Questioning qu : listQu) { - - QuestioningEvent qe = new QuestioningEvent(); - List qeList = new ArrayList<>(); - // questioning events - // everybody in INITLA - Optional part = partitioningRepository.findById(qu.getIdPartitioning()); - Date eventDate = faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()); - qe.setType(TypeQuestioningEvent.INITLA); - qe.setDate(eventDate); - qe.setQuestioning(qu); - qeList.add(qe); - - int qeProfile = qeRan.nextInt(10); - - switch (qeProfile) { - case 0: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.REFUSAL, qu)); - break; - case 1: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PND, qu)); - break; - case 2: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - break; - case 3: - case 4: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.FOLLOWUP, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - case 5: - case 6: - case 7: - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.PARTIELINT, qu)); - qeList.add(new QuestioningEvent( - faker.date().between(part.get().getOpeningDate(), part.get().getClosingDate()), - TypeQuestioningEvent.VALINT, qu)); - break; - } - - qeList.stream().forEach(questEvent -> questioningEventRepository.save(questEvent)); - - } - } - - } - - private void initView() { - if (viewRepository.count() == 0) { - - List listAccreditations = questioningAccreditationRepository.findAll(); - listAccreditations.stream().forEach(a -> { - Partitioning p = partitioningRepository.findById(a.getQuestioning().getIdPartitioning()).orElse(null); - View view = new View(); - view.setIdentifier(contactRepository.findById(a.getIdContact()).orElse(null).getIdentifier()); - view.setCampaignId(p.getCampaign().getId()); - view.setIdSu(a.getQuestioning().getSurveyUnit().getIdSu()); - viewRepository.save(view); - }); - - Iterable listContacts = contactRepository.findAll(); - for (Contact contact : listContacts) { - if (viewRepository.findByIdentifier(contact.getIdentifier()).isEmpty()) { - View view = new View(); - view.setIdentifier(contact.getIdentifier()); - viewRepository.save(view); - - } - } - } - } - -} diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/view/domain/View.java b/src/main/java/fr/insee/survey/datacollectionmanagement/view/domain/View.java index b46c03f4..339948d4 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/view/domain/View.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/view/domain/View.java @@ -1,11 +1,7 @@ package fr.insee.survey.datacollectionmanagement.view.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.Table; +import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -23,7 +19,7 @@ public class View { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "view_seq") private Long id; @NonNull private String identifier; diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/view/repository/ViewRepository.java b/src/main/java/fr/insee/survey/datacollectionmanagement/view/repository/ViewRepository.java index d46b6587..e8d43b20 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/view/repository/ViewRepository.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/view/repository/ViewRepository.java @@ -1,15 +1,15 @@ package fr.insee.survey.datacollectionmanagement.view.repository; -import java.util.List; - +import fr.insee.survey.datacollectionmanagement.view.domain.View; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; -import fr.insee.survey.datacollectionmanagement.view.domain.View; +import java.util.List; @Repository -public interface ViewRepository extends PagingAndSortingRepository { +public interface ViewRepository extends PagingAndSortingRepository, JpaRepository { static final String FIND_DISTNCT_VIEW_BY_IDENTIFIER = "select " + " distinct on " @@ -40,4 +40,5 @@ public interface ViewRepository extends PagingAndSortingRepository { void deleteByIdentifier(String identifier); + } diff --git a/src/main/java/fr/insee/survey/datacollectionmanagement/view/serviceImpl/ViewServiceImpl.java b/src/main/java/fr/insee/survey/datacollectionmanagement/view/serviceImpl/ViewServiceImpl.java index fa9a2bce..707e8539 100644 --- a/src/main/java/fr/insee/survey/datacollectionmanagement/view/serviceImpl/ViewServiceImpl.java +++ b/src/main/java/fr/insee/survey/datacollectionmanagement/view/serviceImpl/ViewServiceImpl.java @@ -1,20 +1,19 @@ package fr.insee.survey.datacollectionmanagement.view.serviceImpl; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.view.domain.View; import fr.insee.survey.datacollectionmanagement.view.repository.ViewRepository; import fr.insee.survey.datacollectionmanagement.view.service.ViewService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; @Service +@RequiredArgsConstructor public class ViewServiceImpl implements ViewService { - @Autowired - private ViewRepository viewRepository; + private final ViewRepository viewRepository; @Override public List findViewByIdentifier(String identifier) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 06cf686d..0e52ee54 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -37,7 +37,7 @@ springdoc.swagger-ui.tagsSorter: alpha springdoc.swagger-ui.enabled=true -fr.insee.datacollectionmanagement.cors.allowedOrigin=* +fr.insee.datacollectionmanagement.cors.allowedOrigins=* #Actuator Metrics @@ -79,3 +79,5 @@ S # Questioning url fr.insee.datacollectionmanagement.api.questioning.url=http://localhost:8081 +fr.insee.datacollectionmanagement.public.urls=/swagger-ui/**,/swagger-ui.html,/v3/api-docs/**,/csrf, /,/webjars/**,/swagger-resources/**,/environnement,/healthcheck,/actuator/** + diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 00000000..a17f8c69 --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,11 @@ + + + ######## ## ### ######## #### ## ## ######## + ## ## ## ## ## ## ## ### ## ## + ## ## ## ## ## ## ## #### ## ## + ######## ## ## ## ## ## ## ## ## ###### + ## ## ######### ## ## ## #### ## + ## ## ## ## ## ## ## ### ## + ## ######## ## ## ## #### ## ## ######## + + diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/DatacollectionManagementApplicationTests.java b/src/test/java/fr/insee/survey/datacollectionmanagement/DatacollectionManagementApplicationTests.java index 4a3992de..36d8de69 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/DatacollectionManagementApplicationTests.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/DatacollectionManagementApplicationTests.java @@ -2,12 +2,14 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootTest +@EnableJpaRepositories class DatacollectionManagementApplicationTests { - @Test - void contextLoads() { - } + @Test + void contextLoads() { + } } diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/AddressControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/AddressControllerTest.java index 9548866c..859c8986 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/AddressControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/AddressControllerTest.java @@ -15,6 +15,7 @@ import org.springframework.http.MediaType; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.servlet.MockMvc; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -35,61 +36,61 @@ public class AddressControllerTest { @Autowired private ContactService contactService; - + @Autowired private AddressService addressService; @Test - public void getAddressOk() throws Exception { + void getAddressOk() throws Exception { String identifier = "CONT1"; - Contact contact = contactService.findByIdentifier(identifier).get(); + Contact contact = contactService.findByIdentifier(identifier); String json = createJsonAddress(contact); - this.mockMvc.perform(get(Constants.API_CONTACTS_ID_ADDRESS , identifier)).andDo(print()).andExpect(status().isOk()).andExpect(content().json(json, false)); + this.mockMvc.perform(get(Constants.API_CONTACTS_ID_ADDRESS, identifier)).andDo(print()).andExpect(status().isOk()).andExpect(content().json(json, false)); } @Test - public void getAddressContacttNotFound() throws Exception { + void getAddressContacttNotFound() throws Exception { String identifier = "CONT500"; - this.mockMvc.perform(get(Constants.API_CONTACTS_ID_ADDRESS , identifier)).andDo(print()).andExpect(status().is(HttpStatus.NOT_FOUND.value())); + this.mockMvc.perform(get(Constants.API_CONTACTS_ID_ADDRESS, identifier)).andDo(print()).andExpect(status().is(HttpStatus.NOT_FOUND.value())); } @Test - public void putAddressCreateUpdate() throws Exception { + void putAddressCreateUpdate() throws Exception { String identifier = "CONT5"; - Contact contact = contactService.findByIdentifier(identifier).get(); + Contact contact = contactService.findByIdentifier(identifier); Address addressBefore = contact.getAddress(); // Before: delete existing address contact.setAddress(null); contact = contactService.saveContact(contact); addressService.deleteAddressById(addressBefore.getId()); - - this.mockMvc.perform(get(Constants.API_CONTACTS_ID_ADDRESS , identifier)).andDo(print()).andExpect(status().is(HttpStatus.NOT_FOUND.value())); + + this.mockMvc.perform(get(Constants.API_CONTACTS_ID_ADDRESS, identifier)).andDo(print()).andExpect(status().is(HttpStatus.NOT_FOUND.value())); // Create address - status created Address addressCreated = initAddressMock(identifier); contact.setAddress(addressCreated); String jsonCreate = createJsonAddress(contact); - this.mockMvc.perform(put(Constants.API_CONTACTS_ID_ADDRESS , identifier).content(jsonCreate).contentType(MediaType.APPLICATION_JSON)).andDo(print()) - .andExpect(status().isCreated()).andExpect(content().json(jsonCreate.toString(), false)); - Contact contactAfterCreate = contactService.findByIdentifier(identifier).get(); + this.mockMvc.perform(put(Constants.API_CONTACTS_ID_ADDRESS, identifier).content(jsonCreate).contentType(MediaType.APPLICATION_JSON)).andDo(print()) + .andExpect(status().isCreated()).andExpect(content().json(jsonCreate.toString(), false)); + Contact contactAfterCreate = contactService.findByIdentifier(identifier); assertEquals(contactAfterCreate.getAddress().getCityName(), addressCreated.getCityName()); assertEquals(contactAfterCreate.getAddress().getStreetName(), addressCreated.getStreetName()); assertEquals(contactAfterCreate.getAddress().getCountryName(), addressCreated.getCountryName()); - + // Update address - status OK Address addressUpdated = initAddressMock("UPDATE"); contact.setAddress(addressUpdated); String jsonUpdate = createJsonAddress(contact); - this.mockMvc.perform(put(Constants.API_CONTACTS_ID_ADDRESS , identifier).content(jsonUpdate).contentType(MediaType.APPLICATION_JSON)).andDo(print()) - .andExpect(status().isOk()).andExpect(content().json(jsonUpdate.toString(), false)); - Contact contactAfterUpdate = contactService.findByIdentifier(identifier).get(); + this.mockMvc.perform(put(Constants.API_CONTACTS_ID_ADDRESS, identifier).content(jsonUpdate).contentType(MediaType.APPLICATION_JSON)).andDo(print()) + .andExpect(status().isOk()).andExpect(content().json(jsonUpdate.toString(), false)); + Contact contactAfterUpdate = contactService.findByIdentifier(identifier); assertEquals(contactAfterUpdate.getAddress().getCityName(), addressUpdated.getCityName()); assertEquals(contactAfterUpdate.getAddress().getStreetName(), addressUpdated.getStreetName()); assertEquals(contactAfterUpdate.getAddress().getCountryName(), addressUpdated.getCountryName()); - + // back to before contact.setAddress(addressBefore); addressService.saveAddress(addressBefore); @@ -97,7 +98,7 @@ public void putAddressCreateUpdate() throws Exception { assertEquals(contact.getAddress().getCityName(), addressBefore.getCityName()); assertEquals(contact.getAddress().getStreetName(), addressBefore.getStreetName()); assertEquals(contact.getAddress().getCountryName(), addressBefore.getCountryName()); - + } private Address initAddressMock(String identifier) { diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/ContactControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/ContactControllerTest.java index c9c1c370..9b173ca4 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/ContactControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/ContactControllerTest.java @@ -8,6 +8,8 @@ import fr.insee.survey.datacollectionmanagement.contact.repository.ContactRepository; import fr.insee.survey.datacollectionmanagement.contact.service.ContactEventService; import fr.insee.survey.datacollectionmanagement.contact.service.ContactService; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.util.JsonUtil; import org.json.JSONException; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -23,7 +25,7 @@ import java.util.ArrayList; import java.util.List; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -48,16 +50,16 @@ public class ContactControllerTest { private ContactRepository contactRepository; @Test - public void getContactOk() throws Exception { + void getContactOk() throws Exception { String identifier = "CONT1"; - Contact contact = contactService.findByIdentifier(identifier).get(); + Contact contact = contactService.findByIdentifier(identifier); String json = createJson(contact); this.mockMvc.perform(get(Constants.API_CONTACTS_ID, identifier)).andDo(print()).andExpect(status().isOk()) .andExpect(content().json(json, false)); } @Test - public void getContactNotFound() throws Exception { + void getContactNotFound() throws Exception { String identifier = "CONT500"; this.mockMvc.perform(get(Constants.API_CONTACTS_ID, identifier)).andDo(print()) .andExpect(status().is(HttpStatus.NOT_FOUND.value())); @@ -65,7 +67,7 @@ public void getContactNotFound() throws Exception { } @Test - public void getContactsOk() throws Exception { + void getContactsOk() throws Exception { JSONObject jo = new JSONObject(); jo.put("totalElements", contactRepository.count()); jo.put("numberOfElements", contactRepository.count()); @@ -75,64 +77,64 @@ public void getContactsOk() throws Exception { } @Test - public void putContactCreateUpdateDelete() throws Exception { + void putContactCreateUpdateDelete() throws Exception { String identifier = "TESTPUT"; // create contact - status created Contact contact = initContact(identifier); String jsonContact = createJson(contact); mockMvc.perform( - put(Constants.API_CONTACTS_ID, identifier).content(jsonContact).contentType(MediaType.APPLICATION_JSON)) + put(Constants.API_CONTACTS_ID, identifier).content(jsonContact).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(content().json(jsonContact.toString(), false)); - Contact contactFound = contactService.findByIdentifier(identifier).get(); + Contact contactFound = contactService.findByIdentifier(identifier); assertEquals(contact.getLastName(), contactFound.getLastName()); assertEquals(contact.getFirstName(), contactFound.getFirstName()); assertEquals(contact.getEmail(), contactFound.getEmail()); List list = new ArrayList<>(contactEventService.findContactEventsByContact(contactFound)); // List list = new ArrayList<>(contactFound.getContactEvents()); - assertEquals(list.size(), 1); - assertEquals(list.get(0).getType(), ContactEventType.create); + assertEquals(1, list.size()); + assertEquals(ContactEventType.create, list.get(0).getType()); // update contact - status ok contact.setLastName("lastNameUpdate"); String jsonContactUpdate = createJson(contact); mockMvc.perform(put(Constants.API_CONTACTS_ID, identifier).content(jsonContactUpdate) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(content().json(jsonContactUpdate.toString(), false)); - Contact contactFoundAfterUpdate = contactService.findByIdentifier(identifier).get(); + Contact contactFoundAfterUpdate = contactService.findByIdentifier(identifier); assertEquals("lastNameUpdate", contactFoundAfterUpdate.getLastName()); assertEquals(contact.getFirstName(), contactFoundAfterUpdate.getFirstName()); assertEquals(contact.getEmail(), contactFoundAfterUpdate.getEmail()); List listUpdate = new ArrayList<>( contactEventService.findContactEventsByContact(contactFoundAfterUpdate)); - assertEquals(listUpdate.size(), 2); - assertEquals(listUpdate.get(1).getType(), ContactEventType.update); + assertEquals(2, listUpdate.size()); + assertEquals(ContactEventType.update, listUpdate.get(1).getType()); // delete contact mockMvc.perform(delete(Constants.API_CONTACTS_ID, identifier).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()); - assertFalse(contactService.findByIdentifier(identifier).isPresent()); + assertThrows(NotFoundException.class, () -> contactService.findByIdentifier(identifier)); assertTrue(contactEventService.findContactEventsByContact(contactFoundAfterUpdate).isEmpty()); // delete contact not found - mockMvc.perform(delete("/contacts/" + identifier).contentType(MediaType.APPLICATION_JSON)) + mockMvc.perform(delete(Constants.API_CONTACTS + identifier).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); } @Test - public void putContactAddressCreateUpdateDelete() throws Exception { + void putContactAddressCreateUpdateDelete() throws Exception { String identifier = "TESTADDRESS"; // create contact - status created Contact contact = initContactAddress(identifier); String jsonContact = createJsonContactAddress(contact); mockMvc.perform( - put(Constants.API_CONTACTS_ID, identifier).content(jsonContact).contentType(MediaType.APPLICATION_JSON)) + put(Constants.API_CONTACTS_ID, identifier).content(jsonContact).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(content().json(jsonContact.toString(), false)); - Contact countactFound = contactService.findByIdentifier(identifier).get(); + Contact countactFound = contactService.findByIdentifier(identifier); assertEquals(contact.getAddress().getCityName(), countactFound.getAddress().getCityName()); // update contact - status ok @@ -140,28 +142,28 @@ public void putContactAddressCreateUpdateDelete() throws Exception { contact.getAddress().setCityName(newCityName); String jsonContactUpdate = createJsonContactAddress(contact); mockMvc.perform(put(Constants.API_CONTACTS_ID, identifier).content(jsonContactUpdate) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(content().json(jsonContactUpdate.toString(), false)); - Contact countactFoundAfterUpdate = contactService.findByIdentifier(identifier).get(); + Contact countactFoundAfterUpdate = contactService.findByIdentifier(identifier); assertEquals(contact.getAddress().getCityName(), countactFoundAfterUpdate.getAddress().getCityName()); // delete contact mockMvc.perform(delete(Constants.API_CONTACTS_ID, identifier).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()); - assertFalse(contactService.findByIdentifier(identifier).isPresent()); + assertThrows(NotFoundException.class, () -> contactService.findByIdentifier(identifier)); } @Test - public void putContactsErrorId() throws Exception { + void putContactsErrorId() throws Exception { String identifier = "NEWONE"; String otherIdentifier = "WRONG"; Contact contact = initContact(identifier); String jsonContact = createJson(contact); mockMvc.perform(put(Constants.API_CONTACTS_ID, otherIdentifier).content(jsonContact) - .contentType(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()) - .andExpect(content().string("id and contact identifier don't match")); + .andExpect(content().json(JsonUtil.createJsonErrorBadRequest("id and contact identifier don't match"), false)); } diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/ContactEventControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/ContactEventControllerTest.java index f40c4d55..1dbaa6cb 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/ContactEventControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/contacts/controller/ContactEventControllerTest.java @@ -28,23 +28,25 @@ public class ContactEventControllerTest { private MockMvc mockMvc; @Test - public void getContactEventOk() throws Exception { + void getContactEventOk() throws Exception { String identifier = "CONT1"; String json = createJsonContactEvent(identifier); - this.mockMvc.perform(get(Constants.API_CONTACTS_ID_CONTACTEVENTS,identifier)).andDo(print()).andExpect(status().isOk()) - .andExpect(content().json(json, false)); + this.mockMvc.perform(get(Constants.API_CONTACTS_ID_CONTACTEVENTS, identifier)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().json(json, false)); } @Test - public void getContactEventNotFound() throws Exception { + void getContactEventNotFound() throws Exception { String identifier = "CONT500"; - this.mockMvc.perform(get(Constants.API_CONTACTS_ID_CONTACTEVENTS,identifier)).andDo(print()) - .andExpect(status().is(HttpStatus.NOT_FOUND.value())); + this.mockMvc.perform(get(Constants.API_CONTACTS_ID_CONTACTEVENTS, identifier)).andDo(print()) + .andExpect(status().is(HttpStatus.NOT_FOUND.value())); } private String createJsonContactEvent(String identifier) throws JSONException { + //region Description JSONObject jo = new JSONObject(); + //endregion JSONObject joPayload = new JSONObject(); joPayload.put("contact_identifier", identifier); jo.put("payload", joPayload); diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/config/DataloaderTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderTest.java similarity index 88% rename from src/test/java/fr/insee/survey/datacollectionmanagement/config/DataloaderTest.java rename to src/test/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderTest.java index 30b17166..db45fa7c 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/config/DataloaderTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/dataloader/DataloaderTest.java @@ -1,31 +1,9 @@ -package fr.insee.survey.datacollectionmanagement.config; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.Year; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.annotation.PostConstruct; - -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; +package fr.insee.survey.datacollectionmanagement.dataloader; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.javafaker.Faker; - import fr.insee.survey.datacollectionmanagement.contact.domain.Address; import fr.insee.survey.datacollectionmanagement.contact.domain.Contact; import fr.insee.survey.datacollectionmanagement.contact.domain.ContactEvent; @@ -33,35 +11,31 @@ import fr.insee.survey.datacollectionmanagement.contact.repository.AddressRepository; import fr.insee.survey.datacollectionmanagement.contact.repository.ContactEventRepository; import fr.insee.survey.datacollectionmanagement.contact.repository.ContactRepository; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Owner; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; -import fr.insee.survey.datacollectionmanagement.metadata.repository.CampaignRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.OwnerRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.PartitioningRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SourceRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SupportRepository; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SurveyRepository; +import fr.insee.survey.datacollectionmanagement.metadata.domain.*; +import fr.insee.survey.datacollectionmanagement.metadata.repository.*; import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; -import fr.insee.survey.datacollectionmanagement.questioning.domain.EventOrder; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningEvent; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; -import fr.insee.survey.datacollectionmanagement.questioning.repository.EventOrderRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningAccreditationRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningEventRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.QuestioningRepository; -import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitRepository; +import fr.insee.survey.datacollectionmanagement.questioning.domain.*; +import fr.insee.survey.datacollectionmanagement.questioning.repository.*; import fr.insee.survey.datacollectionmanagement.questioning.util.TypeQuestioningEvent; +import fr.insee.survey.datacollectionmanagement.user.domain.User; +import fr.insee.survey.datacollectionmanagement.user.service.UserService; import fr.insee.survey.datacollectionmanagement.view.domain.View; import fr.insee.survey.datacollectionmanagement.view.repository.ViewRepository; +import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; -@Component +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +@Configuration @Profile("test") @Slf4j public class DataloaderTest { @@ -111,6 +85,9 @@ public class DataloaderTest { @Autowired private ViewRepository viewRepository; + @Autowired + private UserService userService; + @PostConstruct public void init() throws ParseException { @@ -121,7 +98,15 @@ public void init() throws ParseException { initMetadata(); initQuestionning(faker); initView(); + initUser(); + + } + private void initUser() { + User user = new User(); + user.setIdentifier("USER1"); + user.setRole(User.UserRoleType.ASSISTANCE); + userService.createUser(user, null); } private void initOrder() { @@ -218,7 +203,7 @@ private Contact createContact(int i) { private void initMetadata() throws ParseException { - int year = Year.now().getValue(); + int year = 2023; Owner ownerInsee = new Owner(); ownerInsee.setId("Insee"); @@ -306,8 +291,8 @@ private void initMetadata() throws ParseException { sourceRepository.save(source); log.info("Source created : " + source.toString()); ownerInsee.setSources(setSourcesInsee); - ownerRepository.saveAll(Arrays.asList(new Owner[] { - ownerInsee })); + ownerRepository.saveAll(Arrays.asList(new Owner[]{ + ownerInsee})); } } @@ -317,7 +302,7 @@ private void initMetadata() throws ParseException { private void initQuestionning(Faker faker) { Long nbExistingQuestionings = questioningRepository.count(); - int year = Year.now().getValue(); + int year = 2023; Date today = new Date(); Questioning qu; diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignControllerTest.java index c8cf8d20..7365f051 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/CampaignControllerTest.java @@ -4,12 +4,11 @@ import fr.insee.survey.datacollectionmanagement.constants.Constants; import fr.insee.survey.datacollectionmanagement.metadata.domain.Campaign; import fr.insee.survey.datacollectionmanagement.metadata.domain.Partitioning; -import fr.insee.survey.datacollectionmanagement.metadata.repository.CampaignRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.CampaignService; import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodEnum; +import fr.insee.survey.datacollectionmanagement.util.JsonUtil; +import net.minidev.json.JSONObject; import org.assertj.core.util.DateUtil; -import org.json.JSONException; -import org.json.JSONObject; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -17,15 +16,16 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; import java.util.Date; import java.util.HashSet; -import java.util.Optional; import java.util.Set; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -40,23 +40,11 @@ class CampaignControllerTest { @Autowired - private MockMvc mockMvc; + MockMvc mockMvc; @Autowired - private CampaignService campaignService; + CampaignService campaignService; - @Autowired - private CampaignRepository campaignRepository; - - @Test - void getCampaignOk() throws Exception { - String identifier = "SOURCE12023T01"; - Optional campaign = campaignService.findById(identifier); - assertTrue(campaign.isPresent()); - String json = createJson(campaign.get(), "SOURCE12023"); - this.mockMvc.perform(get(Constants.API_CAMPAIGNS_ID, identifier)).andDo(print()).andExpect(status().isOk()) - .andExpect(content().json(json, false)); - } @Test void getCampaignNotFound() throws Exception { @@ -73,14 +61,14 @@ void putCampaignsErrorId() throws Exception { String otherIdentifier = "WRONG"; Campaign campaign = initOpenedCampaign(identifier); String jsonCampaign = createJson(campaign, "SOURCE12023"); + String jsonError = JsonUtil.createJsonErrorBadRequest("id and idCampaign don't match"); mockMvc.perform(put(Constants.API_CAMPAIGNS_ID, otherIdentifier).content(jsonCampaign) .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isBadRequest()).andExpect(content().string("id and idCampaign don't match")); + .andExpect(status().isBadRequest()).andExpect(content().json(jsonError, false)); } @Test - @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) void isCampaignOnGoing() throws Exception { String identifier = "OPENED"; Campaign campaign = initOpenedCampaign(identifier); @@ -94,7 +82,6 @@ void isCampaignOnGoing() throws Exception { } @Test - @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) void isCampaignOnGoingClose() throws Exception { String identifier = "CLOSED"; Campaign campaign = initClosedCampaign(identifier); @@ -108,7 +95,6 @@ void isCampaignOnGoingClose() throws Exception { } @Test - @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) void isCampaignOnGoingFutureCampaignFalse() throws Exception { String identifier = "FUTURE"; Campaign campaign = initFutureCampaign(identifier); @@ -123,7 +109,6 @@ void isCampaignOnGoingFutureCampaignFalse() throws Exception { } @Test - @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) void isCampaignOnGoingEmptyCampaignFalse() throws Exception { String identifier = "EMPTY"; Campaign campaign = initEmptyCampaign(identifier); @@ -216,14 +201,14 @@ private String createJsonPart(Partitioning part) { JSONObject jo = new JSONObject(); jo.put("id", part.getId()); jo.put("campaignId", part.getCampaign().getId()); - jo.put("openingDate", part.getOpeningDate().toInstant()); - jo.put("closingDate", part.getClosingDate().toInstant()); - jo.put("returnDate", part.getClosingDate().toInstant()); + jo.put("openingDate", part.getOpeningDate().toInstant().toString()); + jo.put("closingDate", part.getClosingDate().toInstant().toString()); + jo.put("returnDate", part.getClosingDate().toInstant().toString()); jo.put("label", "label"); return jo.toString(); } - private String createJson(Campaign campaign, String idSurvey) throws JSONException { + private String createJson(Campaign campaign, String idSurvey) { JSONObject jo = new JSONObject(); jo.put("id", campaign.getId()); jo.put("year", campaign.getYear()); @@ -233,4 +218,18 @@ private String createJson(Campaign campaign, String idSurvey) throws JSONExcepti return jo.toString(); } + @Test + @Transactional + @Rollback + void getCampaignOk() throws Exception { + String identifier = "SOURCE12023T01"; + + assertDoesNotThrow(() -> campaignService.findById(identifier)); + Campaign campaign = campaignService.findById(identifier); + String json = createJson(campaign, "SOURCE12023"); + this.mockMvc.perform(get(Constants.API_CAMPAIGNS_ID, identifier)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().json(json, false)); + } + + } \ No newline at end of file diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SourceControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SourceControllerTest.java index f213c9c4..a779bb33 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SourceControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SourceControllerTest.java @@ -1,17 +1,12 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; -import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.Optional; - +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; +import fr.insee.survey.datacollectionmanagement.metadata.repository.SourceRepository; +import fr.insee.survey.datacollectionmanagement.metadata.service.SourceService; +import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; +import fr.insee.survey.datacollectionmanagement.util.JsonUtil; import org.json.JSONException; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -20,44 +15,41 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.metadata.domain.Source; -import fr.insee.survey.datacollectionmanagement.metadata.repository.SourceRepository; -import fr.insee.survey.datacollectionmanagement.metadata.service.SourceService; -import fr.insee.survey.datacollectionmanagement.metadata.util.PeriodicityEnum; +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @AutoConfigureMockMvc @SpringBootTest @ActiveProfiles("test") -public class SourceControllerTest { +class SourceControllerTest { @Autowired - private MockMvc mockMvc; + MockMvc mockMvc; @Autowired - private SourceService sourceService; + SourceService sourceService; @Autowired - private SourceRepository sourceRepository; + SourceRepository sourceRepository; - @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) @Test - public void getSourceOk() throws Exception { + void getSourceOk() throws Exception { String identifier = "SOURCE1"; - Optional source = sourceService.findById(identifier); - assertTrue(source.isPresent()); - String json = createJson(source.get()); + assertDoesNotThrow(() -> sourceService.findById(identifier)); + Source source = sourceService.findById(identifier); + String json = createJson(source); this.mockMvc.perform(get(Constants.API_SOURCES_ID, identifier)).andDo(print()).andExpect(status().isOk()) .andExpect(content().json(json, false)); } @Test - public void getSourceNotFound() throws Exception { + void getSourceNotFound() throws Exception { String identifier = "SOURCENOTFOUND"; this.mockMvc.perform(get(Constants.API_SOURCES_ID, identifier)).andDo(print()) .andExpect(status().is(HttpStatus.NOT_FOUND.value())); @@ -65,7 +57,7 @@ public void getSourceNotFound() throws Exception { } @Test - public void getSourcesOk() throws Exception { + void getSourcesOk() throws Exception { JSONObject jo = new JSONObject(); jo.put("totalElements", sourceRepository.count()); jo.put("numberOfElements", sourceRepository.count()); @@ -75,38 +67,39 @@ public void getSourcesOk() throws Exception { } @Test - public void putSourceCreateUpdateDelete() throws Exception { + void putSourceCreateUpdateDelete() throws Exception { String identifier = "SOURCEPUT"; // create source - status created Source source = initSource(identifier); String jsonSource = createJson(source); mockMvc.perform( - put(Constants.API_SOURCES_ID, identifier).content(jsonSource) - .contentType(MediaType.APPLICATION_JSON)) + put(Constants.API_SOURCES_ID, identifier).content(jsonSource) + .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(content().json(jsonSource.toString(), false)); - Optional sourceFound = sourceService.findById(identifier); - assertTrue(sourceFound.isPresent()); - assertEquals(source.getLongWording(), sourceFound.get().getLongWording()); - assertEquals(source.getShortWording(), sourceFound.get().getShortWording()); - assertEquals(source.getPeriodicity(), sourceFound.get().getPeriodicity()); + assertDoesNotThrow(() -> sourceService.findById(identifier)); + + Source sourceFound = sourceService.findById(identifier); + assertEquals(source.getLongWording(), sourceFound.getLongWording()); + assertEquals(source.getShortWording(), sourceFound.getShortWording()); + assertEquals(source.getPeriodicity(), sourceFound.getPeriodicity()); // update source - status ok source.setLongWording("Long wording update"); String jsonSourceUpdate = createJson(source); mockMvc.perform(put(Constants.API_SOURCES_ID, identifier).content(jsonSourceUpdate) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(content().json(jsonSourceUpdate.toString(), false)); - Optional sourceFoundAfterUpdate = sourceService.findById(identifier); - assertTrue(sourceFoundAfterUpdate.isPresent()); - assertEquals("Long wording update", sourceFoundAfterUpdate.get().getLongWording()); - assertEquals(source.getId(), sourceFoundAfterUpdate.get().getId()); + assertDoesNotThrow(() -> sourceService.findById(identifier)); + Source sourceFoundAfterUpdate = sourceService.findById(identifier); + assertEquals("Long wording update", sourceFoundAfterUpdate.getLongWording()); + assertEquals(source.getId(), sourceFoundAfterUpdate.getId()); // delete source mockMvc.perform(delete(Constants.API_SOURCES_ID, identifier).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()); - assertFalse(sourceService.findById(identifier).isPresent()); + assertThrows(NotFoundException.class, () -> sourceService.findById(identifier)); // delete source not found mockMvc.perform(delete(Constants.API_SOURCES + "/" + identifier).contentType(MediaType.APPLICATION_JSON)) @@ -115,14 +108,14 @@ public void putSourceCreateUpdateDelete() throws Exception { } @Test - public void putSourcesErrorId() throws Exception { + void putSourcesErrorId() throws Exception { String identifier = "NEWONE"; String otherIdentifier = "WRONG"; Source source = initSource(identifier); String jsonSource = createJson(source); mockMvc.perform(put(Constants.API_SOURCES + "/" + otherIdentifier).content(jsonSource) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isBadRequest()).andExpect(content().string("id and source id don't match")); + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()).andExpect(content().json(JsonUtil.createJsonErrorBadRequest("id and source id don't match"))); } diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SurveyControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SurveyControllerTest.java index 7b15a2e0..c9ec591d 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SurveyControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/metadata/controller/SurveyControllerTest.java @@ -1,9 +1,12 @@ package fr.insee.survey.datacollectionmanagement.metadata.controller; import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; import fr.insee.survey.datacollectionmanagement.metadata.domain.Survey; import fr.insee.survey.datacollectionmanagement.metadata.repository.SurveyRepository; import fr.insee.survey.datacollectionmanagement.metadata.service.SurveyService; +import fr.insee.survey.datacollectionmanagement.util.JsonUtil; + import org.json.JSONException; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -12,25 +15,23 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -import java.util.Optional; +import static org.junit.jupiter.api.Assertions.*; -import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + @AutoConfigureMockMvc @SpringBootTest @ActiveProfiles("test") -public class SurveyControllerTest { +class SurveyControllerTest { @Autowired private MockMvc mockMvc; @@ -41,19 +42,20 @@ public class SurveyControllerTest { @Autowired private SurveyRepository surveyRepository; - @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) + @Test - public void getSurveyOk() throws Exception { - String identifier = "SOURCE12023"; - Optional survey = surveyService.findById(identifier); - assertTrue(survey.isPresent()); - String json = createJson(survey.get(), "SOURCE1"); - this.mockMvc.perform(get(Constants.API_SURVEYS_ID, identifier)).andDo(print()).andExpect(status().isOk()) - .andExpect(content().json(json, false)); + void getSourcesOk() throws Exception { + JSONObject jo = new JSONObject(); + jo.put("totalElements", surveyRepository.count()); + jo.put("numberOfElements", surveyRepository.count()); + + this.mockMvc.perform(get(Constants.API_SURVEYS)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().json(jo.toString(), false)); + } @Test - public void getSurveyNotFound() throws Exception { + void getSurveyNotFound() throws Exception { String identifier = "SURVEYNOTFOUND"; this.mockMvc.perform(get(Constants.API_SURVEYS_ID, identifier)).andDo(print()) .andExpect(status().is(HttpStatus.NOT_FOUND.value())); @@ -61,40 +63,42 @@ public void getSurveyNotFound() throws Exception { } - @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) @Test - public void putSurveyCreateUpdateDelete() throws Exception { + void putSurveyCreateUpdateDelete() throws Exception { String identifier = "SURVEYPUT"; // create survey - status created Survey survey = initSurvey(identifier); String jsonSurvey = createJson(survey, "SOURCE1"); mockMvc.perform( - put(Constants.API_SURVEYS_ID, identifier).content(jsonSurvey) - .contentType(MediaType.APPLICATION_JSON)) + put(Constants.API_SURVEYS_ID, identifier).content(jsonSurvey) + .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(content().json(jsonSurvey.toString(), false)); - Optional surveyFound = surveyService.findById(identifier); - assertTrue(surveyFound.isPresent()); - assertEquals(survey.getLongWording(), surveyFound.get().getLongWording()); - assertEquals(survey.getShortWording(), surveyFound.get().getShortWording()); - assertEquals(survey.getSampleSize(), surveyFound.get().getSampleSize()); + + assertDoesNotThrow(() -> surveyService.findById(identifier)); + Survey surveyFound = surveyService.findById(identifier); + assertEquals(survey.getLongWording(), surveyFound.getLongWording()); + assertEquals(survey.getShortWording(), surveyFound.getShortWording()); + assertEquals(survey.getSampleSize(), surveyFound.getSampleSize()); // update survey - status ok survey.setLongWording("Long wording update"); - String jsonSurveyUpdate = createJson(survey,"SOURCE1"); + String jsonSurveyUpdate = createJson(survey, "SOURCE1"); mockMvc.perform(put(Constants.API_SURVEYS_ID, identifier).content(jsonSurveyUpdate) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(content().json(jsonSurveyUpdate.toString(), false)); - Optional surveyFoundAfterUpdate = surveyService.findById(identifier); - assertTrue(surveyFoundAfterUpdate.isPresent()); - assertEquals("Long wording update", surveyFoundAfterUpdate.get().getLongWording()); - assertEquals(survey.getId(), surveyFoundAfterUpdate.get().getId()); + assertDoesNotThrow(() -> surveyService.findById(identifier)); + Survey surveyFoundAfterUpdate = surveyService.findById(identifier); + + assertEquals("Long wording update", surveyFoundAfterUpdate.getLongWording()); + assertEquals(survey.getId(), surveyFoundAfterUpdate.getId()); // delete survey mockMvc.perform(delete(Constants.API_SURVEYS_ID, identifier).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()); - assertFalse(surveyService.findById(identifier).isPresent()); + + assertThrows(NotFoundException.class, () -> surveyService.findById(identifier)); // delete survey not found mockMvc.perform(delete(Constants.API_SURVEYS_ID, identifier).contentType(MediaType.APPLICATION_JSON)) @@ -103,14 +107,15 @@ public void putSurveyCreateUpdateDelete() throws Exception { } @Test - public void putSurveysErrorId() throws Exception { + void putSurveysErrorId() throws Exception { String identifier = "NEWONE"; String otherIdentifier = "WRONG"; Survey survey = initSurvey(identifier); String jsonSurvey = createJson(survey, "SOURCE1"); mockMvc.perform(put(Constants.API_SURVEYS_ID, otherIdentifier).content(jsonSurvey) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isBadRequest()).andExpect(content().string("id and idSurvey don't match")); + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()).andExpect(content().json(JsonUtil.createJsonErrorBadRequest("id and idSurvey don't match"))); + } @@ -135,4 +140,14 @@ private String createJson(Survey survey, String idSource) throws JSONException { return jo.toString(); } + @Test + void getSurveyOk() throws Exception { + String identifier = "SOURCE12022"; + assertDoesNotThrow(() -> surveyService.findById(identifier)); + Survey survey = surveyService.findById(identifier); + + String json = createJson(survey, "SOURCE1"); + this.mockMvc.perform(get(Constants.API_SURVEYS_ID, identifier)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().json(json, false)); + } } diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/CheckHabilitationControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/CheckHabilitationControllerTest.java index 9a41cf22..4c70a115 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/CheckHabilitationControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/CheckHabilitationControllerTest.java @@ -1,24 +1,13 @@ package fr.insee.survey.datacollectionmanagement.query.controller; -import static org.hamcrest.Matchers.containsString; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.junit.jupiter.api.Test; +import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; - @AutoConfigureMockMvc @SpringBootTest @ActiveProfiles("test") diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/MoogControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/MoogControllerTest.java index daa0052e..b34a4de8 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/MoogControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/MoogControllerTest.java @@ -17,9 +17,9 @@ @AutoConfigureMockMvc @SpringBootTest -@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ActiveProfiles("test") -public class MoogControllerTest { +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class MoogControllerTest { @Autowired private MockMvc mockMvc; @@ -28,25 +28,26 @@ public class MoogControllerTest { private MoogService moogService; @Test - public void getMoogReadOnlyUrl() throws Exception { - String idCampaign= "SOURCE12024T01"; - String surveyUnitId= "100000000"; - this.mockMvc.perform(get(Constants.MOOG_API_READONLY_URL, idCampaign,surveyUnitId)).andDo(print()).andExpect(status().isOk()) + void getMoogReadOnlyUrl() throws Exception { + String idCampaign = "SOURCE12023T01"; + String surveyUnitId = "100000000"; + this.mockMvc.perform(get(Constants.MOOG_API_READONLY_URL, idCampaign, surveyUnitId)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().string("http://localhost:8081/readonly/questionnaire/m0/unite-enquetee/100000000")); } @Test - public void getMoogReadOnlyUrlCampaignNotFound() throws Exception { - String idCampaign= "SOURCE12023T00"; - String surveyUnitId= "100000000"; - this.mockMvc.perform(get(Constants.MOOG_API_READONLY_URL, idCampaign,surveyUnitId)).andDo(print()).andExpect(status().isNotFound()); + void getMoogReadOnlyUrlCampaignNotFound() throws Exception { + String idCampaign = "CAMPAIGN"; + String surveyUnitId = "100000000"; + this.mockMvc.perform(get(Constants.MOOG_API_READONLY_URL, idCampaign, surveyUnitId)).andDo(print()).andExpect(status().isNotFound()); } @Test - public void getMoogReadOnlyUrlQuestioningNotFound() throws Exception { - String idCampaign= "SOURCE12023T01"; - String surveyUnitId= "10"; - this.mockMvc.perform(get(Constants.MOOG_API_READONLY_URL, idCampaign,surveyUnitId)).andDo(print()).andExpect(status().isNotFound()); + void getMoogReadOnlyUrlQuestioningNotFound() throws Exception { + String idCampaign = "SOURCE12023T01"; + String surveyUnitId = "SU"; + this.mockMvc.perform(get(Constants.MOOG_API_READONLY_URL, idCampaign, surveyUnitId)).andDo(print()).andExpect(status().isNotFound()); } } diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/MyQuestioningsControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/MyQuestioningsControllerTest.java index d3217b98..2945d8fd 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/MyQuestioningsControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/query/controller/MyQuestioningsControllerTest.java @@ -1,33 +1,29 @@ package fr.insee.survey.datacollectionmanagement.query.controller; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.stream.Stream; - +import com.fasterxml.jackson.databind.ObjectMapper; +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.query.dto.MyQuestioningDto; +import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; -import com.fasterxml.jackson.databind.ObjectMapper; - -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.query.dto.MyQuestioningDto; -import fr.insee.survey.datacollectionmanagement.query.service.CheckHabilitationService; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @AutoConfigureMockMvc @SpringBootTest @ActiveProfiles("test") -public class MyQuestioningsControllerTest { +@ContextConfiguration +class MyQuestioningsControllerTest { @Autowired private MockMvc mockMvc; @@ -36,7 +32,7 @@ public class MyQuestioningsControllerTest { private CheckHabilitationService checkAccreditationService; // @Test -// public void myQuestionings() throws Exception { +// void myQuestionings() throws Exception { // String identifier = "CONT2"; // // MvcResult result = this.mockMvc.perform(get(Constants.API_MY_QUESTIONINGS_ID, identifier)).andDo(print()) @@ -56,7 +52,7 @@ public class MyQuestioningsControllerTest { // } @Test - public void myQuestioningsContactNotExist() throws Exception { + void myQuestioningsContactNotExist() throws Exception { String identifier = "CONT500"; MvcResult result = this.mockMvc.perform(get(Constants.API_MY_QUESTIONINGS_ID, identifier)).andDo(print()) diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningAccreditationControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningAccreditationControllerTest.java index b68255d1..59da0593 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningAccreditationControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningAccreditationControllerTest.java @@ -1,15 +1,9 @@ package fr.insee.survey.datacollectionmanagement.questioning.controller; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.Set; -import java.util.stream.Collectors; - +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; +import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -19,20 +13,23 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; -import fr.insee.survey.datacollectionmanagement.questioning.domain.QuestioningAccreditation; -import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @AutoConfigureMockMvc @SpringBootTest @ActiveProfiles("test") -@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) -public class QuestionningAccreditationControllerTest { +class QuestionningAccreditationControllerTest { @Autowired private MockMvc mockMvc; @@ -41,15 +38,16 @@ public class QuestionningAccreditationControllerTest { private QuestioningService questioningService; @Test - public void getQuestioningAccreditationOk() throws Exception { - String identifier = "83"; + void getQuestioningAccreditationOk() throws Exception { + Questioning questioning = questioningService.findBySurveyUnitIdSu("100000001").stream().findFirst().get(); + Long identifier = questioning.getQuestioningAccreditations().stream().findFirst().get().getId(); String json = createJsonQuestioningAcreditation(identifier); this.mockMvc.perform(get(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, identifier)).andDo(print()).andExpect(status().isOk()) .andExpect(content().json(json, false)); } @Test - public void getQuestioningAccreditationNotFound() throws Exception { + void getQuestioningAccreditationNotFound() throws Exception { String identifier = "300"; this.mockMvc.perform(get(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, identifier)).andDo(print()) .andExpect(status().is(HttpStatus.NOT_FOUND.value())); @@ -57,47 +55,49 @@ public void getQuestioningAccreditationNotFound() throws Exception { } @Test - public void postAccreditationQuestioningNotFound() throws Exception { - int idQuestioning = 1000; + void postAccreditationQuestioningNotFound() throws Exception { + int idQuestioning = 10000; String idContact = "CONT1"; // create contact - status created QuestioningAccreditation accreditation = initAccreditation(idContact); String jsonAccreditation = createJson(accreditation); mockMvc.perform( - post(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, idQuestioning) - .content(jsonAccreditation).contentType(MediaType.APPLICATION_JSON)) + post(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, idQuestioning) + .content(jsonAccreditation).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); } @Test - public void postAccreditationContactNotFound() throws Exception { - int idQuestioning = 12; + void postAccreditationContactNotFound() throws Exception { + Questioning q = questioningService.findByIdPartitioning("SOURCE12023T1000").stream().findFirst().get(); + Long idQuestioning = q.getId(); String idContact = "CONT7500"; // create contact - status created QuestioningAccreditation accreditation = initAccreditation(idContact); String jsonAccreditation = createJson(accreditation); mockMvc.perform( - post(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, idQuestioning) - .content(jsonAccreditation).contentType(MediaType.APPLICATION_JSON)) + post(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, idQuestioning) + .content(jsonAccreditation).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); } @Test - public void postAccreditationCreateUpdate() throws Exception { - int idQuestioning = 11; + void postAccreditationCreateUpdate() throws Exception { + Questioning q = questioningService.findByIdPartitioning("SOURCE12023T1000").stream().findFirst().get(); + Long idQuestioning = q.getId(); String idContact = "CONT5"; // create accreditation - status created QuestioningAccreditation accreditation = initAccreditation(idContact); String jsonAccreditation = createJson(accreditation); mockMvc.perform( - post(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, idQuestioning) - .content(jsonAccreditation).contentType(MediaType.APPLICATION_JSON)) + post(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, idQuestioning) + .content(jsonAccreditation).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(content().json(jsonAccreditation.toString(), false)); - Questioning questioning = questioningService.findbyId((long) idQuestioning).get(); + Questioning questioning = questioningService.findbyId((long) idQuestioning); Set setAccreditationFound = questioning.getQuestioningAccreditations(); QuestioningAccreditation accreditationFound = setAccreditationFound.stream() .filter(acc -> acc.getIdContact().equals(idContact)) @@ -109,14 +109,14 @@ public void postAccreditationCreateUpdate() throws Exception { accreditation.setMain(true); String jsonAccreditationUpdate = createJson(accreditation); mockMvc.perform( - post(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, idQuestioning) - .content(jsonAccreditationUpdate).contentType(MediaType.APPLICATION_JSON)) + post(Constants.API_QUESTIONINGS_ID_QUESTIONING_ACCREDITATIONS, idQuestioning) + .content(jsonAccreditationUpdate).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().json(jsonAccreditationUpdate.toString(), false)); - QuestioningAccreditation accreditationFoundAfterUpdate = questioningService.findbyId((long) idQuestioning).get() + QuestioningAccreditation accreditationFoundAfterUpdate = questioningService.findbyId((long) idQuestioning) .getQuestioningAccreditations().stream().filter(acc -> acc.getIdContact().equals(idContact)) - .collect(Collectors.toList()).get(0); + .toList().get(0); assertEquals(true, accreditationFoundAfterUpdate.isMain()); } @@ -137,7 +137,7 @@ private String createJson(QuestioningAccreditation accreditation) throws JSONExc return jo.toString(); } - private String createJsonQuestioningAcreditation(String identifier) throws JSONException { + private String createJsonQuestioningAcreditation(Long identifier) throws JSONException { JSONObject jo1 = new JSONObject(); jo1.put("idContact", "CONT1"); diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningControllerTest.java index 6e2553fd..380ab2f5 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningControllerTest.java @@ -1,10 +1,8 @@ package fr.insee.survey.datacollectionmanagement.questioning.controller; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -13,31 +11,35 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -import fr.insee.survey.datacollectionmanagement.constants.Constants; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @AutoConfigureMockMvc @SpringBootTest @ActiveProfiles("test") -@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) -public class QuestionningControllerTest { +class QuestionningControllerTest { + @Autowired + QuestioningService questioningService; @Autowired private MockMvc mockMvc; @Test - public void getQuestioningOk() throws Exception { - int id = 11; + void getQuestioningOk() throws Exception { + Questioning questioning = questioningService.findBySurveyUnitIdSu("100000001").stream().findFirst().get(); + Long id = questioning.getQuestioningAccreditations().stream().findFirst().get().getId(); String json = createJson(id).toString(); this.mockMvc.perform(get(Constants.API_QUESTIONINGS_ID, id)).andDo(print()).andExpect(status().isOk()) .andExpect(content().json(json, false)); } @Test - public void getQuestioningNotFound() throws Exception { + void getQuestioningNotFound() throws Exception { String id = "300"; this.mockMvc.perform(get(Constants.API_QUESTIONINGS_ID, id)).andDo(print()) .andExpect(status().is(HttpStatus.NOT_FOUND.value())); @@ -45,7 +47,7 @@ public void getQuestioningNotFound() throws Exception { } @Test - public void getQuestioningsBySurveyUnit() throws Exception { + void getQuestioningsBySurveyUnit() throws Exception { String idSu = "100000000"; String json = createJsonQuestionings(idSu); this.mockMvc.perform(get(Constants.API_SURVEY_UNITS_ID_QUESTIONINGS, idSu)).andDo(print()) @@ -54,7 +56,7 @@ public void getQuestioningsBySurveyUnit() throws Exception { } - private JSONObject createJson(int id) throws JSONException { + private JSONObject createJson(Long id) throws JSONException { JSONObject jo = new JSONObject(); jo.put("id", id); return jo; diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningEventControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningEventControllerTest.java index 6606ce1f..5433d7e8 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningEventControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/QuestionningEventControllerTest.java @@ -1,10 +1,8 @@ package fr.insee.survey.datacollectionmanagement.questioning.controller; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.questioning.domain.Questioning; +import fr.insee.survey.datacollectionmanagement.questioning.service.QuestioningService; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -13,38 +11,42 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -import fr.insee.survey.datacollectionmanagement.constants.Constants; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @AutoConfigureMockMvc @SpringBootTest @ActiveProfiles("test") -@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) -public class QuestionningEventControllerTest { +class QuestionningEventControllerTest { + @Autowired + QuestioningService questioningService; @Autowired private MockMvc mockMvc; @Test - public void getQuestioningEventOk() throws Exception { - String identifier = "11"; - String json = createJsonQuestioningEvent(identifier); - this.mockMvc.perform(get(Constants.API_QUESTIONING_ID_QUESTIONING_EVENTS,identifier)).andDo(print()).andExpect(status().isOk()) + void getQuestioningEventOk() throws Exception { + Questioning questioning = questioningService.findBySurveyUnitIdSu("100000001").stream().findFirst().get(); + Long id = questioning.getQuestioningAccreditations().stream().findFirst().get().getId(); + String json = createJsonQuestioningEvent(id); + this.mockMvc.perform(get(Constants.API_QUESTIONING_ID_QUESTIONING_EVENTS, id)).andDo(print()).andExpect(status().isOk()) .andExpect(content().json(json, false)); } @Test - public void getQuestioningEventNotFound() throws Exception { + void getQuestioningEventNotFound() throws Exception { String identifier = "300"; - this.mockMvc.perform(get(Constants.API_QUESTIONING_ID_QUESTIONING_EVENTS,identifier)).andDo(print()) + this.mockMvc.perform(get(Constants.API_QUESTIONING_ID_QUESTIONING_EVENTS, identifier)).andDo(print()) .andExpect(status().is(HttpStatus.NOT_FOUND.value())); } - private String createJsonQuestioningEvent(String identifier) throws JSONException { + private String createJsonQuestioningEvent(Long identifier) throws JSONException { JSONObject joEventInitla = new JSONObject(); joEventInitla.put("type", "INITLA"); diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/SurveyUnitControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/SurveyUnitControllerTest.java index 94f80749..b89e1dd1 100644 --- a/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/SurveyUnitControllerTest.java +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/questioning/controller/SurveyUnitControllerTest.java @@ -1,13 +1,12 @@ package fr.insee.survey.datacollectionmanagement.questioning.controller; -import static org.junit.Assert.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; +import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnitAddress; +import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitRepository; +import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; +import fr.insee.survey.datacollectionmanagement.util.JsonUtil; import org.json.JSONException; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -16,21 +15,21 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -import fr.insee.survey.datacollectionmanagement.constants.Constants; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnit; -import fr.insee.survey.datacollectionmanagement.questioning.domain.SurveyUnitAddress; -import fr.insee.survey.datacollectionmanagement.questioning.repository.SurveyUnitRepository; -import fr.insee.survey.datacollectionmanagement.questioning.service.SurveyUnitService; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @AutoConfigureMockMvc @SpringBootTest @ActiveProfiles("test") -@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) -public class SurveyUnitControllerTest { +class SurveyUnitControllerTest { @Autowired private MockMvc mockMvc; @@ -42,16 +41,16 @@ public class SurveyUnitControllerTest { private SurveyUnitRepository surveyUnitRepository; @Test - public void getSurveyUnitOk() throws Exception { + void getSurveyUnitOk() throws Exception { String identifier = "100000000"; - SurveyUnit surveyUnit = surveyUnitService.findbyId(identifier).get(); + SurveyUnit surveyUnit = surveyUnitService.findbyId(identifier); String json = createJson(surveyUnit); this.mockMvc.perform(get(Constants.API_SURVEY_UNITS_ID, identifier)).andDo(print()).andExpect(status().isOk()) .andExpect(content().json(json, false)); } @Test - public void getSurveyUnitNotFound() throws Exception { + void getSurveyUnitNotFound() throws Exception { String identifier = "900000000"; this.mockMvc.perform(get(Constants.API_SURVEY_UNITS_ID, identifier)).andDo(print()) .andExpect(status().is(HttpStatus.NOT_FOUND.value())); @@ -59,7 +58,7 @@ public void getSurveyUnitNotFound() throws Exception { } @Test - public void getSurveyUnitsOk() throws Exception { + void getSurveyUnitsOk() throws Exception { JSONObject jo = new JSONObject(); jo.put("totalElements", surveyUnitRepository.count()); jo.put("numberOfElements", surveyUnitRepository.count()); @@ -69,18 +68,18 @@ public void getSurveyUnitsOk() throws Exception { } @Test - public void putSurveyUnitCreateUpdateDelete() throws Exception { + void putSurveyUnitCreateUpdateDelete() throws Exception { String identifier = "TESTPUT"; // create surveyUnit - status created SurveyUnit surveyUnit = initSurveyUnit(identifier); String jsonSurveyUnit = createJson(surveyUnit); mockMvc.perform( - put(Constants.API_SURVEY_UNITS_ID, identifier).content(jsonSurveyUnit) - .contentType(MediaType.APPLICATION_JSON)) + put(Constants.API_SURVEY_UNITS_ID, identifier).content(jsonSurveyUnit) + .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(content().json(jsonSurveyUnit.toString(), false)); - SurveyUnit surveyUnitFound = surveyUnitService.findbyId(identifier).get(); + SurveyUnit surveyUnitFound = surveyUnitService.findbyId(identifier); assertEquals(surveyUnit.getIdSu(), surveyUnitFound.getIdSu()); assertEquals(surveyUnit.getIdentificationCode(), surveyUnitFound.getIdentificationCode()); assertEquals(surveyUnit.getIdentificationName(), surveyUnitFound.getIdentificationName()); @@ -89,33 +88,33 @@ public void putSurveyUnitCreateUpdateDelete() throws Exception { surveyUnit.setIdentificationName("identificationNameUpdate"); String jsonSurveyUnitUpdate = createJson(surveyUnit); mockMvc.perform(put(Constants.API_SURVEY_UNITS_ID, identifier).content(jsonSurveyUnitUpdate) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(content().json(jsonSurveyUnitUpdate.toString(), false)); - SurveyUnit surveyUnitFoundAfterUpdate = surveyUnitService.findbyId(identifier).get(); + SurveyUnit surveyUnitFoundAfterUpdate = surveyUnitService.findbyId(identifier); assertEquals("identificationNameUpdate", surveyUnitFoundAfterUpdate.getIdentificationName()); assertEquals(surveyUnit.getIdSu(), surveyUnitFoundAfterUpdate.getIdSu()); assertEquals(surveyUnit.getIdentificationName(), surveyUnitFoundAfterUpdate.getIdentificationName()); // delete surveyUnit surveyUnitService.deleteSurveyUnit(identifier); - assertFalse( - surveyUnitService.findbyId(identifier).isPresent()); + assertThrows(NotFoundException.class, () -> surveyUnitService.findbyId(identifier)); + } @Test - public void putSurveyUnitAddressCreateUpdateDelete() throws Exception { + void putSurveyUnitAddressCreateUpdateDelete() throws Exception { String identifier = "TESTADDRESS"; // create surveyUnit - status created SurveyUnit surveyUnit = initSurveyUnitAddress(identifier); String jsonSurveyUnit = createJsonSurveyUnitAddress(surveyUnit); mockMvc.perform( - put(Constants.API_SURVEY_UNITS_ID, identifier).content(jsonSurveyUnit) - .contentType(MediaType.APPLICATION_JSON)) + put(Constants.API_SURVEY_UNITS_ID, identifier).content(jsonSurveyUnit) + .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(content().json(jsonSurveyUnit.toString(), false)); - SurveyUnit suFound = surveyUnitService.findbyId(identifier).get(); + SurveyUnit suFound = surveyUnitService.findbyId(identifier); assertEquals(surveyUnit.getSurveyUnitAddress().getCityName(), suFound.getSurveyUnitAddress().getCityName()); // update surveyUnit - status ok @@ -123,28 +122,28 @@ public void putSurveyUnitAddressCreateUpdateDelete() throws Exception { surveyUnit.getSurveyUnitAddress().setCityName(newCityName); String jsonSurveyUnitUpdate = createJsonSurveyUnitAddress(surveyUnit); mockMvc.perform(put(Constants.API_SURVEY_UNITS_ID, identifier).content(jsonSurveyUnitUpdate) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(content().json(jsonSurveyUnitUpdate.toString(), false)); - SurveyUnit countactFoundAfterUpdate = surveyUnitService.findbyId(identifier).get(); + SurveyUnit countactFoundAfterUpdate = surveyUnitService.findbyId(identifier); assertEquals(surveyUnit.getSurveyUnitAddress().getCityName(), countactFoundAfterUpdate.getSurveyUnitAddress().getCityName()); // delete surveyUnit surveyUnitService.deleteSurveyUnit(identifier); - assertFalse(surveyUnitService.findbyId(identifier).isPresent()); + assertThrows(NotFoundException.class, () -> surveyUnitService.findbyId(identifier)); } @Test - public void putSurveyUnitsErrorId() throws Exception { + void putSurveyUnitsErrorId() throws Exception { String identifier = "NEWONE"; String otherIdentifier = "WRONG"; SurveyUnit surveyUnit = initSurveyUnit(identifier); String jsonSurveyUnit = createJson(surveyUnit); mockMvc.perform(put(Constants.API_SURVEY_UNITS_ID, otherIdentifier).content(jsonSurveyUnit) - .contentType(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()) - .andExpect(content().string("id and idSu don't match")); + .andExpect(content().json(JsonUtil.createJsonErrorBadRequest("id and idSu don't match"))); } diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserControllerTest.java new file mode 100644 index 00000000..2157a7f0 --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserControllerTest.java @@ -0,0 +1,148 @@ +package fr.insee.survey.datacollectionmanagement.user.controller.controller; + +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.exception.NotFoundException; +import fr.insee.survey.datacollectionmanagement.user.domain.User; +import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent; +import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent.UserEventType; +import fr.insee.survey.datacollectionmanagement.user.repository.UserRepository; +import fr.insee.survey.datacollectionmanagement.user.service.UserEventService; +import fr.insee.survey.datacollectionmanagement.user.service.UserService; +import fr.insee.survey.datacollectionmanagement.util.JsonUtil; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +@SpringBootTest +@ActiveProfiles("test") +class UserControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private UserService userService; + + @Autowired + private UserEventService userEventService; + + @Autowired + private UserRepository userRepository; + + @Test + void getUserNotFound() throws Exception { + String identifier = "CONT500"; + this.mockMvc.perform(get(Constants.API_USERS_ID, identifier)).andDo(print()) + .andExpect(status().is(HttpStatus.NOT_FOUND.value())); + + } + + @Test + void getUserOk() throws Exception { + String identifier = "USER1"; + this.mockMvc.perform(get(Constants.API_USERS_ID, identifier)).andDo(print()) + .andExpect(status().is(HttpStatus.OK.value())); + + } + + @Test + void getUsersOk() throws Exception { + JSONObject jo = new JSONObject(); + jo.put("totalElements", userRepository.count()); + jo.put("numberOfElements", userRepository.count()); + + this.mockMvc.perform(get(Constants.API_USERS_ALL)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().json(jo.toString(), false)); + } + + @Test + void putUserCreateUpdateDelete() throws Exception { + String identifier = "TESTPUT"; + + // create user - status created + User user = initGestionnaire(identifier); + String jsonUser = createJson(user); + mockMvc.perform( + put(Constants.API_USERS_ID, identifier).content(jsonUser).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andExpect(content().json(jsonUser.toString(), false)); + assertDoesNotThrow(() -> userService.findByIdentifier(identifier)); + User userFound = userService.findByIdentifier(identifier); + assertEquals(user.getIdentifier(), userFound.getIdentifier()); + assertEquals(user.getRole(), userFound.getRole()); + + // update user - status ok + user.setRole(User.UserRoleType.ASSISTANCE); + String jsonUserUpdate = createJson(user); + mockMvc.perform(put(Constants.API_USERS_ID, identifier).content(jsonUserUpdate) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andExpect(content().json(jsonUserUpdate.toString(), false)); + User userFoundAfterUpdate = userService.findByIdentifier(identifier); + assertEquals(User.UserRoleType.ASSISTANCE, userFoundAfterUpdate.getRole()); + List listUpdate = new ArrayList<>( + userEventService.findUserEventsByUser(userFoundAfterUpdate)); + assertEquals(2, listUpdate.size()); + assertEquals(UserEventType.UPDATE, listUpdate.get(1).getType()); + + // delete user + mockMvc.perform(delete(Constants.API_USERS_ID, identifier).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNoContent()); + assertThrows(NotFoundException.class, () -> userService.findByIdentifier(identifier)); + + assertTrue(userEventService.findUserEventsByUser(userFoundAfterUpdate).isEmpty()); + + // delete user not found + mockMvc.perform(delete(Constants.API_USERS_ID, identifier).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + + } + + @Test + void putUsersErrorId() throws Exception { + String identifier = "NEWONE"; + String otherIdentifier = "WRONG"; + User user = initGestionnaire(identifier); + String jsonUser = createJson(user); + mockMvc.perform(put(Constants.API_USERS_ID, otherIdentifier).content(jsonUser) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()) + .andExpect(content().json(JsonUtil.createJsonErrorBadRequest("id and user identifier don't match"))); + + } + + private User initGestionnaire(String identifier) { + return initUser(identifier, User.UserRoleType.GESTIONNAIRE); + } + + private User initUser(String identifier, User.UserRoleType role) { + User userMock = new User(); + userMock.setIdentifier(identifier); + userMock.setRole(role); + return userMock; + } + + + private String createJson(User user) throws JSONException { + JSONObject jo = new JSONObject(); + jo.put("identifier", user.getIdentifier()); + jo.put("role", user.getRole().name()); + return jo.toString(); + } +} diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserEventControllerTest.java b/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserEventControllerTest.java new file mode 100644 index 00000000..bf163ea7 --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/user/controller/controller/UserEventControllerTest.java @@ -0,0 +1,57 @@ +package fr.insee.survey.datacollectionmanagement.user.controller.controller; + +import fr.insee.survey.datacollectionmanagement.constants.Constants; +import fr.insee.survey.datacollectionmanagement.user.domain.UserEvent; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +@SpringBootTest +@ActiveProfiles("test") +class UserEventControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void getUserEventOk() throws Exception { + String identifier = "USER1"; + + String json = createJsonUserEvent(identifier, null); + this.mockMvc.perform(get(Constants.API_USERS_ID_USEREVENTS, identifier)).andDo(print()).andExpect(status().isOk()) + .andExpect(content().json(json, false)); + } + + @Test + void getUserEventNotFound() throws Exception { + String identifier = "CONT500"; + this.mockMvc.perform(get(Constants.API_USERS_ID_USEREVENTS, identifier)).andDo(print()) + .andExpect(status().is(HttpStatus.NOT_FOUND.value())); + + } + + private String createJsonUserEvent(String identifier, JSONObject payload) throws JSONException { + JSONObject jo = new JSONObject(); + JSONObject joPayload = new JSONObject(); + joPayload.put("identifier", identifier); + joPayload.put("type", UserEvent.UserEventType.CREATE.name()); + jo.put("payload", payload); + JSONArray ja = new JSONArray(); + ja.put(jo); + return ja.toString(); + } + +} diff --git a/src/test/java/fr/insee/survey/datacollectionmanagement/util/JsonUtil.java b/src/test/java/fr/insee/survey/datacollectionmanagement/util/JsonUtil.java new file mode 100644 index 00000000..40221c03 --- /dev/null +++ b/src/test/java/fr/insee/survey/datacollectionmanagement/util/JsonUtil.java @@ -0,0 +1,19 @@ +package fr.insee.survey.datacollectionmanagement.util; + +import net.minidev.json.JSONObject; +import org.springframework.http.HttpStatus; + +public class JsonUtil { + + + public static String createJsonError(int code, String message) { + JSONObject jo = new JSONObject(); + jo.put("code", code); + jo.put("message", message); + return jo.toString(); + } + + public static String createJsonErrorBadRequest(String message) { + return createJsonError(HttpStatus.BAD_REQUEST.value(), message); + } +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 34a6a673..81356cee 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -13,7 +13,7 @@ springdoc.swagger-ui.tagsSorter: alpha springdoc.swagger-ui.enabled=true -fr.insee.datacollectionmanagement.cors.allowedOrigin=* +fr.insee.datacollectionmanagement.cors.allowedOrigins=* #Actuator Metrics @@ -46,4 +46,9 @@ fr.insee.datacollectionmanagement.roles.webclient.role=webclient # Questioning url -fr.insee.datacollectionmanagement.api.questioning.url=http://localhost:8081 \ No newline at end of file +fr.insee.datacollectionmanagement.api.questioning.url=http://localhost:8081 + +spring.datasource.driverClassName=org.h2.Driver +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect + +fr.insee.datacollectionmanagement.public.urls=/swagger-ui/**,/swagger-ui.html,/v3/api-docs/**,/csrf, /,/webjars/**,/swagger-resources/**,/environnement,/healthcheck,/actuator/** \ No newline at end of file diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql index 8337aefd..cf5eb2d3 100644 --- a/src/test/resources/data.sql +++ b/src/test/resources/data.sql @@ -1 +1,2 @@ -create domain if not exists jsonb as other; +create domain if not exists jsonb as json; +