diff --git a/pom.xml b/pom.xml index 02054a40b..162879797 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ fr.insee.rmes Bauhaus-BO jar - 4.1.6 + 4.1.7-beta Bauhaus-Back-Office Back-office services for Bauhaus https://github.com/InseeFr/Bauhaus-Back-Office diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/FileSystemOperation.java b/src/main/java/fr/insee/rmes/bauhaus_services/FileSystemOperation.java index 1be00cb9a..7afdd0b6a 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/FileSystemOperation.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/FileSystemOperation.java @@ -22,16 +22,16 @@ public void delete(String path) { try { Files.delete(Paths.get(path)); } catch (IOException e) { - throw new RmesFileException("Failed to delete file: " + path, e); + throw new RmesFileException(path, "Failed to delete file: " + path, e); } } @Override - public InputStream read(String fileName) { + public byte[] read(String fileName) { try { - return Files.newInputStream(Paths.get(config.getDocumentsStorageGestion()).resolve(fileName)); + return Files.readAllBytes(Paths.get(config.getDocumentsStorageGestion()).resolve(fileName)); } catch (IOException e) { - throw new RmesFileException("Failed to read file: " + fileName, e); + throw new RmesFileException(fileName, "Failed to read file: " + fileName, e); } } @@ -40,7 +40,7 @@ public void write(InputStream content, Path destPath) { try { Files.copy(content, destPath, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { - throw new RmesFileException("Failed to write file: " + destPath, e); + throw new RmesFileException(destPath.toString(),"Failed to write file: " + destPath, e); } } @@ -51,7 +51,7 @@ public void copy(String srcPath, String destPath) { try { Files.copy(file, targetPath.resolve(file.getFileName()), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { - throw new RmesFileException("Failed to copy file : " + srcPath + " to " + destPath, e); + throw new RmesFileException(srcPath, "Failed to copy file : " + srcPath + " to " + destPath, e); } } @@ -59,4 +59,9 @@ public void copy(String srcPath, String destPath) { public boolean dirExists(Path gestionStorageFolder) { return Files.isDirectory(requireNonNull(gestionStorageFolder)); } + + @Override + public boolean exists(Path path) { + return false; + } } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/FilesOperations.java b/src/main/java/fr/insee/rmes/bauhaus_services/FilesOperations.java index 7f7f6453f..7b7ca79f7 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/FilesOperations.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/FilesOperations.java @@ -5,9 +5,11 @@ public interface FilesOperations { void delete(String path); - InputStream read(String path); + byte[] read(String path); void write(InputStream content, Path destPath); void copy(String srcPath, String destPath); boolean dirExists(Path gestionStorageFolder); + + boolean exists(Path path); } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/MinioFilesOperation.java b/src/main/java/fr/insee/rmes/bauhaus_services/MinioFilesOperation.java index 0b794034e..fdb6d7d31 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/MinioFilesOperation.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/MinioFilesOperation.java @@ -3,8 +3,6 @@ import fr.insee.rmes.exceptions.RmesFileException; import io.minio.*; import io.minio.errors.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; @@ -12,62 +10,65 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; -public record MinioFilesOperation(MinioClient minioClient, String bucketName, String directoryGestion, String directoryPublication) implements FilesOperations { +import static java.util.Objects.requireNonNull; - private static final Logger logger = LoggerFactory.getLogger(MinioFilesOperation.class); +public record MinioFilesOperation(MinioClient minioClient, String bucketName, String directoryGestion, String directoryPublication) implements FilesOperations { @Override - public InputStream read(String pathFile){ - String objectName= extractFileName(pathFile); - - try { - return minioClient.getObject(GetObjectArgs.builder() - .bucket(bucketName) - .object(directoryGestion +"/"+ objectName) - .build()); + public byte[] read(String pathFile){ + String objectName = getObjectName(requireNonNull(pathFile)); + try(InputStream inputStream = minioClient.getObject(GetObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build())) { + return inputStream.readAllBytes(); } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) { - throw new RmesFileException("Error reading file: " + objectName, e); + throw new RmesFileException(pathFile, "Error reading file: " + pathFile+" as object `"+objectName+"` in bucket "+bucketName, e); } } - private static String extractFileName(String filePath) { - if (filePath == null || filePath.isEmpty()) { - return ""; - } - return Path.of(filePath).getFileName().toString(); + + private String getObjectName(String pathFile) { + return getObjectName(Path.of(pathFile)); + } + + private String getObjectName(Path pathFile) { + return directoryGestion + "/" + pathFile.getFileName().toString(); } @Override - public void write(InputStream content, Path objectName) { + public void write(InputStream content, Path filePath) { + String objectName = getObjectName(requireNonNull(filePath)); try { minioClient.putObject(PutObjectArgs.builder() .bucket(bucketName) - .object(directoryGestion +"/"+ objectName.getFileName().toString()) + .object(objectName) .stream(content, content.available(), -1) .build()); } catch (IOException | ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException e) { - throw new RmesFileException("Error writing file: " + objectName, e); + throw new RmesFileException(filePath.toString(), "Error writing file: " + filePath+ "as object `"+objectName+"` in bucket "+bucketName, e); } } @Override public void copy(String srcObjectName, String destObjectName) { + String srcObject = getObjectName(requireNonNull(srcObjectName)); + String destObject = getObjectName(requireNonNull(srcObjectName)); try { CopySource source = CopySource.builder() .bucket(bucketName) - .object(directoryGestion +"/"+ extractFileName(srcObjectName)) + .object(srcObject) .build(); - minioClient.copyObject(CopyObjectArgs.builder() .bucket(bucketName) - .object(directoryPublication +"/"+ extractFileName(srcObjectName)) + .object(destObject) .source(source) .build()); } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) { - throw new RmesFileException("Error copying file from " + srcObjectName + " to " + destObjectName, e); + throw new RmesFileException(srcObjectName,"Error copying file from `" + srcObject + "` to `" + destObject+"` in bucket "+bucketName, e); } } @@ -77,7 +78,20 @@ public boolean dirExists(Path gestionStorageFolder) { return true; } - @Override + @Override + public boolean exists(Path path) { + var objectName = getObjectName(requireNonNull(path)); + try { + return minioClient.statObject(StatObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build()).size() > 0; + } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) { + return false; + } + } + + @Override public void delete(String objectName) { try { minioClient.removeObject(RemoveObjectArgs.builder() @@ -85,7 +99,7 @@ public void delete(String objectName) { .object(objectName) .build()); } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) { - throw new RmesFileException("Error deleting file: " + objectName, e); + throw new RmesFileException(objectName,"Error deleting file: " + objectName+" in bucket "+bucketName, e); } } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/StampAuthorizationChecker.java b/src/main/java/fr/insee/rmes/bauhaus_services/StampAuthorizationChecker.java index 8bda2da36..57790af12 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/StampAuthorizationChecker.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/StampAuthorizationChecker.java @@ -136,9 +136,9 @@ private IRI findDistributionIRI(String distributionId) { private IRI findComponentIRI(String componentId) throws RmesException { JSONObject type = repoGestion.getResponseAsObject(StructureQueries.getComponentType(componentId)); String componentType = type.getString("type"); - if (componentType.equals(RdfUtils.toString(QB.ATTRIBUTE_PROPERTY))) { + if (componentType.equals(QB.ATTRIBUTE_PROPERTY.toString())) { return RdfUtils.structureComponentAttributeIRI(componentId); - } else if (componentType.equals(RdfUtils.toString(QB.DIMENSION_PROPERTY))) { + } else if (componentType.equals(QB.DIMENSION_PROPERTY.toString())) { return RdfUtils.structureComponentDimensionIRI(componentId); } else { return RdfUtils.structureComponentMeasureIRI(componentId); diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/classifications/ClassificationPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/classifications/ClassificationPublication.java index 2821cc320..797409f93 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/classifications/ClassificationPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/classifications/ClassificationPublication.java @@ -3,7 +3,6 @@ import fr.insee.rmes.bauhaus_services.Constants; import fr.insee.rmes.bauhaus_services.rdf_utils.PublicationUtils; import fr.insee.rmes.bauhaus_services.rdf_utils.RdfService; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; import fr.insee.rmes.exceptions.ErrorCodes; import fr.insee.rmes.exceptions.RmesException; import fr.insee.rmes.exceptions.RmesNotFoundException; @@ -53,7 +52,7 @@ public void transformStatementToPublish(Model model, RepositoryResult while (classifStatements.hasNext()) { Statement st = classifStatements.next(); // Triplets that don't get published - String predicate = RdfUtils.toString(st.getPredicate()); + String predicate = st.getPredicate().toString(); if (!isTripletForPublication(predicate)) { // nothing, wouldn't copy this attr } else { diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/code_list/CodeListPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/code_list/CodeListPublication.java index 185909de3..901c7047f 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/code_list/CodeListPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/code_list/CodeListPublication.java @@ -30,7 +30,7 @@ private void checkIfResourceExists(RepositoryResult statements, Resou } private boolean shouldExcludeTriplet(Statement statement){ - String pred = RdfUtils.toString(statement.getPredicate()); + String pred = statement.getPredicate().toString(); return pred.endsWith("validationState") || pred.endsWith(Constants.CREATOR) || pred.endsWith(Constants.CONTRIBUTOR) @@ -54,7 +54,7 @@ private void publishCodeListAndCodesWithConnection(Resource codeListOrCode, Repo } - String predicate = RdfUtils.toString(st.getPredicate()); + String predicate = st.getPredicate().toString(); String object = st.getObject().stringValue(); if (RDFS.SEEALSO.toString().equalsIgnoreCase(predicate)) { publishSeeAlsoTriplets(object, connection); diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/code_list/CodeListServiceImpl.java b/src/main/java/fr/insee/rmes/bauhaus_services/code_list/CodeListServiceImpl.java index 3fdd80d01..4ef9a406d 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/code_list/CodeListServiceImpl.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/code_list/CodeListServiceImpl.java @@ -267,7 +267,7 @@ private boolean checkCodeListUnicity(boolean partial, JSONObject codeList, Strin String id = codeList.getString(Constants.ID); if(!partial) { IRI seeAlso = RdfUtils.codeListIRI(CONCEPT + codeList.getString(LAST_CLASS_URI_SEGMENT)); - return repoGestion.getResponseAsBoolean(CodeListQueries.checkCodeListUnicity(id, iri, RdfUtils.toString(seeAlso), false)); + return repoGestion.getResponseAsBoolean(CodeListQueries.checkCodeListUnicity(id, iri, seeAlso.toString(), false)); } return repoGestion.getResponseAsBoolean(CodeListQueries.checkCodeListUnicity(id, iri, "", true)); } @@ -280,7 +280,7 @@ public String setCodesList(String body, boolean partial) throws RmesException { IRI codeListIri = this.generateIri(codesList, partial); - if(this.checkCodeListUnicity(partial, codesList, RdfUtils.toString(codeListIri))){ + if(this.checkCodeListUnicity(partial, codesList, codeListIri.toString())){ throw new RmesBadRequestException(CodesListErrorCodes.CODE_LIST_UNICITY, "The identifier, IRI and OWL class should be unique", ""); } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/concepts/ConceptsImpl.java b/src/main/java/fr/insee/rmes/bauhaus_services/concepts/ConceptsImpl.java index 12c6b8873..e87e807bb 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/concepts/ConceptsImpl.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/concepts/ConceptsImpl.java @@ -89,7 +89,7 @@ public String getConceptByID(String id) throws RmesException{ @Override public String getRelatedConcepts(String id) throws RmesException{ - String uriConcept = RdfUtils.toString(RdfUtils.objectIRI(ObjectType.CONCEPT,id)); + String uriConcept = RdfUtils.objectIRI(ObjectType.CONCEPT, id).toString(); JSONArray resQuery = conceptsUtils.getRelatedConcepts(uriConcept); return QueryUtils.correctEmptyGroupConcat(resQuery.toString()); } @@ -102,7 +102,7 @@ public String getRelatedConcepts(String id) throws RmesException{ */ @Override public String deleteConcept(String id) throws RmesException { - String uriConcept = RdfUtils.toString(RdfUtils.objectIRI(ObjectType.CONCEPT,id)); + String uriConcept = RdfUtils.objectIRI(ObjectType.CONCEPT, id).toString(); JSONArray graphArray = conceptsUtils.getGraphsWithConcept(uriConcept); /* check concept isn't used in several graphs */ diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/concepts/concepts/ConceptsUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/concepts/concepts/ConceptsUtils.java index 3558adf23..1c07f61a2 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/concepts/concepts/ConceptsUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/concepts/concepts/ConceptsUtils.java @@ -216,9 +216,9 @@ public JSONArray getRelatedConcepts(String id) throws RmesException{ } public HttpStatus deleteConcept(String id) throws RmesException{ - HttpStatus result = repoGestion.executeUpdate(ConceptsQueries.deleteConcept(RdfUtils.toString(RdfUtils.objectIRI(ObjectType.CONCEPT,id)),RdfUtils.conceptGraph().toString())); + HttpStatus result = repoGestion.executeUpdate(ConceptsQueries.deleteConcept(RdfUtils.objectIRI(ObjectType.CONCEPT, id).toString(),RdfUtils.conceptGraph().toString())); if (result.equals(HttpStatus.OK)) { - result = repositoryPublication.executeUpdate(ConceptsQueries.deleteConcept(RdfUtils.toString(RdfUtils.objectIRIPublication(ObjectType.CONCEPT,id)),RdfUtils.conceptGraph().toString())); + result = repositoryPublication.executeUpdate(ConceptsQueries.deleteConcept(RdfUtils.objectIRIPublication(ObjectType.CONCEPT, id).toString(),RdfUtils.conceptGraph().toString())); } return result; } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/concepts/publication/ConceptsPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/concepts/publication/ConceptsPublication.java index da25a90bc..16764dbbc 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/concepts/publication/ConceptsPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/concepts/publication/ConceptsPublication.java @@ -8,10 +8,7 @@ import fr.insee.rmes.persistance.ontologies.XKOS; import fr.insee.rmes.persistance.sparql_queries.concepts.ConceptsQueries; import org.apache.http.HttpStatus; -import org.eclipse.rdf4j.model.Literal; -import org.eclipse.rdf4j.model.Model; -import org.eclipse.rdf4j.model.Resource; -import org.eclipse.rdf4j.model.Statement; +import org.eclipse.rdf4j.model.*; import org.eclipse.rdf4j.model.impl.LinkedHashModel; import org.eclipse.rdf4j.model.vocabulary.DCTERMS; import org.eclipse.rdf4j.model.vocabulary.SKOS; @@ -80,7 +77,7 @@ private Boolean prepareOneTripleToPublicationAndCheckIfHasBroader(Model model, L Resource subject = publicationUtils.tranformBaseURIToPublish(st.getSubject()); Resource graph = st.getContext(); - String predicat = RdfUtils.toString(st.getPredicate()); + String predicat = st.getPredicate().toString(); if (PublicationUtils.stringEndsWithItemFromList(predicat,notes)) { model.add(subject, st.getPredicate(), publicationUtils.tranformBaseURIToPublish((Resource) st.getObject()), @@ -147,7 +144,7 @@ private void publishExplanatoryNotes(RepositoryConnection con, Resource note, Mo Resource graph = null; while (statements.hasNext()) { Statement st = statements.next(); - String predicat = RdfUtils.toString(st.getPredicate()); + String predicat = st.getPredicate().toString(); subject = publicationUtils.tranformBaseURIToPublish(st.getSubject()); graph = st.getContext(); if (predicat.endsWith("conceptVersion")) { @@ -214,12 +211,12 @@ public void publishCollection(JSONArray collectionsToValidate) throws RmesExcept while (statements.hasNext()) { Statement st = statements.next(); // Other URI to transform - if (RdfUtils.toString(st.getPredicate()).endsWith("member")) { + if (st.getPredicate().toString().endsWith("member")) { model.add(publicationUtils.tranformBaseURIToPublish(st.getSubject()), st.getPredicate(), publicationUtils.tranformBaseURIToPublish((Resource) st.getObject()), st.getContext()); - } else if (RdfUtils.toString(st.getPredicate()).endsWith("isValidated") - || (RdfUtils.toString(st.getPredicate()).endsWith(Constants.CREATOR)) - || (RdfUtils.toString(st.getPredicate()).endsWith(Constants.CONTRIBUTOR))) { + } else if (st.getPredicate().toString().endsWith("isValidated") + || (st.getPredicate().toString().endsWith(Constants.CREATOR)) + || (st.getPredicate().toString().endsWith(Constants.CONTRIBUTOR))) { // nothing, wouldn't copy this attr } // Literals diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/geography/GeographyServiceImpl.java b/src/main/java/fr/insee/rmes/bauhaus_services/geography/GeographyServiceImpl.java index d908746f6..debfd7184 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/geography/GeographyServiceImpl.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/geography/GeographyServiceImpl.java @@ -195,7 +195,7 @@ public String createRdfGeoFeature(GeoFeature geoFeature) throws RmesException { }); repoGestion.loadSimpleObject(geoIRI, model); - return RdfUtils.toString(geoIRI); - } + return geoIRI.toString(); + } } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/ParentUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/ParentUtils.java index 4b106b410..5808d2d87 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/ParentUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/ParentUtils.java @@ -67,7 +67,7 @@ public boolean checkIfSeriesHasSims(String uriSeries) throws RmesException { } public void checkIfParentIsASeriesWithOperations(String idParent) throws RmesException { - String uriParent = RdfUtils.toString(RdfUtils.objectIRI(ObjectType.SERIES, idParent)); + String uriParent = RdfUtils.objectIRI(ObjectType.SERIES, idParent).toString(); if (checkIfParentExists(uriParent) && checkIfSeriesHasOperation(uriParent)) throw new RmesNotAcceptableException(ErrorCodes.SERIES_OPERATION_OR_SIMS, "Cannot create Sims for a series which already has operations", idParent); } @@ -117,7 +117,7 @@ public JSONArray getSeriesCreators(String id) throws RmesException { } public JSONArray getSeriesCreators(IRI iri) throws RmesException { - return repoGestion.getResponseAsJSONList(OpSeriesQueries.getCreatorsBySeriesUri("<" + RdfUtils.toString(iri) + ">")); + return repoGestion.getResponseAsJSONList(OpSeriesQueries.getCreatorsBySeriesUri("<" + iri.toString() + ">")); } public String[] getDocumentationTargetTypeAndId(String idSims) throws RmesException { diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationExport.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationExport.java index 46eef73dd..e2f3ec1ee 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationExport.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationExport.java @@ -13,6 +13,7 @@ import fr.insee.rmes.exceptions.RmesException; import fr.insee.rmes.model.operations.Operation; import fr.insee.rmes.model.operations.Series; +import fr.insee.rmes.model.operations.documentations.Document; import fr.insee.rmes.model.operations.documentations.MSD; import fr.insee.rmes.utils.*; import org.json.JSONArray; @@ -31,7 +32,6 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.*; import java.util.stream.Collectors; @@ -41,281 +41,284 @@ @Component public class DocumentationExport { - static final Logger logger = LoggerFactory.getLogger(DocumentationExport.class); - - public static final String DOCUMENTATION = "documentation"; - final ExportUtils exportUtils; - - final SeriesUtils seriesUtils; - - final OperationsUtils operationsUtils; - - final IndicatorsUtils indicatorsUtils; - - final ParentUtils parentUtils; - - final CodeListService codeListServiceImpl; - - final OrganizationsService organizationsServiceImpl; - - final DocumentationsUtils documentationsUtils; - final DocumentsUtils documentsUtils; - static final String xslFile = "/xslTransformerFiles/sims2fodt.xsl"; - static final String xmlPatternRmes = "/xslTransformerFiles/simsRmes/rmesPatternContent.xml"; - static final String zipRmes = "/xslTransformerFiles/simsRmes/toZipForRmes.zip"; - - static final String xmlPatternLabel = "/xslTransformerFiles/simsLabel/labelPatternContent.xml"; - static final String zipLabel = "/xslTransformerFiles/simsLabel/toZipForLabel.zip"; - private final int maxLength; - - public DocumentationExport(@Value("${fr.insee.rmes.bauhaus.filenames.maxlength}") int maxLength, DocumentsUtils documentsUtils, ExportUtils exportUtils, SeriesUtils seriesUtils, OperationsUtils operationsUtils, IndicatorsUtils indicatorsUtils, ParentUtils parentUtils, CodeListService codeListServiceImpl, OrganizationsService organizationsServiceImpl, DocumentationsUtils documentationsUtils) { - this.exportUtils = exportUtils; - this.seriesUtils = seriesUtils; - this.operationsUtils = operationsUtils; - this.indicatorsUtils = indicatorsUtils; - this.parentUtils = parentUtils; - this.codeListServiceImpl = codeListServiceImpl; - this.organizationsServiceImpl = organizationsServiceImpl; - this.documentationsUtils = documentationsUtils; - this.documentsUtils = documentsUtils; - this.maxLength = maxLength; - } - - /** - * - * @param id The identifier of the report we want to export - * @param documents a boolean value indicating if we want to include the related documents to the export. - * If this value is equal to true, the export will be a .ZIP archive. If equal to false, - * the export will be a .ODT file. - */ - public ResponseEntity exportAsResponse(String id, Map xmlContent, String targetType, boolean includeEmptyFields, boolean lg1, - boolean lg2, boolean documents, String goal, int maxLength) throws RmesException { - - PatternAndZip patternAndZip = PatternAndZip.of(goal); - String parametersXML = XsltUtils.buildParams(lg1, lg2, includeEmptyFields, targetType); - xmlContent.put(Constants.PARAMETERS_FILE, parametersXML); - - Exporter exporter; - JSONObject sims = this.documentationsUtils.getDocumentationByIdSims(id); - - if (documents) { - exporter = (xml, xsl, xmlPattern, zip, documentation) -> exportAsZip(sims, xml, xsl, xmlPattern, zip, documentation, maxLength); - } else{ - String fileName = FilesUtils.generateFinalFileNameWithoutExtension(sims.getString(Constants.LABEL_LG1), maxLength); - exporter = (xml, xsl, xmlPattern, zip, documentation) -> exportUtils.exportAsODT(fileName, xml, xsl, xmlPattern, zip, documentation ); - } - return export(exporter, xmlContent, patternAndZip); - } - - public ResponseEntity exportAsZip(JSONObject sims, Map xmlContent, String xslFile, String xmlPattern, String zip, String objectType, int maxLength) throws RmesException { - String simsId = sims.getString("id"); - logger.debug("Begin to download the SIMS {} with its documents", simsId); - String fileName = FilesUtils.generateFinalFileNameWithoutExtension(sims.getString(Constants.LABEL_LG1), maxLength); - - try { - - Path directory = Files.createTempDirectory("sims"); - logger.debug("Creating tempory directory {}", directory.toString()); - Path simsDirectory = Files.createDirectory(Path.of(directory.toString(), fileName)); - logger.debug("Creating tempory directory {}", simsDirectory); - - logger.debug("Generating the InputStream for the SIMS {}", simsId); - - InputStream input = exportUtils.exportAsInputStream(fileName, xmlContent, xslFile, xmlPattern, zip, objectType, FilesUtils.ODT_EXTENSION); - if (input == null){ - logger.debug("Error when creating the export of the SIMS {}", simsId); - throw new RmesException(HttpStatus.INTERNAL_SERVER_ERROR, "Can't export this object", ""); - } - - logger.debug("Creating the .odt file for the SIMS {}", simsId); - Path tempFile = Files.createFile(Path.of(simsDirectory.toString(), fileName + FilesUtils.ODT_EXTENSION)); - Files.write(tempFile, input.readAllBytes(), StandardOpenOption.APPEND); - logger.debug("Finishing the creation of the .odt file for the SIMS {}", simsId); - - - logger.debug("Starting downloading documents for the SIMS {}", simsId); - Set missingDocuments = this.exportRubricsDocuments(sims, simsDirectory); - logger.debug("Ending downloading documents for the SIMS {}", simsId); - - logger.debug("Zipping the folder for the SIMS {}", simsId); - FilesUtils.zipDirectory(simsDirectory.toFile()); - - logger.debug("Zip created for the SIMS {}", simsId); - HttpHeaders responseHeaders = HttpUtils.generateHttpHeaders(fileName, FilesUtils.ZIP_EXTENSION); - responseHeaders.set("X-Missing-Documents", String.join(",", missingDocuments)); - Resource resource = new UrlResource(Paths.get(simsDirectory.toString(), simsDirectory.getFileName() + FilesUtils.ZIP_EXTENSION).toUri()); - return ResponseEntity.ok() - .headers(responseHeaders) - .body(resource); - } - catch (Exception exception) { - throw new RmesException(HttpStatus.INTERNAL_SERVER_ERROR, exception.getMessage(), exception.getClass().getSimpleName()); - } - } - - private Set exportRubricsDocuments(JSONObject sims, Path directory) throws IOException, RmesException { - Set history = new HashSet<>(); - JSONArray documents = documentsUtils.getDocumentsUriAndUrlForSims(sims.getString("id")); - Set missingDocuments = new HashSet<>(); - - for (int i = 0; i < documents.length(); i++) { - JSONObject document = documents.getJSONObject(i); - String url = document.getString("url").replace("file://", ""); - if(!history.contains(url)){ - history.add(url); - logger.debug("Extracting document {}", url); - - - Path documentPath = Path.of(url); - - if(!Files.exists(documentPath)){ - missingDocuments.add(document.getString("id")); - } else { - String documentFileName = FilesUtils.generateFinalFileNameWithExtension(UriUtils.getLastPartFromUri(url), maxLength); - try (InputStream inputStream = Files.newInputStream(documentPath)){ - Path documentDirectory = Path.of(directory.toString(), "documents"); - if (!Files.exists(documentDirectory)) { - logger.debug("Creating the documents folder"); - Files.createDirectory(documentDirectory); - } - - logger.debug("Writing the document {} with the name {} into the folder {}", url, documentFileName, directory.toString()); - Path documentTempFile = Files.createFile(Path.of(documentDirectory.toString(), documentFileName)); - Files.write(documentTempFile, inputStream.readAllBytes(), StandardOpenOption.APPEND); - } - } - - } - } - - return missingDocuments; - } - - private ResponseEntity export(Exporter exporter, Map xmlContent, PatternAndZip patternAndZip) throws RmesException { - return exporter.export(xmlContent, xslFile, patternAndZip.xmlPattern(), patternAndZip.zip(), DOCUMENTATION); - } - - public ResponseEntity exportXmlFiles(Map xmlContent, String targetType, boolean includeEmptyFields, boolean lg1, - boolean lg2) throws RmesException { - //Add params to xmlContents - String parametersXML = XsltUtils.buildParams(lg1, lg2, includeEmptyFields, targetType); - xmlContent.put(Constants.PARAMETERS_FILE, parametersXML); - - return exportUtils.exportFilesAsResponse(xmlContent); - } - - - public ResponseEntity exportMetadataReport(String id, Boolean includeEmptyMas, Boolean lg1, Boolean lg2, Boolean document, String goal, int maxLength) throws RmesException { - Map xmlContent = new HashMap<>(); - String targetType = getXmlContent(id, xmlContent); - String msdXML = buildShellSims(); - xmlContent.put("msdFile", msdXML); - return exportAsResponse(id, xmlContent,targetType,includeEmptyMas,lg1,lg2, document, goal, maxLength); - } - - - public ResponseEntity exportMetadataReportFiles(String id, Boolean includeEmptyMas, Boolean lg1, Boolean lg2) throws RmesException { - Map xmlContent = new HashMap<>(); - String targetType = getXmlContent(id, xmlContent); - String msdXML = buildShellSims(); - xmlContent.put("msdFile", msdXML); - return exportXmlFiles(xmlContent,targetType,includeEmptyMas,lg1,lg2); - } - - public String getXmlContent(String id, Map xmlContent) throws RmesException { - String emptyXML=XMLUtils.produceEmptyXML(); - Operation operation; - Series series; - String operationXML; - String seriesXML = emptyXML; - String indicatorXML; - - String[] target = parentUtils.getDocumentationTargetTypeAndId(id); - String targetType = target[0]; - String idDatabase = target[1]; - - List neededCodeLists=new ArrayList<>(); - - if (targetType.equals(Constants.OPERATION_UP)) { - operation=operationsUtils.getOperationById(idDatabase); - operationXML = XMLUtils.produceXMLResponse(operation); - neededCodeLists.addAll(XMLUtils.getTagValues(operationXML,Constants.TYPELIST)); - neededCodeLists.addAll(XMLUtils.getTagValues(operationXML,Constants.ACCRUAL_PERIODICITY_LIST)); - String idSeries=operation.getSeries().getId(); - series=seriesUtils.getSeriesById(idSeries,EncodingType.XML); - seriesXML = XMLUtils.produceXMLResponse(series); - neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML,Constants.TYPELIST)); - neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML,Constants.ACCRUAL_PERIODICITY_LIST)); - } else {operationXML = emptyXML;} - - - if (targetType.equals(Constants.INDICATOR_UP)) { - indicatorXML=XMLUtils.produceXMLResponse( - indicatorsUtils.getIndicatorById(idDatabase,true)); - neededCodeLists.addAll(XMLUtils.getTagValues(indicatorXML,Constants.TYPELIST)); - neededCodeLists.addAll(XMLUtils.getTagValues(indicatorXML,Constants.ACCRUAL_PERIODICITY_LIST)); - String idSeries = XMLUtils.getTagValues( - XMLUtils.getTagValues( - indicatorXML, - Constants.WASGENERATEDBY).getFirst(), - Constants.ID).getFirst(); - series=seriesUtils.getSeriesById(idSeries,EncodingType.XML); - seriesXML = XMLUtils.produceXMLResponse(series); - neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML,Constants.TYPELIST)); - neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML,Constants.ACCRUAL_PERIODICITY_LIST)); - } else {indicatorXML = emptyXML;} - - - if (targetType.equals(Constants.SERIES_UP)) { - seriesXML=XMLUtils.produceXMLResponse( - seriesUtils.getSeriesById(idDatabase,EncodingType.XML)); - neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML,Constants.TYPELIST)); - neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML,Constants.ACCRUAL_PERIODICITY_LIST)); - } - - String organizationsXML = XMLUtils.produceXMLResponse(organizationsServiceImpl.getOrganizations()); - - String simsXML=XMLUtils.produceResponse(documentationsUtils.getFullSimsForXml(id), "application/xml"); - neededCodeLists.addAll(XMLUtils.getTagValues(simsXML,Constants.CODELIST)); - - neededCodeLists = neededCodeLists.stream().distinct().collect(Collectors.toList()); - - String codeListsXML=""; - codeListsXML = codeListsXML.concat(Constants.XML_OPEN_CODELIST_TAG); - - for(String code : neededCodeLists) { - DetailedCodeList codeList = codeListServiceImpl.getCodeListAndCodesForExport(code); - codeListsXML = codeListsXML.concat(XMLUtils.produceXMLResponse(codeList)); - } - codeListsXML=codeListsXML.concat(Constants.XML_END_CODELIST_TAG); - - - xmlContent.put("simsFile", simsXML); - xmlContent.put("seriesFile", seriesXML); - xmlContent.put("operationFile", operationXML); - xmlContent.put("indicatorFile", indicatorXML); - xmlContent.put("codeListsFile", codeListsXML); - xmlContent.put("organizationsFile", organizationsXML); - return targetType; - } - - - private String buildShellSims() throws RmesException { - MSD msd= documentationsUtils.getMSD(); - return XMLUtils.produceXMLResponse(msd); - } - - private interface Exporter{ - ResponseEntity export(Map xmlContent, String xslFile, String xmlPattern, String zip, String objectType) throws RmesException; - } - - private record PatternAndZip(String xmlPattern, String zip) { - public static PatternAndZip of(String goal) throws RmesBadRequestException { - return switch (goal){ - case GOAL_RMES -> new PatternAndZip(xmlPatternRmes, zipRmes); - case GOAL_COMITE_LABEL -> new PatternAndZip(xmlPatternLabel,zipLabel); - default -> throw new RmesBadRequestException("The goal is unknown"); - }; - } - } + static final Logger logger = LoggerFactory.getLogger(DocumentationExport.class); + + public static final String DOCUMENTATION = "documentation"; + final ExportUtils exportUtils; + + final SeriesUtils seriesUtils; + + final OperationsUtils operationsUtils; + + final IndicatorsUtils indicatorsUtils; + + final ParentUtils parentUtils; + + final CodeListService codeListServiceImpl; + + final OrganizationsService organizationsServiceImpl; + + final DocumentationsUtils documentationsUtils; + final DocumentsUtils documentsUtils; + + static final String xslFile = "/xslTransformerFiles/sims2fodt.xsl"; + static final String xmlPatternRmes = "/xslTransformerFiles/simsRmes/rmesPatternContent.xml"; + static final String zipRmes = "/xslTransformerFiles/simsRmes/toZipForRmes.zip"; + + static final String xmlPatternLabel = "/xslTransformerFiles/simsLabel/labelPatternContent.xml"; + static final String zipLabel = "/xslTransformerFiles/simsLabel/toZipForLabel.zip"; + private final int maxLength; + + public DocumentationExport(@Value("${fr.insee.rmes.bauhaus.filenames.maxlength}") int maxLength, DocumentsUtils documentsUtils, ExportUtils exportUtils, SeriesUtils seriesUtils, OperationsUtils operationsUtils, IndicatorsUtils indicatorsUtils, ParentUtils parentUtils, CodeListService codeListServiceImpl, OrganizationsService organizationsServiceImpl, DocumentationsUtils documentationsUtils) { + this.exportUtils = exportUtils; + this.seriesUtils = seriesUtils; + this.operationsUtils = operationsUtils; + this.indicatorsUtils = indicatorsUtils; + this.parentUtils = parentUtils; + this.codeListServiceImpl = codeListServiceImpl; + this.organizationsServiceImpl = organizationsServiceImpl; + this.documentationsUtils = documentationsUtils; + this.documentsUtils = documentsUtils; + this.maxLength = maxLength; + } + + /** + * @param id The identifier of the report we want to export + * @param documents a boolean value indicating if we want to include the related documents to the export. + * If this value is equal to true, the export will be a .ZIP archive. If equal to false, + * the export will be a .ODT file. + */ + public ResponseEntity exportAsResponse(String id, Map xmlContent, String targetType, boolean includeEmptyFields, boolean lg1, + boolean lg2, boolean documents, String goal, int maxLength) throws RmesException { + + PatternAndZip patternAndZip = PatternAndZip.of(goal); + String parametersXML = XsltUtils.buildParams(lg1, lg2, includeEmptyFields, targetType); + xmlContent.put(Constants.PARAMETERS_FILE, parametersXML); + + Exporter exporter; + JSONObject sims = this.documentationsUtils.getDocumentationByIdSims(id); + + if (documents) { + exporter = (xml, xsl, xmlPattern, zip, documentation) -> exportAsZip(sims, xml, xsl, xmlPattern, zip, documentation, maxLength); + } else { + String fileName = FilesUtils.generateFinalFileNameWithoutExtension(sims.getString(Constants.LABEL_LG1), maxLength); + exporter = (xml, xsl, xmlPattern, zip, documentation) -> exportUtils.exportAsODT(fileName, xml, xsl, xmlPattern, zip, documentation); + } + return export(exporter, xmlContent, patternAndZip); + } + + public ResponseEntity exportAsZip(JSONObject sims, Map xmlContent, String xslFile, String xmlPattern, String zip, String objectType, int maxLength) throws RmesException { + String simsId = sims.getString("id"); + logger.debug("Begin to download the SIMS {} with its documents", simsId); + String fileName = FilesUtils.generateFinalFileNameWithoutExtension(sims.getString(Constants.LABEL_LG1), maxLength); + + try { + + Path directory = Files.createTempDirectory("sims"); + logger.debug("Creating tempory directory {}", directory.toString()); + Path simsDirectory = Files.createDirectory(Path.of(directory.toString(), fileName)); + logger.debug("Creating tempory directory {}", simsDirectory); + + logger.debug("Generating the InputStream for the SIMS {}", simsId); + + InputStream input = exportUtils.exportAsInputStream(fileName, xmlContent, xslFile, xmlPattern, zip, objectType, FilesUtils.ODT_EXTENSION); + if (input == null) { + logger.debug("Error when creating the export of the SIMS {}", simsId); + throw new RmesException(HttpStatus.INTERNAL_SERVER_ERROR, "Can't export this object", ""); + } + + logger.debug("Creating the .odt file for the SIMS {}", simsId); + Path tempFile = Files.createFile(Path.of(simsDirectory.toString(), fileName + FilesUtils.ODT_EXTENSION)); + Files.write(tempFile, input.readAllBytes(), StandardOpenOption.APPEND); + logger.debug("Finishing the creation of the .odt file for the SIMS {}", simsId); + + + logger.debug("Starting downloading documents for the SIMS {}", simsId); + Set missingDocuments = this.exportRubricsDocuments(sims, simsDirectory); + logger.debug("Ending downloading documents for the SIMS {}", simsId); + + logger.debug("Zipping the folder for the SIMS {}", simsId); + FilesUtils.zipDirectory(simsDirectory.toFile()); + + logger.debug("Zip created for the SIMS {}", simsId); + HttpHeaders responseHeaders = HttpUtils.generateHttpHeaders(fileName, FilesUtils.ZIP_EXTENSION); + responseHeaders.set("X-Missing-Documents", String.join(",", missingDocuments)); + Resource resource = new UrlResource(Path.of(simsDirectory.toString(), simsDirectory.getFileName() + FilesUtils.ZIP_EXTENSION).toUri()); + return ResponseEntity.ok() + .headers(responseHeaders) + .body(resource); + } catch (Exception exception) { + throw new RmesException(HttpStatus.INTERNAL_SERVER_ERROR, exception.getMessage(), exception.getClass().getSimpleName()); + } + } + + private Set exportRubricsDocuments(JSONObject sims, Path directory) throws RmesException { + JSONArray documents = documentsUtils.getDocumentsUriAndUrlForSims(sims.getString("id")); + Set missingDocuments = new HashSet<>(); + Set documentsSet = JSONUtils.stream(documents) + .map(DocumentsUtils::buildDocumentFromJson) + .collect(Collectors.toSet()); + for (Document document : documentsSet) { + extractDocumentIfExists(directory, missingDocuments, document); + } + return missingDocuments; + } + + private void extractDocumentIfExists(Path directory, Set missingDocuments, Document document) throws RmesException{ + String url = document.url(); + logger.debug("Extracting document {}", url); + if (!documentsUtils.existsInStorage(document)) { + missingDocuments.add(document.getId()); + } else { + extractExistingDocument(directory, document, url); + } + } + + private void extractExistingDocument(Path directory, Document document, String url) throws RmesException { + String documentFileName = FilesUtils.generateFinalFileNameWithExtension(document.documentFileName(), maxLength); + Path documentDirectory = Path.of(directory.toString(), "documents"); + try { + if (!Files.exists(documentDirectory)) { + logger.debug("Creating the documents folder"); + Files.createDirectory(documentDirectory); + } + logger.debug("Writing the document {} with the name {} into the folder {}", url, documentFileName, directory); + Path documentTempFile = Files.createFile(Path.of(documentDirectory.toString(), documentFileName)); + Files.write(documentTempFile, documentsUtils.retrieveDocumentFromStorage(document), StandardOpenOption.APPEND); + } catch (IOException e) { + throw new RmesException(500, "Error while writing temporary files for extraction", e.getMessage(), e); + } + } + + private ResponseEntity export(Exporter exporter, Map xmlContent, PatternAndZip patternAndZip) throws RmesException { + return exporter.export(xmlContent, xslFile, patternAndZip.xmlPattern(), patternAndZip.zip(), DOCUMENTATION); + } + + public ResponseEntity exportXmlFiles(Map xmlContent, String targetType, boolean includeEmptyFields, boolean lg1, + boolean lg2) throws RmesException { + //Add params to xmlContents + String parametersXML = XsltUtils.buildParams(lg1, lg2, includeEmptyFields, targetType); + xmlContent.put(Constants.PARAMETERS_FILE, parametersXML); + + return exportUtils.exportFilesAsResponse(xmlContent); + } + + + public ResponseEntity exportMetadataReport(String id, Boolean includeEmptyMas, Boolean lg1, Boolean lg2, Boolean document, String goal, int maxLength) throws RmesException { + Map xmlContent = new HashMap<>(); + String targetType = getXmlContent(id, xmlContent); + String msdXML = buildShellSims(); + xmlContent.put("msdFile", msdXML); + return exportAsResponse(id, xmlContent, targetType, includeEmptyMas, lg1, lg2, document, goal, maxLength); + } + + + public ResponseEntity exportMetadataReportFiles(String id, Boolean includeEmptyMas, Boolean lg1, Boolean lg2) throws RmesException { + Map xmlContent = new HashMap<>(); + String targetType = getXmlContent(id, xmlContent); + String msdXML = buildShellSims(); + xmlContent.put("msdFile", msdXML); + return exportXmlFiles(xmlContent, targetType, includeEmptyMas, lg1, lg2); + } + + public String getXmlContent(String id, Map xmlContent) throws RmesException { + String emptyXML = XMLUtils.produceEmptyXML(); + Operation operation; + Series series; + String operationXML; + String seriesXML = emptyXML; + String indicatorXML; + + String[] target = parentUtils.getDocumentationTargetTypeAndId(id); + String targetType = target[0]; + String idDatabase = target[1]; + + List neededCodeLists = new ArrayList<>(); + + if (targetType.equals(Constants.OPERATION_UP)) { + operation = operationsUtils.getOperationById(idDatabase); + operationXML = XMLUtils.produceXMLResponse(operation); + neededCodeLists.addAll(XMLUtils.getTagValues(operationXML, Constants.TYPELIST)); + neededCodeLists.addAll(XMLUtils.getTagValues(operationXML, Constants.ACCRUAL_PERIODICITY_LIST)); + String idSeries = operation.getSeries().getId(); + series = seriesUtils.getSeriesById(idSeries, EncodingType.XML); + seriesXML = XMLUtils.produceXMLResponse(series); + neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML, Constants.TYPELIST)); + neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML, Constants.ACCRUAL_PERIODICITY_LIST)); + } else { + operationXML = emptyXML; + } + + + if (targetType.equals(Constants.INDICATOR_UP)) { + indicatorXML = XMLUtils.produceXMLResponse( + indicatorsUtils.getIndicatorById(idDatabase, true)); + neededCodeLists.addAll(XMLUtils.getTagValues(indicatorXML, Constants.TYPELIST)); + neededCodeLists.addAll(XMLUtils.getTagValues(indicatorXML, Constants.ACCRUAL_PERIODICITY_LIST)); + String idSeries = XMLUtils.getTagValues( + XMLUtils.getTagValues( + indicatorXML, + Constants.WASGENERATEDBY).getFirst(), + Constants.ID).getFirst(); + series = seriesUtils.getSeriesById(idSeries, EncodingType.XML); + seriesXML = XMLUtils.produceXMLResponse(series); + neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML, Constants.TYPELIST)); + neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML, Constants.ACCRUAL_PERIODICITY_LIST)); + } else { + indicatorXML = emptyXML; + } + + + if (targetType.equals(Constants.SERIES_UP)) { + seriesXML = XMLUtils.produceXMLResponse( + seriesUtils.getSeriesById(idDatabase, EncodingType.XML)); + neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML, Constants.TYPELIST)); + neededCodeLists.addAll(XMLUtils.getTagValues(seriesXML, Constants.ACCRUAL_PERIODICITY_LIST)); + } + + String organizationsXML = XMLUtils.produceXMLResponse(organizationsServiceImpl.getOrganizations()); + + String simsXML = XMLUtils.produceResponse(documentationsUtils.getFullSimsForXml(id), "application/xml"); + neededCodeLists.addAll(XMLUtils.getTagValues(simsXML, Constants.CODELIST)); + + neededCodeLists = neededCodeLists.stream().distinct().collect(Collectors.toList()); + + String codeListsXML = ""; + codeListsXML = codeListsXML.concat(Constants.XML_OPEN_CODELIST_TAG); + + for (String code : neededCodeLists) { + DetailedCodeList codeList = codeListServiceImpl.getCodeListAndCodesForExport(code); + codeListsXML = codeListsXML.concat(XMLUtils.produceXMLResponse(codeList)); + } + codeListsXML = codeListsXML.concat(Constants.XML_END_CODELIST_TAG); + + + xmlContent.put("simsFile", simsXML); + xmlContent.put("seriesFile", seriesXML); + xmlContent.put("operationFile", operationXML); + xmlContent.put("indicatorFile", indicatorXML); + xmlContent.put("codeListsFile", codeListsXML); + xmlContent.put("organizationsFile", organizationsXML); + return targetType; + } + + + private String buildShellSims() throws RmesException { + MSD msd = documentationsUtils.getMSD(); + return XMLUtils.produceXMLResponse(msd); + } + + private interface Exporter { + ResponseEntity export(Map xmlContent, String xslFile, String xmlPattern, String zip, String objectType) throws RmesException; + } + + private record PatternAndZip(String xmlPattern, String zip) { + public static PatternAndZip of(String goal) throws RmesBadRequestException { + return switch (goal) { + case GOAL_RMES -> new PatternAndZip(xmlPatternRmes, zipRmes); + case GOAL_COMITE_LABEL -> new PatternAndZip(xmlPatternLabel, zipLabel); + default -> throw new RmesBadRequestException("The goal is unknown"); + }; + } + } } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationPublication.java index 05c7f8dd0..f90309b7a 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationPublication.java @@ -42,7 +42,7 @@ public void publishSims(String simsId) throws RmesException { while (metadataReportStatements.hasNext()) { Statement st = metadataReportStatements.next(); // Triplets that don't get published - String predicate = RdfUtils.toString(st.getPredicate()); + String predicate = st.getPredicate().toString(); if (!isTripletForPublication(predicate)) { // nothing, wouldn't copy this attr } else { diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationsRubricsUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationsRubricsUtils.java index 5b7bfde57..0fa18031b 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationsRubricsUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationsRubricsUtils.java @@ -356,7 +356,7 @@ private void addJsonDocumentToObjectRubric(JSONObject rubric, DocumentationRubri for (int i = 0; i < documents.length(); i++) { JSONObject doc = documents.getJSONObject(i); - currentDoc = docUtils.buildDocumentFromJson(doc); + currentDoc = DocumentsUtils.buildDocumentFromJson(doc); docs.add(currentDoc); } if (documentsWithRubricLang.equals(Constants.DOCUMENTS_LG1)) { diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationsUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationsUtils.java index bd3e18033..0ab34a170 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationsUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationsUtils.java @@ -176,7 +176,7 @@ public String setMetadataReport(String id, String body, boolean create) throws R // Create or update rdf IRI seriesOrIndicatorUri = targetUri; - if (RdfUtils.toString(targetUri).contains(this.operationsBaseUri)) { + if (targetUri.toString().contains(this.operationsBaseUri)) { seriesOrIndicatorUri = parentUtils.getSeriesUriByOperationId(idTarget); } if (create) { @@ -290,7 +290,7 @@ private IRI getTarget(Documentation sims) throws RmesException { if (StringUtils.isNotEmpty(sims.getIdIndicator())) { target = RdfUtils.objectIRI(ObjectType.INDICATOR, sims.getIdTarget()); } - if (!parentUtils.checkIfParentExists(RdfUtils.toString(target))) target = null; + if (!parentUtils.checkIfParentExists(target.toString())) target = null; if (target == null) { logger.error("Create or Update sims cancelled - no target"); throw new RmesException(HttpStatus.BAD_REQUEST, "Operation/Series/Indicator doesn't exist", diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsPublication.java index 51b6a327d..20422a932 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsPublication.java @@ -91,7 +91,7 @@ private Model getModelToPublish(String documentId, String filename) throws RmesE } while (documentStatements.hasNext()) { Statement st = documentStatements.next(); - if (RdfUtils.toString(st.getPredicate()).endsWith(Constants.URL)) { + if (st.getPredicate().toString().endsWith(Constants.URL)) { Resource subject = publicationUtils.tranformBaseURIToPublish(st.getSubject()); IRI predicate = RdfUtils .createIRI(publicationUtils.tranformBaseURIToPublish(st.getPredicate()).stringValue()); diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsUtils.java index 98656e17f..68d195793 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsUtils.java @@ -1,7 +1,5 @@ package fr.insee.rmes.bauhaus_services.operations.documentations.documents; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import fr.insee.rmes.bauhaus_services.Constants; import fr.insee.rmes.bauhaus_services.FilesOperations; import fr.insee.rmes.bauhaus_services.operations.ParentUtils; @@ -15,6 +13,7 @@ import fr.insee.rmes.persistance.ontologies.SCHEMA; import fr.insee.rmes.persistance.sparql_queries.operations.documentations.DocumentsQueries; import fr.insee.rmes.utils.DateUtils; +import fr.insee.rmes.utils.Deserializer; import fr.insee.rmes.utils.UriUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.rdf4j.model.IRI; @@ -25,6 +24,7 @@ import org.eclipse.rdf4j.model.vocabulary.FOAF; import org.eclipse.rdf4j.model.vocabulary.RDF; import org.eclipse.rdf4j.model.vocabulary.RDFS; +import org.jetbrains.annotations.NotNull; import org.json.JSONArray; import org.json.JSONObject; import org.slf4j.Logger; @@ -35,17 +35,14 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; -import org.springframework.util.StreamUtils; -import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -72,10 +69,10 @@ public void addDocumentsAndLinksToRubric(Model model, Resource graph, List downloadDocumentFile(String id) throws RmesException { - String filePath = getDocumentFilename(id); - - try (InputStream inputStream = filesOperations.read(filePath)) { // Lire via l'abstraction et utiliser try-with-resources - byte[] data = StreamUtils.copyToByteArray(inputStream); // Convertir InputStream en byte[] + Document document = findDocumentById(id); + var data = retrieveDocumentFromStorage(document); + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + getFileName(document.documentFileName()) + "\""); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE); - HttpHeaders headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + getFileName(filePath) + "\""); - headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE); + // return the response with document + return ResponseEntity.ok() + .headers(headers) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(new ByteArrayResource(data)); + } - // return the response with document - return ResponseEntity.ok() - .headers(headers) - .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(new ByteArrayResource(data)); - }catch (NoSuchFileException e){ - throw new RmesNotFoundException(HttpStatus.NOT_FOUND.value(), filePath+" not found", filePath+" not found"); - }catch (IOException e) { - throw new RmesException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "I/O error", "Error downloading file"); - } + public byte[] retrieveDocumentFromStorage(Document document) { + return documentDatas(document.documentFileName()); } + private byte[] documentDatas(String filePath) { + return filesOperations.read(filePath); + } private String getFileName(String path) { // Extraire juste le nom de fichier du chemin return Paths.get(path).getFileName().toString(); } + + public boolean existsInStorage(Document document) { + return filesOperations.exists(document.path()); + } + + private record DocumentBuilder(Document document) { + public Document withId(String id, boolean isLink) { + return new Document(document.labelLg1(), document.labelLg2(), document.descriptionLg1(), document().descriptionLg2(), document.dateMiseAJour(), document.langue(), document.url(), uriFromId(id, isLink), id); + } + + public static Document emptyDocument() { + return new Document(null, null, null, null, null, null, null, null, null); + } + + private String uriFromId(String id, boolean isLink) { + return (isLink ? RdfUtils.linkIRI(id) : + RdfUtils.documentIRI(id)).toString(); + } + } + + } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/families/FamilyPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/families/FamilyPublication.java index 393085863..14715ce15 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/families/FamilyPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/families/FamilyPublication.java @@ -34,7 +34,7 @@ public void publishFamily(String familyId) throws RmesException { } while (statements.hasNext()) { Statement st = statements.next(); - String pred = RdfUtils.toString(st.getPredicate()); + String pred = st.getPredicate().toString(); // Triplets that don't get published if (pred.endsWith("isValidated") || pred.endsWith("validationState") diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/famopeserind_utils/FamOpeSerIndUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/famopeserind_utils/FamOpeSerIndUtils.java index 16e326331..81e2d990e 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/famopeserind_utils/FamOpeSerIndUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/famopeserind_utils/FamOpeSerIndUtils.java @@ -35,7 +35,7 @@ public String createId() throws RmesException { } public boolean checkIfObjectExists(ObjectType type, String id) throws RmesException { - return repoGestion.getResponseAsBoolean(FamOpeSerQueries.checkIfFamOpeSerExists(RdfUtils.toString(RdfUtils.objectIRI(type, id)))); + return repoGestion.getResponseAsBoolean(FamOpeSerQueries.checkIfFamOpeSerExists(RdfUtils.objectIRI(type, id).toString())); } public IdLabelTwoLangs buildIdLabelTwoLangsFromJson(JSONObject jsonFamOpeSer) { diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/indicators/IndicatorPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/indicators/IndicatorPublication.java index 36d806750..6e5b350b5 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/indicators/IndicatorPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/indicators/IndicatorPublication.java @@ -36,7 +36,7 @@ public void publishIndicator(String indicatorId) throws RmesException { while (statements.hasNext()) { Statement st = statements.next(); // Triplets that don't get published - String pred = RdfUtils.toString(st.getPredicate()); + String pred = st.getPredicate().toString(); if (pred.endsWith("isValidated") || pred.endsWith("validationState")) { diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationPublication.java index 176288bd8..3a8ef6c91 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/operations/OperationPublication.java @@ -47,10 +47,10 @@ public void publishOperation(String operationId, JSONObject operationJson) throw while (statements.hasNext()) { Statement st = statements.next(); // Other URI to transform - if (RdfUtils.toString(st.getPredicate()).endsWith("isPartOf")) { + if (st.getPredicate().toString().endsWith("isPartOf")) { model.add(publicationUtils.tranformBaseURIToPublish(st.getSubject()), st.getPredicate(), publicationUtils.tranformBaseURIToPublish((Resource) st.getObject()), st.getContext()); - } else if (PublicationUtils.stringEndsWithItemFromList(RdfUtils.toString(st.getPredicate()), ignoredAttrs)) { + } else if (PublicationUtils.stringEndsWithItemFromList(st.getPredicate().toString(), ignoredAttrs)) { // nothing, wouldn't copy this attr } // Literals diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/operations/series/SeriesPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/operations/series/SeriesPublication.java index ad3df1ff1..348996237 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/operations/series/SeriesPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/operations/series/SeriesPublication.java @@ -65,7 +65,7 @@ public void publishSeries(String id, JSONObject series) throws RmesException { try { while (statements.hasNext()) { Statement st = statements.next(); - String pred = RdfUtils.toString(st.getPredicate()); + String pred = st.getPredicate().toString(); // Other URI to transform if (pred.endsWith("isPartOf") || diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/PublicationUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/PublicationUtils.java index 125596514..9cfc535ff 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/PublicationUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/PublicationUtils.java @@ -57,7 +57,7 @@ public void publishResource(Resource resource, Set denyList) throws Rmes try { while (statements.hasNext()) { Statement statement = statements.next(); - String predicate = RdfUtils.toString(statement.getPredicate()); + String predicate = statement.getPredicate().toString(); boolean isDeniedPredicate = !denyList.stream().filter(predicate::endsWith).toList().isEmpty(); diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RdfServicesForRdfUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RdfServicesForRdfUtils.java new file mode 100644 index 000000000..5edc2915a --- /dev/null +++ b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RdfServicesForRdfUtils.java @@ -0,0 +1,78 @@ +package fr.insee.rmes.bauhaus_services.rdf_utils; + +import fr.insee.rmes.config.Config; +import jakarta.annotation.PostConstruct; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public record RdfServicesForRdfUtils(Config config, UriUtils uriUtils) { + + @PostConstruct + public void initRdfUtils() { + RdfUtils.instance=this; + } + + String getBaseGraph(){ + return config.getBaseGraph(); + } + + String conceptGraph(){ + return config.getConceptsGraph(); + } + + String documentsGraph() { + return config.getDocumentsGraph(); + } + + String operationsGraph(){ + return config.getOperationsGraph(); + } + + String productsGraph(){ + return config.getProductsGraph(); + } + + String documentationsGraph(String id) { + return config.getDocumentationsGraph() +"/"+ id; + } + + + String documentationsGeoGraph(){ + return config.getDocumentationsGeoGraph(); + } + + String structureGraph(){ + return config.getStructuresGraph(); + } + String codesListGraph(){ + return config.getCodeListGraph(); + } + String codesListGraph(String id) { + return config.getCodeListGraph() + "/" + id; + } + String classificationSerieIRI(String id) { + return config.getBaseUriGestion() + "codes/serieDeNomenclatures/" + id; + } + + String structureComponentGraph(){ + return config.getStructuresComponentsGraph(); + } + + String conceptScheme(){ + return config.getBaseUriGestion() + config.getConceptsScheme(); + } + + public String getBaseUriGestion(ObjectType objType, String... ids) { + ArrayList elementsList = new ArrayList<>(List.of(ids)); + elementsList.addFirst(uriUtils.getBaseUriGestion(objType)); + return String.join("/", elementsList.toArray(String[]::new)); + } + + public String getBaseUriPublication(ObjectType objType, String id) { + return uriUtils.getBaseUriPublication(objType) + "/" + id; + } + +} diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RdfUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RdfUtils.java index 7d6ba2209..527d2f670 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RdfUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RdfUtils.java @@ -1,6 +1,5 @@ package fr.insee.rmes.bauhaus_services.rdf_utils; -import fr.insee.rmes.config.Config; import fr.insee.rmes.model.ValidationStatus; import fr.insee.rmes.model.notes.DatableNote; import fr.insee.rmes.model.notes.VersionableNote; @@ -17,75 +16,74 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; +// TODO Make this class a component to be injected by spring. extract in an other utility class static methods which do not depend over instance public class RdfUtils { - private RdfUtils(){} - - private static Config config; - - private static UriUtils uriUtils; + private RdfUtils(){} private static final String DATE_FORMAT = "yyyy-MM-dd"; + public static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(DATE_FORMAT); - static ValueFactory factory = SimpleValueFactory.getInstance(); + static ValueFactory factory = SimpleValueFactory.getInstance(); + static RdfServicesForRdfUtils instance; - public static BNode createBlankNode(){ return factory.createBNode(); }; + public static BNode createBlankNode(){ return factory.createBNode(); } public static String getBaseGraph(){ - return config.getBaseGraph(); + return instance.getBaseGraph(); } public static Resource conceptGraph(){ - return factory.createIRI(config.getConceptsGraph()); + return factory.createIRI(instance.conceptGraph()); } public static Resource documentsGraph() { - return factory.createIRI(config.getDocumentsGraph()); + return factory.createIRI(instance.documentsGraph()); } public static Resource operationsGraph(){ - return factory.createIRI(config.getOperationsGraph()); + return factory.createIRI(instance.operationsGraph()); } public static Resource productsGraph(){ - return factory.createIRI(config.getProductsGraph()); + return factory.createIRI(instance.productsGraph()); } public static Resource simsGraph(String id) { - return factory.createIRI(config.getDocumentationsGraph() +"/"+ id); + return factory.createIRI(instance.documentationsGraph(id)); } public static Resource simsGeographyGraph(){ - return factory.createIRI(config.getDocumentationsGeoGraph()); + return factory.createIRI(instance.documentationsGeoGraph()); } public static Resource structureGraph(){ - return factory.createIRI(config.getStructuresGraph()); + return factory.createIRI(instance.structureGraph()); } public static Resource codesListGraph(){ - return factory.createIRI(config.getCodeListGraph()); + return factory.createIRI(instance.codesListGraph()); } public static Resource codesListGraph(String id) { - return factory.createIRI(config.getCodeListGraph() + "/" + id); + return factory.createIRI(instance.codesListGraph(id)); } public static Resource classificationSerieIRI(String id) { - return factory.createIRI(config.getBaseUriGestion() + "codes/serieDeNomenclatures/" + id); + return factory.createIRI(instance.classificationSerieIRI(id)); } public static Resource structureComponentGraph(){ - return factory.createIRI(config.getStructuresComponentsGraph()); + return factory.createIRI(instance.structureComponentGraph()); } public static Resource conceptScheme(){ - return factory.createIRI(config.getBaseUriGestion() + config.getConceptsScheme()); + return factory.createIRI(instance.conceptScheme()); } - public static IRI objectIRI(ObjectType objType, String id) { - return factory.createIRI(uriUtils.getBaseUriGestion(objType) + "/" + id); + public static IRI objectIRI(ObjectType objType, String... ids) { + return factory.createIRI(instance.getBaseUriGestion(objType, ids)); } public static IRI objectIRIPublication(ObjectType objType, String id) { - return factory.createIRI(uriUtils.getBaseUriPublication(objType) + "/" + id); + return factory.createIRI(instance.getBaseUriPublication(objType, id)); } public static IRI structureComponentAttributeIRI(String id) { @@ -107,7 +105,7 @@ public static IRI conceptIRI(String id) { return objectIRI(ObjectType.CONCEPT, id); } public static IRI conceptIRI() { - return factory.createIRI(uriUtils.getBaseUriGestion(ObjectType.CONCEPT)); + return objectIRI(ObjectType.CONCEPT); } public static IRI collectionIRI(String id) { @@ -149,7 +147,7 @@ public static IRI createIRI(String uri){ public static IRI versionableNoteIRI(String conceptId, VersionableNote versionableNote) { return RdfUtils.factory.createIRI( - uriUtils.getBaseUriGestion(ObjectType.CONCEPT) + instance.getBaseUriGestion(ObjectType.CONCEPT) + "/" + conceptId + "/" + versionableNote.getPath() + "/v" + versionableNote.getVersion() @@ -159,7 +157,7 @@ public static IRI versionableNoteIRI(String conceptId, VersionableNote versionab public static IRI previousVersionableNoteIRI(String conceptId, VersionableNote versionableNote) { String version = String.valueOf(Integer.parseInt(versionableNote.getVersion()) - 1); return RdfUtils.factory.createIRI( - uriUtils.getBaseUriGestion(ObjectType.CONCEPT) + instance.getBaseUriGestion(ObjectType.CONCEPT) + "/" + conceptId + "/" + versionableNote.getPath() + "/v" + version @@ -168,7 +166,7 @@ public static IRI previousVersionableNoteIRI(String conceptId, VersionableNote v public static IRI datableNoteIRI(String conceptId, DatableNote datableNote) { String parsedDate = DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.now()); - return RdfUtils.factory.createIRI(uriUtils.getBaseUriGestion(ObjectType.CONCEPT) + "/" + conceptId + "/" + datableNote.getPath() + return factory.createIRI(instance.getBaseUriGestion(ObjectType.CONCEPT) + "/" + conceptId + "/" + datableNote.getPath() + "/" + parsedDate + "/" + datableNote.getLang()); } @@ -202,13 +200,11 @@ public static Literal setLiteralDateTime(String date) { } public static Literal setLiteralDate(String date) { - String parsedDate = new SimpleDateFormat(DATE_FORMAT).format(DateUtils.parseDate(date)); - return factory.createLiteral(parsedDate, XSD.DATE); + return factory.createLiteral(DATE_FORMATTER.format(DateUtils.parseDate(date)), XSD.DATE); } public static Literal setLiteralYear(String date) { - String parsedDate = new SimpleDateFormat(DATE_FORMAT).format(DateUtils.parseDate(date)); - return factory.createLiteral(parsedDate, XSD.GYEAR); + return factory.createLiteral(DATE_FORMATTER.format(DateUtils.parseDate(date)), XSD.GYEAR); } @@ -223,12 +219,8 @@ public static Literal setLiteralLanguage(String string) { public static IRI toURI(String string) { return factory.createIRI(string.trim()); } - - public static String toString(IRI iri) { - return iri.toString(); - } - public static void addTripleString(IRI objectURI, IRI predicat, String value, Model model, Resource graph) { + public static void addTripleString(IRI objectURI, IRI predicat, String value, Model model, Resource graph) { if (value != null && !value.isEmpty()) { model.add(objectURI, predicat, RdfUtils.setLiteralString(value), graph); } @@ -305,13 +297,6 @@ public static IRI createXSDIRI(String suffix){ return factory.createIRI("http://www.w3.org/2001/XMLSchema#", suffix); } - public static void setConfig(Config config) { - RdfUtils.config = config; - } - - public static void setUriUtils(UriUtils uriUtils){ - RdfUtils.uriUtils=uriUtils; - } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RepositoryGestion.java b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RepositoryGestion.java index 23221f3a0..ceb78f74b 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RepositoryGestion.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/RepositoryGestion.java @@ -152,7 +152,7 @@ public RepositoryResult getStatementsPredicateObject(RepositoryConnec try { statements = con.getStatements(null, predicate, object, false); } catch (RepositoryException e) { - throwsRmesException(e, "Failure get " +RdfUtils.toString(predicate) + " statements : " + object); + throwsRmesException(e, "Failure get " + predicate.toString() + " statements : " + object); } return statements; } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/UriUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/UriUtils.java index 2331a1e9f..78af15b4b 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/UriUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/rdf_utils/UriUtils.java @@ -18,7 +18,6 @@ public UriUtils(@Value("${"+BASE_URI_PUBLICATION+"}") String baseUriPublication, this.baseUriPublication=baseUriPublication; this.baseUriGestion=baseUriGestion; this.propertiesFinder=propertiesFinder; - RdfUtils.setUriUtils(this); } public String getBaseUriPublication(ObjectType objectType){ diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/structures/impl/StructureImpl.java b/src/main/java/fr/insee/rmes/bauhaus_services/structures/impl/StructureImpl.java index 507442370..c0892e54f 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/structures/impl/StructureImpl.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/structures/impl/StructureImpl.java @@ -75,15 +75,17 @@ public String getStructureByIdWithDetails(String id) throws RmesException { // We first have to rename the type property String type = (String) component.get("type"); - if(type.equalsIgnoreCase(RdfUtils.toString(QB.ATTRIBUTE_PROPERTY))){ + if(type.equalsIgnoreCase(QB.ATTRIBUTE_PROPERTY.toString())){ component.put("type", "attribute"); } - else if(type.equalsIgnoreCase(RdfUtils.toString(QB.MEASURE_PROPERTY))){ + else if(type.equalsIgnoreCase(QB.MEASURE_PROPERTY.toString())){ component.put("type", "measure"); } - else if(type.equalsIgnoreCase(RdfUtils.toString(QB.DIMENSION_PROPERTY))){ - component.put("type", "dimension"); - } + else { + if (type.equalsIgnoreCase(QB.DIMENSION_PROPERTY.toString())) { + component.put("type", "dimension"); + } + } // If the codelist is defined, we have to remove the range property and fetch the codes list if(!component.isNull(Constants.CODELIST)){ diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/ComponentPublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/ComponentPublication.java index e877c2a19..fb661116b 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/ComponentPublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/ComponentPublication.java @@ -2,7 +2,6 @@ import fr.insee.rmes.bauhaus_services.Constants; import fr.insee.rmes.bauhaus_services.rdf_utils.RdfService; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; import fr.insee.rmes.exceptions.RmesException; import org.apache.http.HttpStatus; import org.eclipse.rdf4j.model.IRI; @@ -28,7 +27,7 @@ public void publishComponent(Resource component, IRI type) throws RmesException try { while (statements.hasNext()) { Statement st = statements.next(); - String pred = RdfUtils.toString(st.getPredicate()); + String pred = st.getPredicate().toString(); if (pred.endsWith("validationState") || pred.endsWith(Constants.CONTRIBUTOR) || pred.endsWith(Constants.CREATOR)) { // nothing, wouldn't copy this attr }else if (pred.endsWith("attribute") @@ -57,7 +56,7 @@ public void publishComponent(Resource component, IRI type) throws RmesException con.close(); } Resource componentToPublishRessource = publicationUtils.tranformBaseURIToPublish(component); - repositoryPublication.publishResource(componentToPublishRessource, model, RdfUtils.toString(type)); + repositoryPublication.publishResource(componentToPublishRessource, model, type.toString()); } diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructureComponentUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructureComponentUtils.java index 7500c836c..a129e57fc 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructureComponentUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructureComponentUtils.java @@ -62,7 +62,7 @@ private void addStructures(JSONObject response, String id) throws RmesException private void addCodeListRange(JSONObject response) { if (response.has(Constants.CODELIST)) { - response.put("range", RdfUtils.toString(INSEE.CODELIST)); + response.put("range", INSEE.CODELIST.toString()); } } @@ -154,9 +154,9 @@ private void createRDFForComponent(MutualizedComponent component, ValidationStat } String type = component.getType(); - if (type.equals(RdfUtils.toString(QB.ATTRIBUTE_PROPERTY))) { + if (type.equals(QB.ATTRIBUTE_PROPERTY.toString())) { createRDFForComponent(component, QB.ATTRIBUTE_PROPERTY, RdfUtils.structureComponentAttributeIRI(component.getId()), status, jsonComponent); - } else if (type.equals(RdfUtils.toString(QB.MEASURE_PROPERTY))) { + } else if (type.equals(QB.MEASURE_PROPERTY.toString())) { createRDFForComponent(component, QB.MEASURE_PROPERTY, RdfUtils.structureComponentMeasureIRI(component.getId()), status, jsonComponent); } else { createRDFForComponent(component, QB.DIMENSION_PROPERTY, RdfUtils.structureComponentDimensionIRI(component.getId()), status, jsonComponent); @@ -206,7 +206,7 @@ private void createRDFForComponent(MutualizedComponent component, Resource resou RdfUtils.addTripleUri(componentURI, QB.CONCEPT, RdfUtils.conceptIRI() + "/" + component.getConcept(), model, graph); } - if (component.getRange() != null && component.getRange().equals(RdfUtils.toString(INSEE.CODELIST))) { + if (component.getRange() != null && component.getRange().equals(INSEE.CODELIST.toString())) { RdfUtils.addTripleUri(componentURI, RDF.TYPE, QB.CODED_PROPERTY, model, graph); JSONObject object = repoGestion.getResponseAsObject(StructureQueries.getUriClasseOwl(component.getFullCodeListValue())); @@ -250,10 +250,10 @@ else if (component.getRange().equals(XSD.STRING.stringValue())) { } private String generateNextId(String type) throws RmesException { - if (type.equals(RdfUtils.toString(QB.ATTRIBUTE_PROPERTY))) { + if (type.equals(QB.ATTRIBUTE_PROPERTY.toString())) { return generateNextId("a", "attribut", QB.ATTRIBUTE_PROPERTY); } - if (type.equals(RdfUtils.toString(QB.MEASURE_PROPERTY))) { + if (type.equals(QB.MEASURE_PROPERTY.toString())) { return generateNextId("m", "mesure", QB.MEASURE_PROPERTY); } return generateNextId("d", "dimension", QB.DIMENSION_PROPERTY); @@ -263,7 +263,7 @@ private String generateNextId(String type) throws RmesException { private String generateNextId(String prefix, String namespaceSuffix, IRI type) throws RmesException { logger.info("Generate id for component"); - JSONObject json = repoGestion.getResponseAsObject(StructureQueries.lastId(namespaceSuffix, RdfUtils.toString(type))); + JSONObject json = repoGestion.getResponseAsObject(StructureQueries.lastId(namespaceSuffix, type.toString())); logger.debug("JSON when generating the id of a component : {}", json); if (json.length() == 0) { return prefix + "1000"; diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructurePublication.java b/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructurePublication.java index e554ff287..5e412dd7d 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructurePublication.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructurePublication.java @@ -3,7 +3,6 @@ import fr.insee.rmes.bauhaus_services.Constants; import fr.insee.rmes.bauhaus_services.rdf_utils.PublicationUtils; import fr.insee.rmes.bauhaus_services.rdf_utils.RdfService; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; import fr.insee.rmes.exceptions.RmesException; import org.apache.http.HttpStatus; import org.eclipse.rdf4j.model.Model; @@ -27,7 +26,7 @@ private void copyTriplet(Resource structure, Model model, RepositoryConnection c while (statements.hasNext()) { Statement st = statements.next(); - String pred = RdfUtils.toString(st.getPredicate()); + String pred = st.getPredicate().toString(); if (PublicationUtils.stringEndsWithItemFromList(pred,denyList)) { // nothing, wouldn't copy this attr } else if(pred.endsWith("component")){ diff --git a/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructureUtils.java b/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructureUtils.java index f9b51e2d7..dbb59fe05 100644 --- a/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructureUtils.java +++ b/src/main/java/fr/insee/rmes/bauhaus_services/structures/utils/StructureUtils.java @@ -299,7 +299,7 @@ public void createRdfComponentSpecification(IRI structureIRI, ComponentDefinitio IRI componentSpecificationIRI; - componentSpecificationIRI = getComponentDefinitionIRI(RdfUtils.toString(structureIRI), componentDefinition.getId()); + componentSpecificationIRI = getComponentDefinitionIRI(structureIRI.toString(), componentDefinition.getId()); model.add(structureIRI, QB.COMPONENT, componentSpecificationIRI, graph); @@ -326,10 +326,10 @@ public void createRdfComponentSpecification(IRI structureIRI, ComponentDefinitio model.add(componentSpecificationIRI, RDFS.LABEL, RdfUtils.setLiteralString(componentDefinition.getLabelLg2(), config.getLg2()), graph); } MutualizedComponent component = componentDefinition.getComponent(); - if (component.getType().equals(RdfUtils.toString(QB.DIMENSION_PROPERTY))) { + if (component.getType().equals(QB.DIMENSION_PROPERTY.toString())) { model.add(componentSpecificationIRI, QB.DIMENSION, getDimensionIRI(component.getId()), graph); } - if (component.getType().equals(RdfUtils.toString(QB.ATTRIBUTE_PROPERTY))) { + if (component.getType().equals(QB.ATTRIBUTE_PROPERTY.toString())) { for(String attachment : componentDefinition.getAttachment()){ IRI attachmentIRI ; try { @@ -344,7 +344,7 @@ public void createRdfComponentSpecification(IRI structureIRI, ComponentDefinitio model.add(componentSpecificationIRI, QB.ATTRIBUTE, getAttributeIRI(component.getId()), graph); model.add(componentSpecificationIRI, QB.COMPONENT_REQUIRED, RdfUtils.setLiteralBoolean(componentDefinition.getRequired()), graph); } - if (component.getType().equals(RdfUtils.toString(QB.MEASURE_PROPERTY))) { + if (component.getType().equals(QB.MEASURE_PROPERTY.toString())) { model.add(componentSpecificationIRI, QB.MEASURE, getMeasureIRI(component.getId()), graph); } repoGestion.loadSimpleObject(componentSpecificationIRI, model); diff --git a/src/main/java/fr/insee/rmes/config/Config.java b/src/main/java/fr/insee/rmes/config/Config.java index 14c8e1707..f9b41d91a 100644 --- a/src/main/java/fr/insee/rmes/config/Config.java +++ b/src/main/java/fr/insee/rmes/config/Config.java @@ -128,7 +128,6 @@ public class Config { @PostConstruct private void init() { GenericQueries.setConfig(this); - RdfUtils.setConfig(this); } /******************************************************/ diff --git a/src/main/java/fr/insee/rmes/exceptions/RmesExceptionHandler.java b/src/main/java/fr/insee/rmes/exceptions/RmesExceptionHandler.java index aade896a6..ff0a73668 100644 --- a/src/main/java/fr/insee/rmes/exceptions/RmesExceptionHandler.java +++ b/src/main/java/fr/insee/rmes/exceptions/RmesExceptionHandler.java @@ -38,6 +38,12 @@ public final ResponseEntity handleRmesException(RmesException exception) return ResponseEntity.internalServerError().body(exception.getMessage()); } + @ExceptionHandler(RmesFileException.class) + public final ResponseEntity handleRmesFileException(RmesFileException exception){ + logger.error(exception.getMessage(), exception); + return ResponseEntity.internalServerError().body(exception.toString()); + } + @ExceptionHandler(NoSuchFileException.class) public final ResponseEntity handleRmesException(NoSuchFileException exception){ logger.error("NoSuchFileException "+ exception.getMessage(), exception); diff --git a/src/main/java/fr/insee/rmes/exceptions/RmesFileException.java b/src/main/java/fr/insee/rmes/exceptions/RmesFileException.java index e36357ecb..c59d6ecca 100644 --- a/src/main/java/fr/insee/rmes/exceptions/RmesFileException.java +++ b/src/main/java/fr/insee/rmes/exceptions/RmesFileException.java @@ -1,7 +1,22 @@ package fr.insee.rmes.exceptions; public class RmesFileException extends RuntimeException { - public RmesFileException(String message, Throwable cause) { + + private final String fileName; + + public RmesFileException(String filename, String message, Throwable cause) { super(message, cause); + this.fileName = filename; + } + + public String getFileName() { + return fileName; + } + + @Override + public String toString() { + return "RmesFileException{" + + "fileName='" + fileName + '\'' + + '}'; } } diff --git a/src/main/java/fr/insee/rmes/model/operations/documentations/Document.java b/src/main/java/fr/insee/rmes/model/operations/documentations/Document.java index c24081cdf..a6c7906fd 100644 --- a/src/main/java/fr/insee/rmes/model/operations/documentations/Document.java +++ b/src/main/java/fr/insee/rmes/model/operations/documentations/Document.java @@ -2,89 +2,45 @@ import com.fasterxml.jackson.annotation.JsonProperty; import fr.insee.rmes.bauhaus_services.Constants; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; -import fr.insee.rmes.utils.DateUtils; import org.apache.commons.lang3.StringUtils; -public class Document { - - private String labelLg1; - private String labelLg2; - private String descriptionLg1; - private String descriptionLg2; - private String dateMiseAJour; - private String langue; - private String url; - private String uri; +import java.net.URI; +import java.nio.file.Path; - public Document() { - } - - public Document(String id) { - this.uri = RdfUtils.toString(RdfUtils.documentIRI(id)); - } +public record Document(String labelLg1, + String labelLg2, + String descriptionLg1, + String descriptionLg2, + @JsonProperty(Constants.UPDATED_DATE) + String dateMiseAJour, + @JsonProperty("lang") + String langue, + String url, + String uri, + // TODO remove this attribute + String id) { - public Document(String id, boolean isLink) { - if (isLink) {this.uri = RdfUtils.toString(RdfUtils.linkIRI(id));} - else {this.uri = RdfUtils.toString(RdfUtils.documentIRI(id));} - } - - public String getLabelLg1() { - return labelLg1; - } - public void setLabelLg1(String labelLg1) { - this.labelLg1 = labelLg1; - } - public String getLabelLg2() { - return labelLg2; - } - public void setLabelLg2(String labelLg2) { - this.labelLg2 = labelLg2; - } - public String getDescriptionLg1() { - return descriptionLg1; - } - public void setDescriptionLg1(String descriptionLg1) { - this.descriptionLg1 = descriptionLg1; - } - public String getDescriptionLg2() { - return descriptionLg2; - } - public void setDescriptionLg2(String descriptionLg2) { - this.descriptionLg2 = descriptionLg2; - } - - @JsonProperty(Constants.UPDATED_DATE) - public String getDateMiseAJour() { - return DateUtils.getDate(dateMiseAJour); - } - public void setDateMiseAJour(String dateMiseAJour) { - this.dateMiseAJour = dateMiseAJour; - } - @JsonProperty("lang") - public String getLangue() { - return langue; - } - public void setLangue(String langue) { - this.langue = langue; - } - public String getUrl() { - return url; - } - public void setUrl(String url) { - this.url = url; - } + public String getId() { + String idFromUri = StringUtils.substringAfter(uri, "/"); + if (idFromUri != null) { + return idFromUri; + } + return id; + } + + public Document withUrl(String url) { + return new Document(this.labelLg1, this.labelLg2, this.descriptionLg1, this.descriptionLg2, this.dateMiseAJour, this.langue, url, this.uri, null); + } + + public String documentFileName() { + return path().getFileName().toString(); + } + + public Path path() { + URI uriFromUrl = URI.create(this.url); + return uriFromUrl.getScheme()==null?Path.of(this.url):Path.of(uriFromUrl); + } + - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public String getId() { - return StringUtils.substringAfter(uri, "/"); - } } \ No newline at end of file diff --git a/src/main/java/fr/insee/rmes/persistance/ontologies/QB.java b/src/main/java/fr/insee/rmes/persistance/ontologies/QB.java index 893b1c7c8..ee4c32d56 100644 --- a/src/main/java/fr/insee/rmes/persistance/ontologies/QB.java +++ b/src/main/java/fr/insee/rmes/persistance/ontologies/QB.java @@ -1,6 +1,5 @@ package fr.insee.rmes.persistance.ontologies; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Namespace; import org.eclipse.rdf4j.model.ValueFactory; @@ -72,7 +71,7 @@ private QB() { } public static String[] getURIForComponent(){ - return new String[]{RdfUtils.toString(MEASURE_PROPERTY), RdfUtils.toString(ATTRIBUTE_PROPERTY), RdfUtils.toString(DIMENSION_PROPERTY)}; + return new String[]{MEASURE_PROPERTY.toString(), ATTRIBUTE_PROPERTY.toString(), DIMENSION_PROPERTY.toString()}; } diff --git a/src/main/java/fr/insee/rmes/persistance/sparql_queries/links/LinksQueries.java b/src/main/java/fr/insee/rmes/persistance/sparql_queries/links/LinksQueries.java index b0c7d2c53..0584ad9c3 100644 --- a/src/main/java/fr/insee/rmes/persistance/sparql_queries/links/LinksQueries.java +++ b/src/main/java/fr/insee/rmes/persistance/sparql_queries/links/LinksQueries.java @@ -1,15 +1,14 @@ package fr.insee.rmes.persistance.sparql_queries.links; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; import fr.insee.rmes.persistance.sparql_queries.GenericQueries; import org.eclipse.rdf4j.model.IRI; public class LinksQueries extends GenericQueries{ public static String getLinksToDelete(IRI conceptURI) { - return "SELECT ?concept \n" + return "SELECT ?concept \n" + "WHERE { GRAPH <"+config.getConceptsGraph()+"> { \n" - + "?concept ?b <" + RdfUtils.toString(conceptURI) + "> \n" + + "?concept ?b <" + conceptURI.toString() + "> \n" + " }}"; } diff --git a/src/main/java/fr/insee/rmes/utils/Deserializer.java b/src/main/java/fr/insee/rmes/utils/Deserializer.java index b7d001d0a..aeae9861c 100644 --- a/src/main/java/fr/insee/rmes/utils/Deserializer.java +++ b/src/main/java/fr/insee/rmes/utils/Deserializer.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import fr.insee.rmes.exceptions.RmesException; -import fr.insee.rmes.model.dataset.Dataset; import org.apache.http.HttpStatus; import org.json.JSONObject; @@ -21,14 +20,14 @@ private Deserializer() { public static T deserializeJsonString(String json, Class target) throws RmesException { try { - return mapper.readValue(json, target); + T t = mapper.readValue(json, target); + return t; } catch (IOException e) { - throw new RmesException(HttpStatus.SC_BAD_REQUEST, "while " , e.getMessage()); + throw new RmesException(HttpStatus.SC_BAD_REQUEST, "while deserializing "+json , e.getMessage()); } } - //TODO Use a mapper directly from JSONObject to java class - public static Dataset deserializeJSONObject(JSONObject json, Class target) throws RmesException { + public static T deserializeJSONObject(JSONObject json, Class target) throws RmesException { return deserializeJsonString(json.toString(), target); } } \ No newline at end of file diff --git a/src/main/java/fr/insee/rmes/utils/DocumentBuilders.java b/src/main/java/fr/insee/rmes/utils/DocumentBuilders.java deleted file mode 100644 index 024c99875..000000000 --- a/src/main/java/fr/insee/rmes/utils/DocumentBuilders.java +++ /dev/null @@ -1,28 +0,0 @@ -package fr.insee.rmes.utils; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -public interface DocumentBuilders -{ - interface ParserConfigurer - { - void configureParser(DocumentBuilderFactory factory) throws ParserConfigurationException; - } - - static DocumentBuilder createSaferDocumentBuilder(ParserConfigurer parserConfigurer) throws ParserConfigurationException - { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - - factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - factory.setFeature("http://xml.org/sax/features/external-general-entities", false); - factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - factory.setXIncludeAware(false); - factory.setExpandEntityReferences(false); - parserConfigurer.configureParser(factory); - - return factory.newDocumentBuilder(); - } -} \ No newline at end of file diff --git a/src/main/java/fr/insee/rmes/utils/JSONUtils.java b/src/main/java/fr/insee/rmes/utils/JSONUtils.java index d4343fa4c..f554be3eb 100644 --- a/src/main/java/fr/insee/rmes/utils/JSONUtils.java +++ b/src/main/java/fr/insee/rmes/utils/JSONUtils.java @@ -5,7 +5,6 @@ import java.util.Iterator; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; diff --git a/src/main/java/fr/insee/rmes/utils/RestTemplateUtils.java b/src/main/java/fr/insee/rmes/utils/RestTemplateUtils.java deleted file mode 100644 index b80894d6c..000000000 --- a/src/main/java/fr/insee/rmes/utils/RestTemplateUtils.java +++ /dev/null @@ -1,121 +0,0 @@ -package fr.insee.rmes.utils; - -import fr.insee.rmes.exceptions.RmesException; -import org.apache.commons.codec.binary.Base64; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; -import org.springframework.http.*; -import org.springframework.stereotype.Service; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.client.RestTemplate; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Service -public class RestTemplateUtils { - - RestTemplate restTemplate = new RestTemplate(); - - public HttpHeaders getHeadersWithBasicAuth(String username, String password) { - // HttpHeaders - HttpHeaders headers = new HttpHeaders(); - - // Authentication - String auth = username + ":" + password; - byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.US_ASCII)); - String authHeader = "Basic " + new String(encodedAuth); - headers.set("Authorization", authHeader); - - return headers; - } - - public HttpHeaders addJsonContentToHeader(HttpHeaders headers) { - addAcceptJsonToHeader(headers); - headers.setContentType(MediaType.APPLICATION_JSON ); - return headers; - } - - - public String getResponseAsString(String target, HttpHeaders headers, Map params) { - if (params == null) return getResponseAsString(target, headers); - // HttpEntity: To get result as String. - HttpEntity entity = new HttpEntity<>(headers); - - // Send request with GET method, and Headers, and Params (can't be null). - ResponseEntity response = restTemplate.exchange(target, HttpMethod.GET, entity, String.class, params); - - return response.getBody(); - } - - public String getResponseAsString(String target, HttpHeaders headers) { - // HttpEntity: To get result as String. - HttpEntity entity = new HttpEntity<>(headers); - - // Send request with GET method, and Headers. - ResponseEntity response = restTemplate.exchange(target, HttpMethod.GET, entity, String.class); - - return response.getBody(); - } - - public void addAcceptJsonToHeader(HttpHeaders headers) { - List acceptHeaders =new ArrayList<>( headers.getAccept()); - acceptHeaders.add(MediaType.APPLICATION_JSON ); - headers.setAccept(acceptHeaders); - } - - private static Resource getFileAsResource(InputStream fileIs, String filename) throws RmesException { - try { - String tempDir = System.getProperty("java.io.tmpdir"); - Path tempFile = Paths.get(tempDir ,filename); - Files.write(tempFile, fileIs.readAllBytes()); - File file = tempFile.toFile(); - file.deleteOnExit(); - return new FileSystemResource(file); - } catch (IOException e) { - throw new RmesException(HttpStatus.INTERNAL_SERVER_ERROR, "Can't convert file to resource IOException", e.getMessage()); - } - - } - - public String postForEntity(String target, MultiValueMap body, HttpHeaders headers) throws RmesException { - - // HttpEntity>: To get result as String. - HttpEntity requestEntity = new HttpEntity<>(body, headers); - - // Send request with POST method, and Headers. - try { - ResponseEntity response = restTemplate.postForEntity(target, requestEntity, String.class); - return response.getBody(); - }catch(Exception e) { - throw new RmesException(HttpStatus.FAILED_DEPENDENCY, "SPOC error, "+ e.getClass(), e.getMessage()); - } - } - - public MultiValueMap buildBodyAsMap(String request, InputStream fileResource, String filename) throws RmesException { - MultiValueMap body = new LinkedMultiValueMap<>(); - - //add file to join to body - HttpHeaders fileheaders = new HttpHeaders(); - fileheaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); - body.add("attachments", new HttpEntity<>(getFileAsResource(fileResource, filename), fileheaders)); - - //add xml content to body - HttpHeaders contentheaders = new HttpHeaders(); - contentheaders.setContentType(MediaType.APPLICATION_XML); - body.add("request", new HttpEntity<>(request, contentheaders)); - - return body; - } - - -} diff --git a/src/main/java/fr/insee/rmes/utils/StringUtils.java b/src/main/java/fr/insee/rmes/utils/StringUtils.java index 936365407..ca760dc22 100644 --- a/src/main/java/fr/insee/rmes/utils/StringUtils.java +++ b/src/main/java/fr/insee/rmes/utils/StringUtils.java @@ -1,11 +1,9 @@ package fr.insee.rmes.utils; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; import org.eclipse.rdf4j.model.IRI; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class StringUtils { @@ -26,7 +24,7 @@ public static String urisAsString(List uris) { @NotNull private static String uriAsString(IRI uri) { - return "<" + RdfUtils.toString(uri) + ">"; + return "<" + uri.toString() + ">"; } public static String convertHtmlStringToRaw(String html) { diff --git a/src/main/java/fr/insee/rmes/utils/UriUtils.java b/src/main/java/fr/insee/rmes/utils/UriUtils.java index a69f1e4b0..87c3fce1c 100644 --- a/src/main/java/fr/insee/rmes/utils/UriUtils.java +++ b/src/main/java/fr/insee/rmes/utils/UriUtils.java @@ -1,6 +1,6 @@ package fr.insee.rmes.utils; -import org.apache.commons.lang3.StringUtils; +import java.nio.file.Path; public class UriUtils { @@ -10,8 +10,7 @@ private UriUtils() { public static String getLastPartFromUri(String uri) { - if (uri.contains("\\")) return StringUtils.substringAfterLast(uri, "\\"); - return StringUtils.substringAfterLast(uri, "/"); + return Path.of(uri).getFileName().toString(); } } diff --git a/src/main/java/fr/insee/rmes/webservice/HealthcheckApi.java b/src/main/java/fr/insee/rmes/webservice/HealthcheckApi.java index 03f6b8936..bb5544bf2 100644 --- a/src/main/java/fr/insee/rmes/webservice/HealthcheckApi.java +++ b/src/main/java/fr/insee/rmes/webservice/HealthcheckApi.java @@ -1,8 +1,10 @@ package fr.insee.rmes.webservice; +import fr.insee.rmes.bauhaus_services.FilesOperations; import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryGestion; import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryPublication; import fr.insee.rmes.exceptions.RmesException; +import fr.insee.rmes.exceptions.RmesFileException; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.apache.commons.lang3.StringUtils; @@ -16,9 +18,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; +import java.io.ByteArrayInputStream; +import java.nio.file.Path; import java.util.StringJoiner; @ApiResponses(value = { @@ -44,6 +45,8 @@ public class HealthcheckApi extends GenericResources { private final RepositoryPublication repositoryPublication; + private final FilesOperations filesOperations; + private final String documentsStoragePublicationInterne; private final String documentsStoragePublicationExterne; private final String documentsStorageGestion; @@ -53,12 +56,13 @@ public class HealthcheckApi extends GenericResources { public HealthcheckApi(@Autowired RepositoryGestion repoGestion, - @Autowired RepositoryPublication repositoryPublication, + @Autowired RepositoryPublication repositoryPublication, FilesOperations filesOperations, @Value("${fr.insee.rmes.bauhaus.storage.document.publication.interne}") String documentsStoragePublicationInterne, @Value("${fr.insee.rmes.bauhaus.storage.document.publication}") String documentsStoragePublicationExterne, @Value("${fr.insee.rmes.bauhaus.storage.document.gestion}") String documentsStorageGestion) { this.repoGestion = repoGestion; this.repositoryPublication = repositoryPublication; + this.filesOperations = filesOperations; this.documentsStoragePublicationInterne = documentsStoragePublicationInterne; this.documentsStoragePublicationExterne = documentsStoragePublicationExterne; this.documentsStorageGestion = documentsStorageGestion; @@ -73,7 +77,7 @@ public ResponseEntity getHealthcheck() { logger.info(" Begin healthCheck"); checkDatabase(errorMessage, stateResult); - checkStrorage(errorMessage, stateResult); + checkStrorage(stateResult); //print result in log @@ -89,11 +93,11 @@ public ResponseEntity getHealthcheck() { } - private void checkStrorage(StringJoiner errorMessage, StringJoiner stateResult) { + private void checkStrorage(StringJoiner stateResult) { stateResult.add("Document storage \n"); - checkDocumentStorage(this.documentsStorageGestion, "Gestion", stateResult, errorMessage); - checkDocumentStorage(this.documentsStoragePublicationExterne, "Publication Externe", stateResult, errorMessage); - checkDocumentStorage(this.documentsStoragePublicationInterne, "Publication Interne", stateResult, errorMessage); + checkDocumentStorage(this.documentsStorageGestion, "Gestion", stateResult); + checkDocumentStorage(this.documentsStoragePublicationExterne, "Publication Externe", stateResult); + checkDocumentStorage(this.documentsStoragePublicationInterne, "Publication Interne", stateResult); } protected void checkDatabase(StringJoiner errorMessage, StringJoiner stateResult) { @@ -123,26 +127,23 @@ private void checkDatabaseConnexion(StringJoiner errorMessage, StringJoiner stat } } - private void checkDocumentStorage(String pathToStorage, String storageType, StringJoiner stateResult, StringJoiner errorMessage) { - String dirPath = pathToStorage + "testHealthcheck.txt"; - File testFile = new File(dirPath); - try { - if (!testFile.createNewFile()) { - errorMessage.add("- File for healthcheck already exists in").add(storageType).add("\n"); - stateResult.add(" - File creation").add(storageType).add(KO_STATE); - } else { + private void checkDocumentStorage(String pathToStorage, String storageType, StringJoiner stateResult) { + String testFilename = "testHealthcheck.txt"; + Path testFile = Path.of(pathToStorage, testFilename); + try { + filesOperations.write(new ByteArrayInputStream("test".getBytes()), testFile); stateResult.add(" - File creation").add(storageType).add(OK_STATE); + }catch (RmesFileException rfe){ + logger.error("While trying to write "+testFilename+" in "+storageType, rfe); + stateResult.add(" - File creation").add(storageType).add(KO_STATE); } - if (!Files.deleteIfExists(testFile.toPath())) { - errorMessage.add("- Can't delete test file").add(storageType).add("\n"); - stateResult.add(" - File deletion").add(storageType).add(KO_STATE); - } else { + try{ + filesOperations.delete(testFile.toString()); stateResult.add(" - File deletion").add(storageType).add(OK_STATE); + }catch (RmesFileException rfe){ + logger.error("While trying to delete "+testFilename+" in "+storageType, rfe); + stateResult.add(" - File deletion").add(storageType).add(KO_STATE); } - } catch (IOException e) { - errorMessage.add("- IOException to save file in").add(pathToStorage).add("-").add(e.getMessage()).add("\n"); - stateResult.add(" - Document storage").add(storageType).add(KO_STATE); - } } private interface RequestExecutor { diff --git a/src/test/java/fr/insee/rmes/bauhaus_services/classifications/item/ClassificationItemUtilsTest.java b/src/test/java/fr/insee/rmes/bauhaus_services/classifications/item/ClassificationItemUtilsTest.java index c245db0a0..5442191d0 100644 --- a/src/test/java/fr/insee/rmes/bauhaus_services/classifications/item/ClassificationItemUtilsTest.java +++ b/src/test/java/fr/insee/rmes/bauhaus_services/classifications/item/ClassificationItemUtilsTest.java @@ -1,7 +1,8 @@ package fr.insee.rmes.bauhaus_services.classifications.item; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; +import fr.insee.rmes.bauhaus_services.rdf_utils.RdfServicesForRdfUtils; import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryGestion; +import fr.insee.rmes.bauhaus_services.rdf_utils.UriUtils; import fr.insee.rmes.config.Config; import fr.insee.rmes.exceptions.RmesBadRequestException; import fr.insee.rmes.exceptions.RmesException; @@ -11,6 +12,7 @@ import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.impl.SimpleValueFactory; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -18,6 +20,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -35,13 +38,19 @@ class ClassificationItemUtilsTest { @InjectMocks ClassificationItemUtils classificationItemUtils; + @BeforeEach + public void init() { + //UriUtils uriUtils = new UriUtils("", "http://bauhaus/", p -> Optional.of(SERIES_BASE_URI)); + RdfServicesForRdfUtils rdfServicesForRdfUtils = new RdfServicesForRdfUtils(config, new UriUtils("","", null)); + rdfServicesForRdfUtils.initRdfUtils(); + } + @Test void shouldThrowExceptionIfPrefLabelLg1Null() throws RmesException { when(config.getLg1()).thenReturn("fr"); when(config.getLg2()).thenReturn("en"); - RdfUtils.setConfig(config); ItemsQueries.setConfig(config); ClassificationItem item = new ClassificationItem(); item.setId("1"); @@ -61,7 +70,6 @@ void shouldAddNotes() throws RmesException { when(config.getLg2()).thenReturn("en"); when(config.getCodeListGraph()).thenReturn("http://codeListGraph"); - RdfUtils.setConfig(config); ItemsQueries.setConfig(config); ClassificationItem item = new ClassificationItem(); item.setId("1"); diff --git a/src/test/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationExportTest.java b/src/test/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationExportTest.java index 3a5171cbc..0661536f7 100644 --- a/src/test/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationExportTest.java +++ b/src/test/java/fr/insee/rmes/bauhaus_services/operations/documentations/DocumentationExportTest.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -71,6 +72,7 @@ void testExportAsZip_success() throws Exception { document.put("id", "1"); when(documentsUtils.getDocumentsUriAndUrlForSims("sims123")).thenReturn(new JSONArray().put(document)); + when(documentsUtils.existsInStorage(any())).thenReturn(false); var sims = new JSONObject(); sims.put("id", "sims123"); sims.put("labelLg1", "simsLabel"); @@ -93,8 +95,8 @@ void testExportAsZip_success() throws Exception { assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody()); - assertEquals(response.getStatusCode(), HttpStatus.OK); - assertEquals(response.getHeaders().get("X-Missing-Documents").get(0), "1"); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(response.getHeaders().get("X-Missing-Documents").getFirst()).isEqualTo("1"); } @Test diff --git a/src/test/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsUtilsTest.java b/src/test/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsUtilsTest.java index 06b7b5402..95a468e6a 100644 --- a/src/test/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsUtilsTest.java +++ b/src/test/java/fr/insee/rmes/bauhaus_services/operations/documentations/documents/DocumentsUtilsTest.java @@ -2,8 +2,9 @@ import fr.insee.rmes.Stubber; import fr.insee.rmes.bauhaus_services.FilesOperations; -import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; +import fr.insee.rmes.bauhaus_services.rdf_utils.RdfServicesForRdfUtils; import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryGestion; +import fr.insee.rmes.bauhaus_services.rdf_utils.UriUtils; import fr.insee.rmes.config.Config; import fr.insee.rmes.config.ConfigStub; import fr.insee.rmes.config.auth.security.restrictions.StampsRestrictionsService; @@ -11,9 +12,7 @@ import fr.insee.rmes.exceptions.RmesNotAcceptableException; import fr.insee.rmes.persistance.sparql_queries.GenericQueries; import fr.insee.rmes.persistance.sparql_queries.operations.documentations.DocumentsQueries; -import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Model; -import org.eclipse.rdf4j.model.impl.SimpleValueFactory; import org.json.JSONArray; import org.json.JSONObject; import org.junit.jupiter.api.Assertions; @@ -30,7 +29,11 @@ import org.testcontainers.shaded.org.apache.commons.io.IOUtils; import java.nio.file.Path; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Optional; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -38,6 +41,7 @@ @ExtendWith(MockitoExtension.class) class DocumentsUtilsTest { + public static final String DOCUMENTS_GRAPH = "http://documents/graph"; @Mock RepositoryGestion repositoryGestion; @@ -50,6 +54,8 @@ class DocumentsUtilsTest { @Mock FilesOperations filesOperations; + String documentIRIString = "http://document/1"; + @BeforeAll @@ -119,28 +125,18 @@ void testIfDateMiseAJourSavedAsString() throws RmesException { when(filesOperations.dirExists(any(Path.class))).thenReturn(true); var id = "1"; + String date = LocalDate.now().format(DateTimeFormatter.ISO_DATE); var body = new JSONObject() .put("id", "1") - .put("updatedDate", "2024-11-20").toString(); + .put("updatedDate", date).toString(); var isLink = false; var document = IOUtils.toInputStream("stream"); var name = "documentName"; - String documentIRIString = "http://document/1"; - SimpleValueFactory valueFactory = SimpleValueFactory.getInstance(); - IRI documentIRI = valueFactory.createIRI(documentIRIString); - IRI graph = valueFactory.createIRI("http://documents/graph"); - - try (MockedStatic rdfUtilsMockedStatic = Mockito.mockStatic(RdfUtils.class); + initRdfUtils(); + try ( MockedStatic documentQueriesMockedStatic = Mockito.mockStatic(DocumentsQueries.class) ) { - rdfUtilsMockedStatic.when(() -> RdfUtils.setLiteralString(anyString())).thenCallRealMethod(); - rdfUtilsMockedStatic.when(() -> RdfUtils.addTripleString(eq(documentIRI), any(IRI.class), any(), any(Model.class), eq(graph))).thenCallRealMethod(); - rdfUtilsMockedStatic.when(() -> RdfUtils.setLiteralDate(any(String.class))).thenCallRealMethod(); - rdfUtilsMockedStatic.when(() -> RdfUtils.addTripleDate(eq(documentIRI), any(IRI.class), any(), any(Model.class), eq(graph))).thenCallRealMethod(); - rdfUtilsMockedStatic.when(RdfUtils::documentsGraph).thenReturn(graph); - rdfUtilsMockedStatic.when(() -> RdfUtils.toString(any())).thenReturn(documentIRIString); - rdfUtilsMockedStatic.when(() -> RdfUtils.toURI(any())).thenReturn(documentIRI); documentQueriesMockedStatic.when(() -> DocumentsQueries.checkLabelUnicity(eq("1"), anyString(), any())).thenReturn(documentIRIString); @@ -148,7 +144,18 @@ void testIfDateMiseAJourSavedAsString() throws RmesException { ArgumentCaptor model = ArgumentCaptor.forClass(Model.class); verify(repositoryGestion, times(1)).loadSimpleObject(any(), model.capture()); - Assertions.assertEquals("[(http://document/1, http://purl.org/pav/lastRefreshedOn, \"2024-11-20\"^^, http://documents/graph) [http://documents/graph]]", model.getValue().toString()); + assertThat( model.getValue().toString()).asString().contains(date); } } + + private void initRdfUtils() { + + RdfServicesForRdfUtils rdfServicesForRdfUtils = new RdfServicesForRdfUtils(new Config(){ + @Override + public String getDocumentsGraph() { + return DOCUMENTS_GRAPH; + } + }, new UriUtils("","http://document/", s-> Optional.empty())); + rdfServicesForRdfUtils.initRdfUtils(); + } } \ No newline at end of file diff --git a/src/test/java/fr/insee/rmes/integration/TestDocumentsResourcesWithFilesOperation.java b/src/test/java/fr/insee/rmes/integration/TestDocumentsResourcesWithFilesOperation.java new file mode 100644 index 000000000..4f6e1d1cc --- /dev/null +++ b/src/test/java/fr/insee/rmes/integration/TestDocumentsResourcesWithFilesOperation.java @@ -0,0 +1,122 @@ +package fr.insee.rmes.integration; + +import fr.insee.rmes.bauhaus_services.FilesOperations; +import fr.insee.rmes.bauhaus_services.operations.documentations.documents.DocumentsImpl; +import fr.insee.rmes.bauhaus_services.operations.documentations.documents.DocumentsUtils; +import fr.insee.rmes.bauhaus_services.rdf_utils.PublicationUtils; +import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryGestion; +import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryPublication; +import fr.insee.rmes.bauhaus_services.stamps.StampsRestrictionServiceImpl; +import fr.insee.rmes.config.BaseConfigForMvcTests; +import fr.insee.rmes.config.Config; +import fr.insee.rmes.exceptions.RmesFileException; +import fr.insee.rmes.model.operations.documentations.Document; +import fr.insee.rmes.utils.IdGenerator; +import fr.insee.rmes.webservice.operations.DocumentsResources; +import io.minio.errors.MinioException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.io.InputStream; +import java.nio.file.Path; + +import static fr.insee.rmes.utils.ConsoleCapture.startCapturingConsole; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(DocumentsResources.class) +@Import({BaseConfigForMvcTests.class, DocumentsImpl.class, TestDocumentsResourcesWithFilesOperation.ConfigurationForTest.class}) +class TestDocumentsResourcesWithFilesOperation { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private RepositoryPublication repositoryPublication; + @MockBean + private StampsRestrictionServiceImpl stampsRestrictionService; + @MockBean + private IdGenerator idGenerator; + @MockBean + private PublicationUtils publicationUtils; + @MockBean + private Config config; + @MockBean + private RepositoryGestion repositoryGestion; + + static final String nomFichier = "nomFichier"; + static final String objectName = "directoryGestion/"+nomFichier; + static final String bucketName = "metadata_bucket"; + + private final String fichierId="ID"; + + @Test + void shouldLogAndReturnInternalException_WhenErrorOccursInMinio() throws Exception { + var capture=startCapturingConsole(); + mockMvc.perform(MockMvcRequestBuilders.get("/documents/document/" + fichierId + "/file")) + .andExpect(status().isInternalServerError()) + .andExpect(content().string(containsString("fileName='" + nomFichier + "'"))); + assertThat(capture.standardOut()).asString().contains("Error reading file: "+nomFichier+" as object `"+objectName+"` in bucket "+bucketName); + assertThat(capture.standardOut()).asString().contains("at fr.insee.rmes.bauhaus_services.operations.documentations.documents.DocumentsUtils.downloadDocumentFile"); + assertThat(capture.standardOut()).asString().contains("at fr.insee.rmes.bauhaus_services.operations.documentations.documents.DocumentsImpl.downloadDocument"); + capture.stop(); + } + + @TestConfiguration + static class ConfigurationForTest{ + + @Bean + public DocumentsUtils myDocumentsUtils() { + return new DocumentsUtils(null, new FilesOperationStub()){ + @Override + protected Document findDocumentById(String id){ + return new Document(null, null, null, null, null, null, nomFichier, "http://id.insee.fr/1", "1"); + } + }; + } + + } + + static class FilesOperationStub implements FilesOperations { + @Override + public void delete(String path) { + + } + + @Override + public byte[] read(String path) { + throw new RmesFileException(nomFichier, "Error reading file: " + nomFichier+ + " as object `"+objectName+"` in bucket "+bucketName, new MinioException()); + } + + @Override + public void write(InputStream content, Path destPath) { + + } + + @Override + public void copy(String srcPath, String destPath) { + + } + + @Override + public boolean dirExists(Path gestionStorageFolder) { + return false; + } + + @Override + public boolean exists(Path path) { + return false; + } + } + +} diff --git a/src/test/java/fr/insee/rmes/persistance/sparql_queries/operations/series/OpSeriesQueriesTest.java b/src/test/java/fr/insee/rmes/persistance/sparql_queries/operations/series/OpSeriesQueriesTest.java index d6bd45e12..495b1fc90 100644 --- a/src/test/java/fr/insee/rmes/persistance/sparql_queries/operations/series/OpSeriesQueriesTest.java +++ b/src/test/java/fr/insee/rmes/persistance/sparql_queries/operations/series/OpSeriesQueriesTest.java @@ -1,6 +1,7 @@ package fr.insee.rmes.persistance.sparql_queries.operations.series; import fr.insee.rmes.bauhaus_services.rdf_utils.ObjectType; +import fr.insee.rmes.bauhaus_services.rdf_utils.RdfServicesForRdfUtils; import fr.insee.rmes.bauhaus_services.rdf_utils.RdfUtils; import fr.insee.rmes.bauhaus_services.rdf_utils.UriUtils; import fr.insee.rmes.config.ConfigStub; @@ -52,7 +53,8 @@ private void prepareGenericQueries() { } private void prepareRdfUtils() { - RdfUtils.setUriUtils(new UriUtils("","http://bauhaus/",p-> Optional.of(SERIES_BASE_URI))); + RdfServicesForRdfUtils rdfServicesForRdfUtils = new RdfServicesForRdfUtils(null, new UriUtils("","http://bauhaus/",p-> Optional.of(SERIES_BASE_URI))); + rdfServicesForRdfUtils.initRdfUtils(); } } \ No newline at end of file diff --git a/src/test/java/fr/insee/rmes/utils/ConsoleCapture.java b/src/test/java/fr/insee/rmes/utils/ConsoleCapture.java new file mode 100644 index 000000000..62185a468 --- /dev/null +++ b/src/test/java/fr/insee/rmes/utils/ConsoleCapture.java @@ -0,0 +1,41 @@ +package fr.insee.rmes.utils; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +public class ConsoleCapture{ + + private final ByteArrayOutputStream standardOut; + private final ByteArrayOutputStream standardErr; + private boolean capturing; + private PrintStream lastErr; + private PrintStream lastOut; + + private ConsoleCapture(ByteArrayOutputStream standardOut, ByteArrayOutputStream standardErr) { + this.standardOut = standardOut; + this.standardErr = standardErr; + this.capturing=true; + } + + public static ConsoleCapture startCapturingConsole() { + ConsoleCapture consoleCapture = new ConsoleCapture(new ByteArrayOutputStream(), new ByteArrayOutputStream()); + consoleCapture.lastErr=System.err; + consoleCapture.lastOut=System.out; + System.setOut(new PrintStream(consoleCapture.standardOut)); + System.setErr(new PrintStream(consoleCapture.standardErr)); + return consoleCapture; + } + + public void stop() { + System.setErr(this.lastErr); + System.setOut(this.lastOut); + capturing=false; + } + + public String standardOut() { + if(! capturing) { + throw new IllegalStateException("No capturing any more"); + } + return standardOut.toString(); + } +} diff --git a/src/test/java/fr/insee/rmes/webservice/DocumentsResourcesTest.java b/src/test/java/fr/insee/rmes/webservice/DocumentsResourcesTest.java index 22ef10045..db258b4be 100644 --- a/src/test/java/fr/insee/rmes/webservice/DocumentsResourcesTest.java +++ b/src/test/java/fr/insee/rmes/webservice/DocumentsResourcesTest.java @@ -15,7 +15,6 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -41,12 +40,5 @@ void shouldReturnNotFoundException() throws Exception { .andExpect(content().string(containsString("id not found"))); } - @Test - void shouldReturnInternalException() throws Exception { - when(documentsService.downloadDocument(anyString())).thenThrow(new RmesException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "I/O error", "Error downloading file")); - mockMvc.perform(MockMvcRequestBuilders.get("/documents/document/nomFichier/file")) - .andExpect(status().isInternalServerError()) - .andExpect(content().string(not(containsString("nomFichier")))); - } } diff --git a/src/test/java/fr/insee/rmes/webservice/HealthcheckApiTest.java b/src/test/java/fr/insee/rmes/webservice/HealthcheckApiTest.java index 3e3645101..4a6e70c61 100644 --- a/src/test/java/fr/insee/rmes/webservice/HealthcheckApiTest.java +++ b/src/test/java/fr/insee/rmes/webservice/HealthcheckApiTest.java @@ -1,5 +1,6 @@ package fr.insee.rmes.webservice; +import fr.insee.rmes.bauhaus_services.FilesOperations; import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryGestion; import fr.insee.rmes.bauhaus_services.rdf_utils.RepositoryPublication; import fr.insee.rmes.stubs.RepositoryGestionStub; @@ -24,7 +25,8 @@ void checkDatabaseTest_success() { //Given RepositoryGestion repoGestionStub=new RepositoryGestionStub(); RepositoryPublication repoPublicationStub=new RepositoryPublicationStub(); - var healthcheckApi=new HealthcheckApi(repoGestionStub, repoPublicationStub, documentsStoragePublicationInterne, documentsStoragePublicationExterne, documentsStorageGestion); + FilesOperations filesOperations = null; + var healthcheckApi=new HealthcheckApi(repoGestionStub, repoPublicationStub, filesOperations, documentsStoragePublicationInterne, documentsStoragePublicationExterne, documentsStorageGestion); StringJoiner errorMessage = new StringJoiner(" "); StringJoiner stateResult = new StringJoiner(" "); @@ -47,7 +49,8 @@ void checkDatabaseTest_withInternalPublicationError() { //Given RepositoryGestion repoGestionStub=new RepositoryGestionStub(); RepositoryPublication repoPublicationStub=new RepositoryPublicationStubInternalError(); - var healthcheckApi=new HealthcheckApi(repoGestionStub, repoPublicationStub, documentsStoragePublicationInterne, documentsStoragePublicationExterne, documentsStorageGestion); + FilesOperations filesOperations = null; + var healthcheckApi=new HealthcheckApi(repoGestionStub, repoPublicationStub, filesOperations, documentsStoragePublicationInterne, documentsStoragePublicationExterne, documentsStorageGestion); StringJoiner errorMessage = new StringJoiner(" "); StringJoiner stateResult = new StringJoiner(" ");