From 77f620e1855455bed6cb47f2d5f3e1b866b4e201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Bourgeois?= Date: Thu, 14 Dec 2023 17:36:46 +0100 Subject: [PATCH] WS ddiFragment/uuid/withChildren --- Dockerfile | 2 +- .../ToColecticaApi/controller/GetItem.java | 11 ++ .../models/NamespaceContextMap.java | 32 +++++ .../service/ColecticaService.java | 2 + .../service/ColecticaServiceImpl.java | 120 +++++++++++++++--- 5 files changed, 151 insertions(+), 16 deletions(-) create mode 100644 src/main/java/fr/insee/rmes/ToColecticaApi/models/NamespaceContextMap.java diff --git a/Dockerfile b/Dockerfile index 0bfca54d..1bec60a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,5 +6,5 @@ RUN mvn -B -f /DDI-Access-Services/pom.xml package MAINTAINER hugobouttes FROM openjdk:17-alpine -COPY --from=mvn DDI-Access-Services/target/rmes-0.0.10-BetaElastic.jar app.jar +COPY --from=mvn DDI-Access-Services/target/rmes-0.1.10-BetaElastic.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/src/main/java/fr/insee/rmes/ToColecticaApi/controller/GetItem.java b/src/main/java/fr/insee/rmes/ToColecticaApi/controller/GetItem.java index 439c2a48..46f7f2e3 100644 --- a/src/main/java/fr/insee/rmes/ToColecticaApi/controller/GetItem.java +++ b/src/main/java/fr/insee/rmes/ToColecticaApi/controller/GetItem.java @@ -60,7 +60,18 @@ public ResponseEntity FindFragmentByUuidColectica ( } + @GetMapping("ddiFragment/uuid/withChildren") + @Operation(summary = "Get Fragment by uuid", description = "Get an XML document for a ddi:Fragment from Colectica repository.") + @Produces(MediaType.APPLICATION_XML) + public String FindFragmentByUuidWithChildrenColectica ( + @Parameter( + description = "id de l'objet colectica", + required = true, + schema = @Schema( + type = "string", example="d6c08ec1-c4d2-4b9a-b358-b23aa4e0af93")) String uuid) throws Exception { + return colecticaService.findFragmentByUuidWithChildren(uuid); + } @GetMapping("/filtered-search/texte") @Operation(summary = "Get list of match in elasticsearch database", description = "Get a JSON ") diff --git a/src/main/java/fr/insee/rmes/ToColecticaApi/models/NamespaceContextMap.java b/src/main/java/fr/insee/rmes/ToColecticaApi/models/NamespaceContextMap.java new file mode 100644 index 00000000..ba633a01 --- /dev/null +++ b/src/main/java/fr/insee/rmes/ToColecticaApi/models/NamespaceContextMap.java @@ -0,0 +1,32 @@ +package fr.insee.rmes.ToColecticaApi.models; + +import javax.xml.namespace.NamespaceContext; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class NamespaceContextMap implements NamespaceContext { + private final Map prefixMap; + + public NamespaceContextMap(String... mappings) { + prefixMap = new HashMap<>(); + for (int i = 0; i < mappings.length; i += 2) { + prefixMap.put(mappings[i], mappings[i + 1]); + } + } + + @Override + public String getNamespaceURI(String prefix) { + return prefixMap.getOrDefault(prefix, ""); + } + + @Override + public String getPrefix(String namespaceURI) { + throw new UnsupportedOperationException(); + } + + @Override + public Iterator getPrefixes(String namespaceURI) { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file diff --git a/src/main/java/fr/insee/rmes/ToColecticaApi/service/ColecticaService.java b/src/main/java/fr/insee/rmes/ToColecticaApi/service/ColecticaService.java index 0d5b3bb1..3f6d4c75 100644 --- a/src/main/java/fr/insee/rmes/ToColecticaApi/service/ColecticaService.java +++ b/src/main/java/fr/insee/rmes/ToColecticaApi/service/ColecticaService.java @@ -13,6 +13,8 @@ public interface ColecticaService { ResponseEntity findFragmentByUuid(String uuid); + String findFragmentByUuidWithChildren(String uuid) throws Exception; + ResponseEntity findInstanceByUuid(String uuid); ResponseEntity filteredSearchText(String index, String texte); diff --git a/src/main/java/fr/insee/rmes/ToColecticaApi/service/ColecticaServiceImpl.java b/src/main/java/fr/insee/rmes/ToColecticaApi/service/ColecticaServiceImpl.java index ee685cf3..7de78328 100644 --- a/src/main/java/fr/insee/rmes/ToColecticaApi/service/ColecticaServiceImpl.java +++ b/src/main/java/fr/insee/rmes/ToColecticaApi/service/ColecticaServiceImpl.java @@ -7,10 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import fr.insee.rmes.ToColecticaApi.models.AuthRequest; -import fr.insee.rmes.ToColecticaApi.models.CustomMultipartFile; -import fr.insee.rmes.ToColecticaApi.models.RessourcePackage; -import fr.insee.rmes.ToColecticaApi.models.TransactionType; +import fr.insee.rmes.ToColecticaApi.models.*; import fr.insee.rmes.ToColecticaApi.randomUUID; import fr.insee.rmes.config.keycloak.KeycloakServices; import fr.insee.rmes.metadata.exceptions.ExceptionColecticaUnreachable; @@ -21,7 +18,8 @@ import net.sf.saxon.s9api.Processor; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.http.HttpResponse; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; @@ -30,6 +28,7 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; +import org.json.JSONArray; import org.json.JSONObject; import org.json.simple.parser.JSONParser; import org.springframework.beans.factory.annotation.Autowired; @@ -39,8 +38,6 @@ import org.springframework.http.*; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.RestTemplate; @@ -59,6 +56,9 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; import java.io.*; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -88,7 +88,7 @@ public class ColecticaServiceImpl implements ColecticaService { @Value("${fr.insee.rmes.api.remote.metadata.agency}") private String agency; - @Value("${fr.insee.rmes.elasticsearch.host}") + @Value("${fr.insee.rmes.elasticsearch.host}") private String elasticHost; @Value("${fr.insee.rmes.elasticsearch.port}") @@ -172,8 +172,101 @@ public ResponseEntity findInstanceByUuid(String uuid) { } } + @Override + public String findFragmentByUuidWithChildren(String uuid) throws Exception { + ResponseEntity responseEntity = searchColecticaInstanceByUuid(uuid); + + if (responseEntity.getStatusCode().is2xxSuccessful()) { + String responseBody = (String) responseEntity.getBody(); + Set resultIntermediaire = extractUniqueIdentifiers(responseBody); + JSONArray resultArray = processUuidsAndFetchData(resultIntermediaire); + return resultArray.toString(4); + } else { + return "L'objet n'existe pas"; + } + } + + public Set extractUniqueIdentifiers(String xmlResponse) throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(new ByteArrayInputStream(xmlResponse.getBytes())); + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + + xpath.setNamespaceContext(new NamespaceContextMap( + "r", "ddi:reusable:3_3", + "ddi", "ddi:instance:3_3" + )); + + Set identifiers = new HashSet<>(); + + // Extraire tous les UUIDs + NodeList idNodes = (NodeList) xpath.evaluate("//r:ID", document, XPathConstants.NODESET); + for (int i = 0; i < idNodes.getLength(); i++) { + identifiers.add(idNodes.item(i).getTextContent()); + } + + return identifiers; + } + + public JSONArray processUuidsAndFetchData(Set uuids) { + JSONArray dataArray = new JSONArray(); + + for (String uuid : uuids) { + ResponseEntity responseEntity = searchColecticaFragmentByUuid(uuid); + if (responseEntity.getStatusCode().is2xxSuccessful()) { + String fragmentXml = (String) responseEntity.getBody(); + JSONObject fragmentData = extractDataFromFragment(fragmentXml); + dataArray.put(fragmentData); + } else { + System.out.println("Erreur ou élément non trouvé pour UUID: " + uuid); + } + } + + return dataArray; + } + + private JSONObject extractDataFromFragment(String fragmentXml) { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(new ByteArrayInputStream(fragmentXml.getBytes(StandardCharsets.UTF_8))); + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + + xpath.setNamespaceContext(new NamespaceContextMap("r", "ddi:reusable:3_3", "ddi", "ddi:instance:3_3")); + + Node firstElement = (Node) xpath.evaluate("/*/*[1]", document, XPathConstants.NODE); + String itemType = firstElement.getLocalName(); + String id = xpath.evaluate("//r:ID", firstElement); + String agency = xpath.evaluate("//r:Agency", firstElement); + String version = xpath.evaluate("//r:Version", firstElement); + + JSONObject fragmentData = new JSONObject(); + fragmentData.put("Identifier", id); + fragmentData.put("AgencyId", agency); + fragmentData.put("Version", version); + fragmentData.put("ItemType", itemType); + + return fragmentData; + } catch (Exception e) { + e.printStackTrace(); + return new JSONObject(); + } + } + private ResponseEntity searchColecticaInstanceByUuid(String uuid) { - try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + // Configuration pour ignorer les cookies invalides + RequestConfig globalConfig = RequestConfig.custom() + .setCookieSpec(CookieSpecs.IGNORE_COOKIES) + .build(); + + try (CloseableHttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(globalConfig) + .build()) { + HttpGet httpGet; String authentToken; String url = String.format("%s/api/v1/ddiset/%s/%s", serviceUrl, agency, uuid); @@ -187,6 +280,7 @@ private ResponseEntity searchColecticaInstanceByUuid(String uuid) { authentToken = extractAccessToken(token2); httpGet.setHeader("Authorization", "Bearer " + authentToken); } + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { String preresponseBody = EntityUtils.toString(response.getEntity()); String responseBody = preresponseBody.replace("",""); @@ -455,12 +549,8 @@ public String convertXmlToJson(String uuid) throws ExceptionColecticaUnreachable } @Override - public String replaceXmlParameters(@RequestBody String inputXml, - @RequestParam("Type") DDIItemType type, - @RequestParam ("Label") String label, - @RequestParam ("Version") int version, - @RequestParam ("Name") String name, - @RequestParam ("VersionResponsibility") String idepUtilisateur) { + public String replaceXmlParameters(String inputXml, DDIItemType type, String label, int version,String name, + String idepUtilisateur) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();