Skip to content

Commit 2018f86

Browse files
Merge pull request #248 from marcberger/feat/feat_exportrawresponse_generic2
feat: add /responses/raw/lunatic-json/{campaignId} endpoint
2 parents 4e1440b + 3b9d297 commit 2018f86

12 files changed

Lines changed: 217 additions & 56 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ src/test/resources/OUT/*
4848
/src/test/resources/DONE/*
4949
/src/test/resources/genesis_deleted_schedules/*
5050
/src/test/resources/IN/WEB/SAMPLETEST/
51+
/src/main/resources/application-mbg.properties

src/main/java/fr/insee/genesis/controller/rest/responses/RawResponseController.java

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,41 @@
1616
import io.swagger.v3.oas.annotations.Hidden;
1717
import io.swagger.v3.oas.annotations.Operation;
1818
import lombok.extern.slf4j.Slf4j;
19+
import org.springframework.data.domain.Page;
20+
import org.springframework.data.domain.PageRequest;
21+
import org.springframework.data.domain.Pageable;
22+
import org.springframework.data.web.PagedModel;
23+
import org.springframework.format.annotation.DateTimeFormat;
24+
import org.springframework.http.HttpStatus;
1925
import org.springframework.http.ResponseEntity;
2026
import org.springframework.security.access.prepost.PreAuthorize;
2127
import org.springframework.stereotype.Controller;
2228
import org.springframework.web.bind.annotation.GetMapping;
29+
import org.springframework.web.bind.annotation.PathVariable;
2330
import org.springframework.web.bind.annotation.PostMapping;
2431
import org.springframework.web.bind.annotation.PutMapping;
2532
import org.springframework.web.bind.annotation.RequestBody;
2633
import org.springframework.web.bind.annotation.RequestMapping;
2734
import org.springframework.web.bind.annotation.RequestParam;
2835

36+
import java.time.Instant;
2937
import java.time.LocalDateTime;
3038
import java.util.ArrayList;
31-
import java.util.Arrays;
3239
import java.util.List;
3340
import java.util.Map;
3441
import java.util.Set;
3542
import java.util.stream.Collectors;
3643

3744
@Slf4j
3845
@Controller
39-
@RequestMapping(path = "/responses/raw" )
46+
@RequestMapping(path = "/responses/raw")
4047
public class RawResponseController {
4148

4249
private static final String SUCCESS_MESSAGE = "Interrogation %s saved";
4350
private static final String PARTITION_ID = "partitionId";
4451
private static final String INTERROGATION_ID = "interrogationId";
4552
private final LunaticJsonRawDataApiPort lunaticJsonRawDataApiPort;
46-
53+
4754
public RawResponseController(LunaticJsonRawDataApiPort lunaticJsonRawDataApiPort) {
4855
this.lunaticJsonRawDataApiPort = lunaticJsonRawDataApiPort;
4956
}
@@ -60,7 +67,7 @@ public ResponseEntity<String> saveRawResponsesFromJsonBody(
6067
@RequestParam(value = "mode") Mode modeSpecified,
6168
@RequestBody Map<String, Object> dataJson
6269
) {
63-
log.info("Try to save interrogationId {} for campaign {}",interrogationId,campaignName);
70+
log.info("Try to save interrogationId {} for campaign {}", interrogationId, campaignName);
6471
LunaticJsonRawDataModel rawData = LunaticJsonRawDataModel.builder()
6572
.campaignId(campaignName)
6673
.questionnaireId(questionnaireId)
@@ -72,12 +79,12 @@ public ResponseEntity<String> saveRawResponsesFromJsonBody(
7279
.build();
7380
try {
7481
lunaticJsonRawDataApiPort.save(rawData);
75-
} catch (Exception e){
82+
} catch (Exception e) {
7683
return ResponseEntity.status(500).body("Unexpected error");
7784
}
78-
log.info("Data saved for interrogationId {} and campaign {}",interrogationId, campaignName);
85+
log.info("Data saved for interrogationId {} and campaign {}", interrogationId, campaignName);
7986
// Collect platform prefer code 201 in case of success
80-
return ResponseEntity.status(201).body(String.format(SUCCESS_MESSAGE,interrogationId));
87+
return ResponseEntity.status(201).body(String.format(SUCCESS_MESSAGE, interrogationId));
8188
}
8289

8390
@Operation(summary = "Save lunatic json data from one interrogation in Genesis Database (with json " +
@@ -90,8 +97,8 @@ public ResponseEntity<String> saveRawResponsesFromJsonBodyWithValidation(
9097
JsonSchema jsonSchema = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7).getSchema(
9198
RawResponseController.class.getResourceAsStream("/jsonSchemas/RawResponse.json")
9299
);
93-
try{
94-
if(jsonSchema == null){
100+
try {
101+
if (jsonSchema == null) {
95102
throw new GenesisException(500, "No RawResponse json schema has been found");
96103
}
97104
Set<ValidationMessage> errors = jsonSchema.validate(
@@ -103,9 +110,9 @@ public ResponseEntity<String> saveRawResponsesFromJsonBodyWithValidation(
103110
validate(errors);
104111
//Check required ids
105112
checkRequiredIds(body);
106-
}catch (JsonProcessingException jpe){
113+
} catch (JsonProcessingException jpe) {
107114
return ResponseEntity.status(400).body(jpe.toString());
108-
}catch (GenesisException ge){
115+
} catch (GenesisException ge) {
109116
return ResponseEntity.status(ge.getStatus()).body(ge.getMessage());
110117
}
111118

@@ -124,29 +131,29 @@ public ResponseEntity<String> saveRawResponsesFromJsonBodyWithValidation(
124131
return ResponseEntity.status(500).body("Unexpected error");
125132
}
126133

127-
log.info("Data saved for interrogationId {} and partition {}",body.get(INTERROGATION_ID).toString(),
134+
log.info("Data saved for interrogationId {} and partition {}", body.get(INTERROGATION_ID).toString(),
128135
body.get(PARTITION_ID).toString());
129-
return ResponseEntity.status(201).body(String.format(SUCCESS_MESSAGE,body.get(INTERROGATION_ID).toString()));
136+
return ResponseEntity.status(201).body(String.format(SUCCESS_MESSAGE, body.get(INTERROGATION_ID).toString()));
130137
}
131138

132139
//GET unprocessed
133140
@Operation(summary = "Get campaign id and interrogationId from all unprocessed raw json data")
134141
@GetMapping(path = "/lunatic-json/get/unprocessed")
135142
@PreAuthorize("hasRole('SCHEDULER')")
136-
public ResponseEntity<List<LunaticJsonRawDataUnprocessedDto>> getUnproccessedJsonRawData(){
143+
public ResponseEntity<List<LunaticJsonRawDataUnprocessedDto>> getUnproccessedJsonRawData() {
137144
log.info("Try to get unprocessed raw JSON datas...");
138145
return ResponseEntity.ok(lunaticJsonRawDataApiPort.getUnprocessedDataIds());
139146
}
140147

141148
@Hidden
142-
@GetMapping(path= "/lunatic-json/get/by-interrogation-mode-and-campaign")
149+
@GetMapping(path = "/lunatic-json/get/by-interrogation-mode-and-campaign")
143150
@PreAuthorize("hasRole('ADMIN')")
144-
public ResponseEntity<LunaticJsonRawDataModel> getJsonRawData(
145-
@RequestParam(INTERROGATION_ID) String interrogationId,
146-
@RequestParam("campaignName") String campaignName,
147-
@RequestParam(value = "mode") Mode modeSpecified
148-
){
149-
List<LunaticJsonRawDataModel> data = lunaticJsonRawDataApiPort.getRawData(campaignName,modeSpecified,List.of(interrogationId));
151+
public ResponseEntity<LunaticJsonRawDataModel> getJsonRawData(
152+
@RequestParam(INTERROGATION_ID) String interrogationId,
153+
@RequestParam("campaignName") String campaignName,
154+
@RequestParam(value = "mode") Mode modeSpecified
155+
) {
156+
List<LunaticJsonRawDataModel> data = lunaticJsonRawDataApiPort.getRawData(campaignName, modeSpecified, List.of(interrogationId));
150157
return ResponseEntity.ok(data.getFirst());
151158
}
152159

@@ -158,7 +165,7 @@ public ResponseEntity<String> processJsonRawData(
158165
@RequestParam("campaignName") String campaignName,
159166
@RequestParam("questionnaireId") String questionnaireId,
160167
@RequestBody List<String> interrogationIdList
161-
){
168+
) {
162169
log.info("Try to process raw JSON datas for campaign {} and {} interrogationIds", campaignName, interrogationIdList.size());
163170
List<GenesisError> errors = new ArrayList<>();
164171

@@ -168,13 +175,30 @@ public ResponseEntity<String> processJsonRawData(
168175
ResponseEntity.ok("%d document(s) processed".formatted(result.dataCount()))
169176
: ResponseEntity.ok("%d document(s) processed, including %d FORMATTED after data verification"
170177
.formatted(result.dataCount(), result.formattedDataCount()));
171-
}catch (GenesisException e){
178+
} catch (GenesisException e) {
172179
return ResponseEntity.status(e.getStatus()).body(e.getMessage());
173180
}
174181
}
175182

183+
@Operation(summary = "Get lunatic JSON data from one campaign in Genesis Database, filtered by optional start and end dates")
184+
@GetMapping(path = "/lunatic-json/{campaignId}")
185+
@PreAuthorize("hasRole('USER_KRAFTWERK')")
186+
public ResponseEntity<PagedModel<LunaticJsonRawDataModel>> getRawResponsesFromJsonBody(
187+
@PathVariable String campaignId,
188+
@RequestParam(value = "startDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant startDate,
189+
@RequestParam(value = "endDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant endDate,
190+
@RequestParam(value = "page", defaultValue = "0") int page,
191+
@RequestParam(value = "size", defaultValue = "1000") int size
192+
) {
193+
log.info("Try to read raw JSONs for campaign {}, with startDate={} and endDate={}", campaignId, startDate, endDate);
194+
Pageable pageable = PageRequest.of(page, size);
195+
Page<LunaticJsonRawDataModel> rawResponses = lunaticJsonRawDataApiPort.findRawDataByCampaignIdAndDate(campaignId, startDate, endDate, pageable);
196+
log.info("rawResponses=" + rawResponses.getContent().size());
197+
return ResponseEntity.status(HttpStatus.OK).body(new PagedModel<>(rawResponses));
198+
}
199+
176200
private void validate(Set<ValidationMessage> errors) throws GenesisException {
177-
if(!errors.isEmpty()){
201+
if (!errors.isEmpty()) {
178202
String errorMessage = errors.stream()
179203
.map(ValidationMessage::getMessage)
180204
.collect(Collectors.joining(System.lineSeparator() + " - "));
@@ -187,14 +211,14 @@ private void validate(Set<ValidationMessage> errors) throws GenesisException {
187211
}
188212

189213
private void checkRequiredIds(Map<String, Object> body) throws GenesisException {
190-
for(String requiredKey : List.of(
214+
for (String requiredKey : List.of(
191215
PARTITION_ID,
192216
"questionnaireModelId",
193217
INTERROGATION_ID,
194218
"surveyUnitId",
195219
"mode"
196-
)){
197-
if(body.get(requiredKey) == null){
220+
)) {
221+
if (body.get(requiredKey) == null) {
198222
throw new GenesisException(400, "No %s found in body".formatted(requiredKey));
199223
}
200224
}

src/main/java/fr/insee/genesis/domain/ports/api/LunaticJsonRawDataApiPort.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
import fr.insee.genesis.domain.model.surveyunit.rawdata.LunaticJsonRawDataModel;
99
import fr.insee.genesis.exceptions.GenesisError;
1010
import fr.insee.genesis.exceptions.GenesisException;
11+
import org.springframework.data.domain.Page;
12+
import org.springframework.data.domain.Pageable;
1113

14+
import java.time.Instant;
1215
import java.util.List;
1316
import java.util.Set;
1417

@@ -21,6 +24,7 @@ public interface LunaticJsonRawDataApiPort {
2124
void updateProcessDates(List<SurveyUnitModel> surveyUnitModels);
2225
Set<String> findDistinctQuestionnaireIds();
2326
long countResponsesByQuestionnaireId(String campaignId);
27+
Page<LunaticJsonRawDataModel> findRawDataByCampaignIdAndDate(String campaignId, Instant startDt, Instant endDt, Pageable pageable);
2428

2529
DataProcessResult processRawData(String campaignName, List<String> interrogationIdList, List<GenesisError> errors) throws GenesisException;
2630
}

src/main/java/fr/insee/genesis/domain/ports/spi/LunaticJsonRawDataPersistencePort.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import fr.insee.genesis.domain.model.surveyunit.Mode;
44
import fr.insee.genesis.domain.model.surveyunit.rawdata.LunaticJsonRawDataModel;
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
57

8+
import java.time.Instant;
69
import java.util.List;
710
import java.util.Set;
811

@@ -13,5 +16,6 @@ public interface LunaticJsonRawDataPersistencePort {
1316
List<LunaticJsonRawDataModel> getAllUnprocessedData();
1417
void updateProcessDates(String campaignId, Set<String> interrogationIds);
1518
Set<String> findDistinctQuestionnaireIds();
19+
Page<LunaticJsonRawDataModel> findByCampaignIdAndDate(String campaignId, Instant startDt, Instant endDt, Pageable pageable);
1620
long countResponsesByQuestionnaireId(String questionnaireId);
1721
}

src/main/java/fr/insee/genesis/domain/service/rawdata/LunaticJsonRawDataService.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828
import lombok.extern.slf4j.Slf4j;
2929
import org.springframework.beans.factory.annotation.Autowired;
3030
import org.springframework.beans.factory.annotation.Qualifier;
31+
import org.springframework.data.domain.Page;
32+
import org.springframework.data.domain.Pageable;
3133
import org.springframework.http.ResponseEntity;
3234
import org.springframework.stereotype.Service;
3335

3436
import java.io.IOException;
37+
import java.time.Instant;
3538
import java.time.LocalDateTime;
3639
import java.util.ArrayList;
3740
import java.util.HashMap;
@@ -387,4 +390,12 @@ public Set<String> findDistinctQuestionnaireIds() {
387390
public long countResponsesByQuestionnaireId(String campaignId) {
388391
return lunaticJsonRawDataPersistencePort.countResponsesByQuestionnaireId(campaignId);
389392
}
393+
394+
395+
@Override
396+
public Page<LunaticJsonRawDataModel> findRawDataByCampaignIdAndDate(String campaignId, Instant startDt, Instant endDt, Pageable pageable){
397+
return lunaticJsonRawDataPersistencePort.findByCampaignIdAndDate(campaignId,startDt, endDt,pageable);
398+
399+
}
400+
390401
}

src/main/java/fr/insee/genesis/infrastructure/adapter/LunaticJsonRawDataMongoAdapter.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
import fr.insee.genesis.infrastructure.repository.LunaticJsonMongoDBRepository;
1010
import lombok.extern.slf4j.Slf4j;
1111
import org.springframework.beans.factory.annotation.Qualifier;
12+
import org.springframework.data.domain.Page;
13+
import org.springframework.data.domain.PageImpl;
14+
import org.springframework.data.domain.Pageable;
1215
import org.springframework.data.mongodb.core.MongoTemplate;
1316
import org.springframework.data.mongodb.core.query.Criteria;
1417
import org.springframework.data.mongodb.core.query.Query;
1518
import org.springframework.data.mongodb.core.query.Update;
1619
import org.springframework.stereotype.Service;
1720

21+
import java.time.Instant;
1822
import java.time.LocalDateTime;
1923
import java.util.HashSet;
2024
import java.util.List;
@@ -68,6 +72,13 @@ public Set<String> findDistinctQuestionnaireIds() {
6872
return questionnaireIds;
6973
}
7074

75+
@Override
76+
public Page<LunaticJsonRawDataModel> findByCampaignIdAndDate(String campaignId, Instant startDt, Instant endDt, Pageable pageable) {
77+
Page<LunaticJsonRawDataDocument> rawDataDocsPage = repository.findByCampaignIdAndRecordDateBetween(campaignId,startDt,endDt,pageable);
78+
List<LunaticJsonRawDataModel> modelList = LunaticJsonRawDataDocumentMapper.INSTANCE.listDocumentToListModel(rawDataDocsPage.getContent());
79+
return new PageImpl<>(modelList, rawDataDocsPage.getPageable(), rawDataDocsPage.getTotalElements());
80+
}
81+
7182
@Override
7283
public long countResponsesByQuestionnaireId(String questionnaireId) {
7384
return repository.countByQuestionnaireId(questionnaireId);

src/main/java/fr/insee/genesis/infrastructure/document/rundeck/RundeckExecutionDocument.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import fr.insee.genesis.domain.model.rundeck.DateStarted;
5-
import lombok.*;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
68
import org.springframework.data.mongodb.core.mapping.Document;
79

810
@Data

src/main/java/fr/insee/genesis/infrastructure/repository/LunaticJsonMongoDBRepository.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,28 @@
22

33
import fr.insee.genesis.domain.model.surveyunit.Mode;
44
import fr.insee.genesis.infrastructure.document.rawdata.LunaticJsonRawDataDocument;
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
57
import org.springframework.data.mongodb.repository.MongoRepository;
68
import org.springframework.data.mongodb.repository.Query;
79
import org.springframework.stereotype.Repository;
810

11+
import java.time.Instant;
912
import java.util.List;
1013

1114
@Repository
12-
public interface LunaticJsonMongoDBRepository extends MongoRepository<LunaticJsonRawDataDocument,String> {
15+
public interface LunaticJsonMongoDBRepository extends MongoRepository<LunaticJsonRawDataDocument, String> {
1316

1417
@Query("{\"processDate\" : null}")
1518
List<LunaticJsonRawDataDocument> findByNullProcessDate();
19+
1620
@Query(value = "{ 'campaignId' : ?0 }", fields = "{ 'mode' : 1 }")
1721
List<Mode> findModesByCampaignId(String campaignId);
22+
1823
@Query(value = "{ 'campaignId' : ?0, 'mode' : ?1, 'interrogationId': {$in: ?2} }")
1924
List<LunaticJsonRawDataDocument> findModesByCampaignIdAndByModeAndinterrogationIdIninterrogationIdList(String campaignName, Mode mode, List<String> interrogationIdList);
25+
26+
Page<LunaticJsonRawDataDocument> findByCampaignIdAndRecordDateBetween(String campagneId, Instant start, Instant end, Pageable pageable);
2027
long countByQuestionnaireId(String questionnaireId);
2128

2229

0 commit comments

Comments
 (0)