Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
b263024
Add unprocessed raw data endpoint
alexisszmundy Dec 19, 2024
ff82ef8
Add data processing
alexisszmundy Dec 20, 2024
e44151b
Add variable type storage
alexisszmundy Dec 20, 2024
c07fdea
Add exception management + fix after mongo tests
alexisszmundy Dec 20, 2024
65517c9
Merge branch 'main' into devRawDataProcessing
alexisszmundy Dec 23, 2024
265347c
refactors
alexisszmundy Dec 30, 2024
7a57e42
Removed unused
alexisszmundy Jan 6, 2025
80f2fdf
Store variablesmap in variabletype collection
alexisszmundy Jan 6, 2025
f5e3dbe
Merge branch 'main' into devRawDataProcessing
alicela Jan 9, 2025
61ca83f
fix: remove unused
alicela Jan 9, 2025
275fd5b
Merge branch 'main' into devRawDataProcessing
alexisszmundy Jan 9, 2025
0cf7a1d
fix: cucumber definitions with vartype
alexisszmundy Jan 9, 2025
6d19845
Merge branch 'devRawDataProcessing' of https://github.com/InseeFr/Gen…
alicela Jan 10, 2025
70d916d
Fix for sonar
alicela Jan 20, 2025
f3fd06b
build: refactors
alexisszmundy Jan 21, 2025
96881e0
feat: Disabled save Metadata when processing due to mapping problem
alexisszmundy Jan 21, 2025
1651366
Merge branch 'main' into devRawDataProcessing
alexisszmundy Feb 5, 2025
7257f87
fix: use VariableModel not CollectedVariable
alexisszmundy Feb 5, 2025
aeecb7c
fix: After merge fixes
alexisszmundy Feb 5, 2025
7bb7385
Merge branch 'main' into devRawDataProcessing
alexisszmundy Feb 20, 2025
23bf782
feat: input JSON raw data structure check and adaptations to lunatic …
alexisszmundy Feb 21, 2025
c5def6f
test: add raw data processing functional test
alexisszmundy Feb 24, 2025
3bdac3e
feat: add data verification on raw data processing
alexisszmundy Feb 24, 2025
2457ae9
Merge branch 'main' into devRawDataProcessing
alexisszmundy Feb 24, 2025
9f59a18
refactor: added refactors from Init raw response controller
alexisszmundy Feb 28, 2025
b8e342d
Merge branch 'main' into devRawDataProcessing
alexisszmundy Feb 28, 2025
70a2d69
fix: GroupUtils instead of LoopIdentifier
alexisszmundy Feb 28, 2025
aa25fed
fix: Mockito not creating mock
alexisszmundy Feb 28, 2025
6a9c22b
chore: remove unused imports
alexisszmundy Feb 28, 2025
f9f5504
fix: error on parentId (group parent) name
loichenninger Mar 5, 2025
fd5dff3
fix: can't see endpoints in swagger
loichenninger Mar 7, 2025
bfca7b5
fix: empty values should be send too
loichenninger Mar 7, 2025
64b5172
test: on fix empty values should be return too
loichenninger Mar 7, 2025
1d76bb1
chore: renaming raw controller services
loichenninger Mar 14, 2025
12e61f8
fix: remove code used for testing
loichenninger Mar 14, 2025
4baf785
fix: change mapper to read raw data in db
loichenninger Mar 18, 2025
b095e4e
test: update to take into account the changes
loichenninger Mar 18, 2025
216340c
refactor: RawData model change
loichenninger Mar 19, 2025
6035763
build: WIP on process data corresponding tests are deactivated
loichenninger Mar 19, 2025
2f4d79e
feat: forgot to add recordDate when saving the data
loichenninger Mar 19, 2025
602e107
chore: response message with more details
loichenninger Mar 19, 2025
7f8db99
chore: unnecessary code
loichenninger Mar 19, 2025
6804728
fix: test for saving raw data
alicela Mar 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>


<dependency>
Expand Down
31 changes: 31 additions & 0 deletions qodana.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#-------------------------------------------------------------------------------#
# Qodana analysis is configured by qodana.yaml file #
# https://www.jetbrains.com/help/qodana/qodana-yaml.html #
#-------------------------------------------------------------------------------#
version: "1.0"

#Specify inspection profile for code analysis
profile:
name: qodana.starter

#Enable inspections
#include:
# - name: <SomeEnabledInspectionId>

#Disable inspections
#exclude:
# - name: <SomeDisabledInspectionId>
# paths:
# - <path/where/not/run/inspection>

projectJDK: 21 #(Applied in CI/CD pipeline)

#Execute shell command before Qodana execution (Applied in CI/CD pipeline)
#bootstrap: sh ./prepare-qodana.sh

#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline)
#plugins:
# - id: <plugin.id> #(plugin id can be found at https://plugins.jetbrains.com)

#Specify Qodana linter for analysis (Applied in CI/CD pipeline)
linter: jetbrains/qodana-jvm-community:latest
2 changes: 2 additions & 0 deletions src/main/java/fr/insee/genesis/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ public class Constants {
"(^([0-9]|[0-2][0-9]|3[0-1])[\\-\\/]([0-9]|1[0-2]|0[1-9])[\\-\\/]([0-9]{4})$)";
public static final String FILTER_RESULT_PREFIX = "FILTER_RESULT_";
public static final String MISSING_SUFFIX = "_MISSING";
public static final String MONGODB_LUNATIC_RAWDATA_COLLECTION_NAME = "lunaticjsondata";
private static final String[] ENO_VARIABLES = {"COMMENT_QE","COMMENT_UE","HEURE_REMPL","MIN_REMPL"};

public static final String MONGODB_SCHEDULE_COLLECTION_NAME = "schedules";
public static final String LOOP_NAME_PREFIX = "BOUCLE";
public static final String MONGODB_RESPONSE_COLLECTION_NAME = "responses";
public static final String MONGODB_VARIABLETYPE_COLLECTION_NAME = "variabletypes";
public static final String VOLUMETRY_FOLDER_NAME = "genesis_volumetries";
public static final String VOLUMETRY_FILE_SUFFIX = "_VOLUMETRY";
public static final String VOLUMETRY_FILE_DATE_FORMAT = "yyyy_MM_dd";
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/fr/insee/genesis/configuration/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

import java.nio.file.Path;

@Configuration
@Getter
@EnableCaching
public class Config {

/******************************************************/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package fr.insee.genesis.controller.dto.rawdata;

import lombok.Builder;

@Builder
public record LunaticJsonRawDataUnprocessedDto(String campaignId, String interrogationId){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package fr.insee.genesis.controller.rest.responses;

import fr.insee.bpm.metadata.model.VariablesMap;
import fr.insee.genesis.controller.dto.rawdata.LunaticJsonRawDataUnprocessedDto;
import fr.insee.genesis.controller.services.MetadataService;
import fr.insee.genesis.controller.utils.ControllerUtils;
import fr.insee.genesis.domain.model.surveyunit.DataState;
import fr.insee.genesis.domain.model.surveyunit.Mode;
import fr.insee.genesis.domain.model.surveyunit.SurveyUnitModel;
import fr.insee.genesis.domain.model.surveyunit.rawdata.LunaticJsonRawDataModel;
import fr.insee.genesis.domain.ports.api.LunaticJsonRawDataApiPort;
import fr.insee.genesis.domain.service.surveyunit.SurveyUnitQualityService;
import fr.insee.genesis.domain.service.surveyunit.SurveyUnitService;
import fr.insee.genesis.exceptions.GenesisError;
import fr.insee.genesis.exceptions.GenesisException;
import fr.insee.genesis.infrastructure.utils.FileUtils;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Controller
@RequestMapping(path = "/responses/raw" )
public class RawResponseController {

private static final String SUCCESS_MESSAGE = "Interrogation %s saved";
private final LunaticJsonRawDataApiPort lunaticJsonRawDataApiPort;
private final ControllerUtils controllerUtils;
private final MetadataService metadataService;
private final SurveyUnitService surveyUnitService;
private final SurveyUnitQualityService surveyUnitQualityService;
private final FileUtils fileUtils;

public RawResponseController(LunaticJsonRawDataApiPort lunaticJsonRawDataApiPort, ControllerUtils controllerUtils, MetadataService metadataService, SurveyUnitService surveyUnitService, SurveyUnitQualityService surveyUnitQualityService, FileUtils fileUtils) {
this.lunaticJsonRawDataApiPort = lunaticJsonRawDataApiPort;
this.controllerUtils = controllerUtils;
this.metadataService = metadataService;
this.surveyUnitService = surveyUnitService;
this.surveyUnitQualityService = surveyUnitQualityService;
this.fileUtils = fileUtils;
}

@Operation(summary = "Save lunatic json data from one interrogation in Genesis Database")
@PutMapping(path = "/lunatic-json/save")
public ResponseEntity<String> saveRawResponsesFromJsonBody(
@RequestParam("campaignName") String campaignName,
@RequestParam("questionnaireId") String questionnaireId,
@RequestParam("interrogationId") String interrogationId,
@RequestParam(value = "surveyUnitId", required = false) String idUE,
@RequestParam(value = "mode") Mode modeSpecified,
@RequestBody Map<String, Object> dataJson
) {
log.info("Try to save interrogationId {} for campaign {}",interrogationId,campaignName);
LunaticJsonRawDataModel rawData = LunaticJsonRawDataModel.builder()
.campaignId(campaignName)
.questionnaireId(questionnaireId)
.interrogationId(interrogationId)
.idUE(idUE)
.mode(modeSpecified)
.data(dataJson)
.recordDate(LocalDateTime.now())
.build();
try {
lunaticJsonRawDataApiPort.save(rawData);
} catch (Exception e){
return ResponseEntity.status(500).body("Unexpected error");
}
log.info("Data saved for interrogationId {} and campaign {}",interrogationId, campaignName);
// Collect platform prefer code 201 in case of success
return ResponseEntity.status(201).body(String.format(SUCCESS_MESSAGE,interrogationId));
}

//GET unprocessed
@Operation(summary = "Get campaign id and interrogationId from all unprocessed raw json data")
@GetMapping(path = "/lunatic-json/get/unprocessed")
public ResponseEntity<List<LunaticJsonRawDataUnprocessedDto>> getUnproccessedJsonRawData(){
log.info("Try to get unprocessed raw JSON datas...");
return ResponseEntity.ok(lunaticJsonRawDataApiPort.getUnprocessedDataIds());
}

//PROCESS
@Operation(summary = "Process raw data of a campaign")
@PostMapping(path = "/lunatic-json/process")
public ResponseEntity<Object> processJsonRawData(
@RequestParam("campaignName") String campaignName,
@RequestParam("questionnaireId") String questionnaireId,
@RequestBody List<String> interrogationIdList
){
log.info("Try to process raw JSON datas for campaign {} and {} interrogationIds", campaignName, interrogationIdList.size());

int dataCount = 0;
int forcedDataCount = 0;
List<GenesisError> errors = new ArrayList<>();

try {
List<Mode> modesList = controllerUtils.getModesList(campaignName, null);
for (Mode mode : modesList) {
//Load and save metadatas into database, throw exception if none
VariablesMap variablesMap = metadataService.readMetadatas(campaignName, mode.getModeName(), fileUtils,
errors);
if (variablesMap == null) {
throw new GenesisException(400,
"Error during metadata parsing for mode %s :%n%s"
.formatted(mode, errors.getLast().getMessage())
);
}

List<LunaticJsonRawDataModel> rawData = lunaticJsonRawDataApiPort.getRawData(campaignName,mode,interrogationIdList);
//Save converted data
List<SurveyUnitModel> surveyUnitModels = lunaticJsonRawDataApiPort.convertRawData(
rawData,
variablesMap
);

surveyUnitQualityService.verifySurveyUnits(surveyUnitModels, variablesMap);
surveyUnitService.saveSurveyUnits(surveyUnitModels);

//Update process dates
lunaticJsonRawDataApiPort.updateProcessDates(surveyUnitModels);

//Save metadatas
//TODO Enable when mapping problem solved for get metadatas step
//variableTypeApiPort.saveMetadatas(campaignName, questionnaireId, mode, variablesMap);

//Increment data count
dataCount += surveyUnitModels.size();
forcedDataCount += surveyUnitModels.stream().filter(
surveyUnitModel -> surveyUnitModel.getState().equals(DataState.FORCED)
).toList().size();
}
return forcedDataCount == 0 ?
ResponseEntity.ok("%d document(s) processed".formatted(dataCount))
: ResponseEntity.ok("%d document(s) processed, including %d FORCED after data verification"
.formatted(dataCount, forcedDataCount));
}catch (GenesisException e){ //TODO replace with spring exception handler
return ResponseEntity.status(e.getStatus()).body(e.getMessage());
}
}

}
Loading
Loading