Skip to content

Commit 75a71f2

Browse files
laurentC35nsenave
andauthored
feat: simplify questionnaire with references for public-enemy (#226)
* feat: Questionnaire service: create getQuestionnaireByID with ref * feat: move deref implementation to QuestionnaireService * feat: composition, adapt VariablesService * feat: add requestParam "references" to GET "api/questionnaire/{id}" with false by default * test: fix test * fix: mock issue and log * docs: add javadoc to explain what "references" means --------- Co-authored-by: Nicolas Senave <[email protected]>
1 parent b9aecf7 commit 75a71f2

File tree

8 files changed

+158
-75
lines changed

8 files changed

+158
-75
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<groupId>fr.insee</groupId>
1414
<artifactId>Pogues-BO</artifactId>
1515
<packaging>jar</packaging>
16-
<version>4.4.1</version>
16+
<version>4.4.2</version>
1717
<name>Pogues-BO</name>
1818

1919
<properties>

src/main/java/fr/insee/pogues/persistence/service/QuestionnairesService.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,27 @@ public interface QuestionnairesService {
3030
* @throws Exception
3131
*/
3232
JSONObject getQuestionnaireByID(String id) throws Exception;
33-
33+
34+
/**
35+
* A questionnaire can "contain" other questionnaires. These questionnaires appear as references.
36+
* This method makes it possible to obtain the complete questionnaire, by replacing the references with the complete questionnaires.
37+
* @param id Id of requested object
38+
*
39+
* @return JSON representation of the questionnaire with references
40+
* @throws Exception
41+
*/
42+
JSONObject getQuestionnaireByIDWithReferences(String id) throws Exception;
43+
44+
/**
45+
* A questionnaire can "contain" other questionnaires. These questionnaires appear as references.
46+
* This method makes it possible to obtain the complete questionnaire, by replacing the references with the complete questionnaires.
47+
*
48+
* @param jsonQuestionnaire JSON representation of a questionnaire
49+
* @return JSON representation of the questionnaire with its references
50+
* @throws Exception
51+
*/
52+
JSONObject getQuestionnaireWithReferences(JSONObject jsonQuestionnaire) throws Exception;
53+
3454
/**
3555
*
3656
* @param id Id of requested object

src/main/java/fr/insee/pogues/persistence/service/QuestionnairesServiceImpl.java

+58-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
package fr.insee.pogues.persistence.service;
22

33
import java.util.List;
4+
import java.util.Map;
45

6+
import fr.insee.pogues.exception.NullReferenceException;
7+
import fr.insee.pogues.model.Questionnaire;
8+
import fr.insee.pogues.transforms.visualize.PoguesJSONToPoguesJSONDeref;
9+
import fr.insee.pogues.transforms.visualize.PoguesJSONToPoguesJSONDerefImpl;
10+
import fr.insee.pogues.transforms.visualize.composition.QuestionnaireComposition;
11+
import fr.insee.pogues.utils.PoguesDeserializer;
12+
import fr.insee.pogues.utils.PoguesSerializer;
13+
import fr.insee.pogues.utils.json.JSONFunctions;
14+
import org.apache.logging.log4j.LogManager;
15+
import org.apache.logging.log4j.Logger;
516
import org.json.simple.JSONObject;
17+
import org.json.simple.parser.JSONParser;
618
import org.springframework.beans.factory.annotation.Autowired;
719
import org.springframework.stereotype.Service;
820

921
import fr.insee.pogues.persistence.query.EntityNotFoundException;
1022
import fr.insee.pogues.persistence.query.NonUniqueResultException;
1123
import fr.insee.pogues.persistence.query.QuestionnairesServiceQuery;
1224
import fr.insee.pogues.webservice.rest.PoguesException;
13-
1425
/**
1526
* Questionnaire Service to assume the persistence of Pogues UI in JSON
1627
*
@@ -21,9 +32,11 @@
2132
@Service
2233
public class QuestionnairesServiceImpl implements QuestionnairesService {
2334

35+
static final Logger logger = LogManager.getLogger(QuestionnairesServiceImpl.class);
2436
@Autowired
2537
private QuestionnairesServiceQuery questionnaireServiceQuery;
2638

39+
2740
public List<JSONObject> getQuestionnaireList() throws Exception {
2841
List<JSONObject> questionnaires = questionnaireServiceQuery.getQuestionnaires();
2942
if (questionnaires.isEmpty()) {
@@ -61,7 +74,22 @@ public JSONObject getQuestionnaireByID(String id) throws Exception {
6174
}
6275
return questionnaire;
6376
}
64-
77+
78+
@Override
79+
public JSONObject getQuestionnaireByIDWithReferences(String id) throws Exception {
80+
JSONObject jsonQuestionnaire = this.getQuestionnaireByID(id);
81+
return getQuestionnaireWithReferences(jsonQuestionnaire);
82+
}
83+
84+
@Override
85+
public JSONObject getQuestionnaireWithReferences(JSONObject jsonQuestionnaire) throws Exception {
86+
Questionnaire questionnaireWithReferences = this.deReference(jsonQuestionnaire);
87+
JSONObject jsonQuestionnaireWithReferences = (JSONObject) new JSONParser().parse(
88+
PoguesSerializer.questionnaireJavaToString(questionnaireWithReferences)
89+
);
90+
return jsonQuestionnaireWithReferences;
91+
}
92+
6593
public JSONObject getJsonLunaticByID(String id) throws Exception {
6694
JSONObject questionnaireLunatic = this.questionnaireServiceQuery.getJsonLunaticByID(id);
6795
if (null == questionnaireLunatic) {
@@ -109,4 +137,32 @@ public void updateJsonLunatic(String id, JSONObject dataLunatic) throws Exceptio
109137
throw new PoguesException(404, "Not found", e.getMessage());
110138
}
111139
}
140+
141+
public Questionnaire deReference(JSONObject jsonQuestionnaire) throws Exception {
142+
143+
Questionnaire questionnaire = PoguesDeserializer.questionnaireToJavaObject(jsonQuestionnaire);
144+
List<String> references = JSONFunctions.getChildReferencesFromQuestionnaire(jsonQuestionnaire);
145+
deReference(references, questionnaire);
146+
return questionnaire;
147+
}
148+
149+
private void deReference(List<String> references, Questionnaire questionnaire) throws Exception {
150+
for (String reference : references) {
151+
JSONObject referencedJsonQuestionnaire = this.getQuestionnaireByID(reference);
152+
if (referencedJsonQuestionnaire == null) {
153+
throw new NullReferenceException(String.format(
154+
"Null reference behind reference '%s' in questionnaire '%s'.",
155+
reference, questionnaire.getId()));
156+
} else {
157+
Questionnaire referencedQuestionnaire = PoguesDeserializer.questionnaireToJavaObject(referencedJsonQuestionnaire);
158+
// Coherence check
159+
if (! reference.equals(referencedQuestionnaire.getId())) {
160+
logger.warn("Reference '{}' found in questionnaire '{}' mismatch referenced questionnaire's id '{}'",
161+
reference, questionnaire.getId(), referencedQuestionnaire.getId());
162+
}
163+
//
164+
QuestionnaireComposition.insertReference(questionnaire, referencedQuestionnaire);
165+
}
166+
}
167+
}
112168
}

src/main/java/fr/insee/pogues/persistence/service/VariablesServiceImpl.java

+6-7
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,18 @@ public class VariablesServiceImpl implements VariablesService {
3333

3434
@Autowired
3535
JdbcTemplate jdbcTemplate;
36-
37-
@Autowired
38-
private QuestionnairesServiceQuery questionnaireServiceQuery;
36+
37+
@Autowired QuestionnairesService questionnairesService;
3938

4039
public VariablesServiceImpl() {}
4140

42-
public VariablesServiceImpl(QuestionnairesServiceQuery questionnairesServiceQuery) {
43-
this.questionnaireServiceQuery = questionnairesServiceQuery;
41+
public VariablesServiceImpl(QuestionnairesService questionnairesService) {
42+
this.questionnairesService = questionnairesService;
4443
}
4544

4645
public JSONArray getVariablesByQuestionnaireForPublicEnemy(String id){
4746
try {
48-
JSONObject questionnaire = questionnaireServiceQuery.getQuestionnaireByID(id);
47+
JSONObject questionnaire = questionnairesService.getQuestionnaireByIDWithReferences(id);
4948
// We test the existence of the questionnaire in repository
5049
if (questionnaire != null) {
5150
JSONObject variables = (JSONObject) questionnaire.get("Variables");
@@ -61,7 +60,7 @@ public String getVariablesByQuestionnaire(String id){
6160
StreamSource json = null;
6261
ByteArrayOutputStream baos = new ByteArrayOutputStream();
6362
try {
64-
JSONObject questionnaire = questionnaireServiceQuery.getQuestionnaireByID(id);
63+
JSONObject questionnaire = questionnairesService.getQuestionnaireByID(id);
6564
// We test the existence of the questionnaire in repository
6665
if (questionnaire != null) {
6766
logger.info("Deserializing questionnaire ");

src/main/java/fr/insee/pogues/transforms/visualize/PoguesJSONToPoguesJSONDerefImpl.java

+2-29
Original file line numberDiff line numberDiff line change
@@ -80,36 +80,9 @@ public Questionnaire transformAsQuestionnaire(String input) throws Exception {
8080
// Parse Pogues json questionnaire
8181
JSONParser parser = new JSONParser();
8282
JSONObject jsonQuestionnaire = (JSONObject) parser.parse(input);
83-
// Get referenced questionnaire identifiers
84-
// TODO: The "childQuestionnaireRef" in the json should be supported by Pogues-Model
85-
List<String> references = JSONFunctions.getChildReferencesFromQuestionnaire(jsonQuestionnaire);
86-
// Deserialize json into questionnaire object
87-
Questionnaire questionnaire = PoguesDeserializer.questionnaireToJavaObject(jsonQuestionnaire);
88-
//
89-
deReference(references, questionnaire);
90-
logger.info("Sequences inserted");
91-
//
92-
return questionnaire;
83+
JSONObject questionnaireWithRef = questionnairesService.getQuestionnaireWithReferences(jsonQuestionnaire);
84+
return PoguesDeserializer.questionnaireToJavaObject(questionnaireWithRef);
9385
}
9486

95-
private void deReference(List<String> references, Questionnaire questionnaire) throws Exception {
96-
for (String reference : references) {
97-
JSONObject referencedJsonQuestionnaire = questionnairesService.getQuestionnaireByID(reference);
98-
if (referencedJsonQuestionnaire == null) {
99-
throw new NullReferenceException(String.format(
100-
"Null reference behind reference '%s' in questionnaire '%s'.",
101-
reference, questionnaire.getId()));
102-
} else {
103-
Questionnaire referencedQuestionnaire = PoguesDeserializer.questionnaireToJavaObject(referencedJsonQuestionnaire);
104-
// Coherence check
105-
if (! reference.equals(referencedQuestionnaire.getId())) {
106-
logger.warn("Reference '{}' found in questionnaire '{}' mismatch referenced questionnaire's id '{}'",
107-
reference, questionnaire.getId(), referencedQuestionnaire.getId());
108-
}
109-
//
110-
QuestionnaireComposition.insertReference(questionnaire, referencedQuestionnaire);
111-
}
112-
}
113-
}
11487

11588
}

src/main/java/fr/insee/pogues/webservice/rest/PoguesPersistence.java

+17-4
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
import fr.insee.pogues.config.auth.user.User;
55
import fr.insee.pogues.persistence.service.QuestionnairesService;
66
import fr.insee.pogues.persistence.service.VariablesService;
7+
import fr.insee.pogues.transforms.visualize.PoguesJSONToPoguesJSONDeref;
78
import io.swagger.v3.oas.annotations.Operation;
89
import io.swagger.v3.oas.annotations.media.Content;
910
import io.swagger.v3.oas.annotations.responses.ApiResponse;
1011
import io.swagger.v3.oas.annotations.responses.ApiResponses;
1112
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
1213
import io.swagger.v3.oas.annotations.tags.Tag;
13-
import java.util.ArrayList;
14-
import java.util.List;
14+
15+
import java.util.*;
1516

1617
import javax.ws.rs.Consumes;
1718
import javax.ws.rs.Produces;
@@ -21,6 +22,7 @@
2122
import org.apache.logging.log4j.Logger;
2223
import org.json.simple.JSONArray;
2324
import org.json.simple.JSONObject;
25+
import org.json.simple.parser.JSONParser;
2426
import org.springframework.beans.factory.annotation.Autowired;
2527
import org.springframework.core.env.Environment;
2628
import org.springframework.http.HttpStatus;
@@ -73,6 +75,14 @@ public class PoguesPersistence {
7375
private static final String BAD_REQUEST = "Bad Request";
7476
private static final String MESSAGE_INVALID_IDENTIFIER = "Identifier %s is invalid";
7577

78+
/**
79+
* @param id: the id of questionnaire
80+
* @param references (false by default): this param indicates if you want the complete questionnaire
81+
* A questionnaire may be "contain" other questionnaires. These questionnaires appear as references.
82+
* This end-point makes it possible to obtain the complete questionnaire, by replacing the references with the complete questionnaires.
83+
* @return the json representation of questionnaire (and potentially its references according to references param)
84+
* @throws Exception
85+
*/
7686
@GetMapping("questionnaire/{id}")
7787
@Produces(MediaType.APPLICATION_JSON)
7888
@Operation(
@@ -85,9 +95,12 @@ public class PoguesPersistence {
8595
@ApiResponse(responseCode = "404", description = "Not found")
8696
})
8797
public ResponseEntity<Object> getQuestionnaire(
88-
@PathVariable(value = "id") String id
98+
@PathVariable(value = "id") String id,
99+
@RequestParam(name = "references", defaultValue = "false") Boolean references
89100
) throws Exception {
90-
JSONObject result = questionnaireService.getQuestionnaireByID(id);
101+
JSONObject result = references ?
102+
questionnaireService.getQuestionnaireByIDWithReferences(id) :
103+
questionnaireService.getQuestionnaireByID(id);
91104
return ResponseEntity.status(HttpStatus.OK).body(result);
92105
}
93106

src/test/java/fr/insee/pogues/persistence/service/VariablesServiceImplTest.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ void getVariables() throws Exception {
2626
String stringQuestionnaire = Files.readString(Path.of(url.toURI()));
2727
JSONObject jsonQuestionnaire = (JSONObject) new JSONParser().parse(stringQuestionnaire);
2828
// Mock questionnaire service
29-
QuestionnairesServiceQuery questionnairesServiceQuery = Mockito.mock(QuestionnairesServiceQuery.class);
30-
Mockito.when(questionnairesServiceQuery.getQuestionnaireByID("l4i3m6qa")).thenReturn(jsonQuestionnaire);
29+
QuestionnairesService questionnairesService = Mockito.mock(QuestionnairesService.class);
30+
Mockito.when(questionnairesService.getQuestionnaireByID("l4i3m6qa")).thenReturn(jsonQuestionnaire);
3131

3232
// When
33-
VariablesServiceImpl variablesService = new VariablesServiceImpl(questionnairesServiceQuery);
33+
VariablesServiceImpl variablesService = new VariablesServiceImpl(questionnairesService);
3434
String result = variablesService.getVariablesByQuestionnaire("l4i3m6qa");
3535

3636
// Then
@@ -56,11 +56,11 @@ void getVariablesForPublicEnemy() throws Exception {
5656
String stringQuestionnaire = Files.readString(Path.of(url.toURI()));
5757
JSONObject jsonQuestionnaire = (JSONObject) new JSONParser().parse(stringQuestionnaire);
5858
// Mock questionnaire service
59-
QuestionnairesServiceQuery questionnairesServiceQuery = Mockito.mock(QuestionnairesServiceQuery.class);
60-
Mockito.when(questionnairesServiceQuery.getQuestionnaireByID("l4i3m6qa")).thenReturn(jsonQuestionnaire);
59+
QuestionnairesService questionnairesService = Mockito.mock(QuestionnairesService.class);
60+
Mockito.when(questionnairesService.getQuestionnaireByIDWithReferences("l4i3m6qa")).thenReturn(jsonQuestionnaire);
6161

6262
// When
63-
VariablesServiceImpl variablesService = new VariablesServiceImpl(questionnairesServiceQuery);
63+
VariablesServiceImpl variablesService = new VariablesServiceImpl(questionnairesService);
6464
JSONArray result = variablesService.getVariablesByQuestionnaireForPublicEnemy("l4i3m6qa");
6565

6666
// Then
@@ -78,11 +78,11 @@ public MockedException() {
7878
@Test
7979
void getVariables_exceptionDuringQuestionnaireQuery_shouldReturnNull() throws Exception {
8080
// Given
81-
QuestionnairesServiceQuery questionnairesServiceQuery = Mockito.mock(QuestionnairesServiceQuery.class);
82-
Mockito.when(questionnairesServiceQuery.getQuestionnaireByID("foo-id")).thenThrow(new MockedException());
81+
QuestionnairesService questionnairesService = Mockito.mock(QuestionnairesService.class);
82+
Mockito.when(questionnairesService.getQuestionnaireByID("foo-id")).thenThrow(new MockedException());
8383

8484
// When
85-
VariablesServiceImpl variablesService = new VariablesServiceImpl(questionnairesServiceQuery);
85+
VariablesServiceImpl variablesService = new VariablesServiceImpl(questionnairesService);
8686
String result = variablesService.getVariablesByQuestionnaire("foo-id");
8787

8888
// Then
@@ -92,11 +92,11 @@ void getVariables_exceptionDuringQuestionnaireQuery_shouldReturnNull() throws Ex
9292
@Test
9393
void getVariablesForPublicEnemy_exceptionDuringQuestionnaireQuery_shouldReturnNull() throws Exception {
9494
// Given
95-
QuestionnairesServiceQuery questionnairesServiceQuery = Mockito.mock(QuestionnairesServiceQuery.class);
96-
Mockito.when(questionnairesServiceQuery.getQuestionnaireByID("foo-id")).thenThrow(new MockedException());
95+
QuestionnairesService questionnairesService = Mockito.mock(QuestionnairesService.class);
96+
Mockito.when(questionnairesService.getQuestionnaireByID("foo-id")).thenThrow(new MockedException());
9797

9898
// When
99-
VariablesServiceImpl variablesService = new VariablesServiceImpl(questionnairesServiceQuery);
99+
VariablesServiceImpl variablesService = new VariablesServiceImpl(questionnairesService);
100100
JSONArray result = variablesService.getVariablesByQuestionnaireForPublicEnemy("foo-id");
101101

102102
// Then

0 commit comments

Comments
 (0)