From a3735207ad3d3cb403c31c3d5c79d2982b2e7484 Mon Sep 17 00:00:00 2001 From: Mario Serrano Leones Date: Mon, 30 Sep 2024 11:36:26 -0500 Subject: [PATCH] upgrade to AWS SDK v2.28 --- .../LocalEntityFileStorageController.java | 34 +++++++ .../modules/entityfile/domain/EntityFile.java | 1 + .../local/LocalEntityFileStorage.java | 7 ++ .../local/LocalEntityFileStorageConfig.java | 28 +----- .../local/LocalEntityFileStorageHandler.java | 39 +++----- .../service/impl/EntityFileServiceImpl.java | 12 ++- sources/pom.xml | 4 +- .../entityfiles/s3/S3EntityFileStorage.java | 12 +-- ...er.java => EntityFilesModuleProvider.java} | 99 ++++++++++--------- .../ui/actions/ViewFileURLAction.java | 4 +- .../ui/components/EntityFileImage.java | 2 +- .../META-INF/descriptors/EntityFileConfig.yml | 9 +- 12 files changed, 136 insertions(+), 115 deletions(-) create mode 100644 sources/core/src/main/java/tools/dynamia/modules/entityfile/controller/LocalEntityFileStorageController.java rename sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/{EntityFilesInstaller.java => EntityFilesModuleProvider.java} (77%) diff --git a/sources/core/src/main/java/tools/dynamia/modules/entityfile/controller/LocalEntityFileStorageController.java b/sources/core/src/main/java/tools/dynamia/modules/entityfile/controller/LocalEntityFileStorageController.java new file mode 100644 index 0000000..7b9fb79 --- /dev/null +++ b/sources/core/src/main/java/tools/dynamia/modules/entityfile/controller/LocalEntityFileStorageController.java @@ -0,0 +1,34 @@ +package tools.dynamia.modules.entityfile.controller; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import tools.dynamia.integration.sterotypes.Controller; +import tools.dynamia.modules.entityfile.local.LocalEntityFileStorageHandler; + +@Controller +public class LocalEntityFileStorageController { + + private final LocalEntityFileStorageHandler handler; + + public LocalEntityFileStorageController(LocalEntityFileStorageHandler handler) { + this.handler = handler; + } + + @GetMapping(value = "/storage/{file}") + public ResponseEntity get(@PathVariable String file, @RequestParam("uuid") String uuid, HttpServletRequest request) { + var resource = handler.getResource(file, uuid, request); + if (resource != null && resource.exists() && resource.isReadable()) { + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"") + .body(resource); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } +} diff --git a/sources/core/src/main/java/tools/dynamia/modules/entityfile/domain/EntityFile.java b/sources/core/src/main/java/tools/dynamia/modules/entityfile/domain/EntityFile.java index 3a52742..f128e7c 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/entityfile/domain/EntityFile.java +++ b/sources/core/src/main/java/tools/dynamia/modules/entityfile/domain/EntityFile.java @@ -32,6 +32,7 @@ import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; + import java.util.List; @Entity diff --git a/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorage.java b/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorage.java index 77be073..fa255e5 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorage.java +++ b/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorage.java @@ -18,6 +18,8 @@ package tools.dynamia.modules.entityfile.local; import org.springframework.core.env.Environment; +import tools.dynamia.commons.logger.LoggingService; +import tools.dynamia.commons.logger.SLF4JLoggingService; import tools.dynamia.domain.ValidationError; import tools.dynamia.domain.query.Parameters; import tools.dynamia.domain.services.CrudService; @@ -37,6 +39,8 @@ @Service public class LocalEntityFileStorage implements EntityFileStorage { + private final LoggingService logger = new SLF4JLoggingService(LocalEntityFileStorage.class, "Local: "); + public static final String ID = "LocalStorage"; private static final String LOCAL_FILES_LOCATION = "LOCAL_FILES_LOCATION"; private static final String LOCAL_USE_HTTPS = "LOCAL_USE_HTTPS"; @@ -71,9 +75,12 @@ public void upload(EntityFile entityFile, UploadedFileInfo fileInfo) { File realFile = getRealFile(entityFile); try { + IOUtils.copy(fileInfo.getInputStream(), realFile); entityFile.setSize(realFile.length()); + logger.info("Uploaded to server: " + realFile); } catch (IOException e) { + logger.error("Error upload local file " + realFile, e); throw new EntityFileException("Error upload local file " + realFile, e); } diff --git a/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorageConfig.java b/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorageConfig.java index 01560d8..f659ac5 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorageConfig.java +++ b/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorageConfig.java @@ -17,34 +17,16 @@ package tools.dynamia.modules.entityfile.local; -import java.util.HashMap; -import java.util.Map; - import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; -import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; +import tools.dynamia.modules.entityfile.service.EntityFileService; @Configuration class LocalEntityFileStorageConfig { - @Bean - public SimpleUrlHandlerMapping localHandler() { - - ResourceHttpRequestHandler handler = localEntityFileStorageHandler(); - - Map map = new HashMap<>(); - - map.put("storage/**", handler); - - SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); - mapping.setUrlMap(map); - - return mapping; - } - @Bean - public LocalEntityFileStorageHandler localEntityFileStorageHandler() { - return new LocalEntityFileStorageHandler(); - } + @Bean + public LocalEntityFileStorageHandler localEntityFileStorageHandler(LocalEntityFileStorage storage, EntityFileService service) { + return new LocalEntityFileStorageHandler(storage, service); + } } diff --git a/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorageHandler.java b/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorageHandler.java index 5178889..0d1b1ff 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorageHandler.java +++ b/sources/core/src/main/java/tools/dynamia/modules/entityfile/local/LocalEntityFileStorageHandler.java @@ -23,7 +23,6 @@ import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; -import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import tools.dynamia.commons.StringUtils; import tools.dynamia.integration.Containers; @@ -36,21 +35,21 @@ import tools.dynamia.modules.entityfile.enums.EntityFileType; import tools.dynamia.modules.entityfile.service.EntityFileService; -public class LocalEntityFileStorageHandler extends ResourceHttpRequestHandler { +public class LocalEntityFileStorageHandler { private static final String UUID = "/uuid/"; - private LocalEntityFileStorage storage; - private EntityFileService service; + private final LocalEntityFileStorage storage; + private final EntityFileService service; private EntityFileAccountProvider accountProvider; - @Override - protected Resource getResource(HttpServletRequest request) { - if (service == null) { - service = Containers.get().findObject(EntityFileService.class); - } - if (storage == null) { - storage = Containers.get().findObject(LocalEntityFileStorage.class); - } + public LocalEntityFileStorageHandler(LocalEntityFileStorage storage, EntityFileService service) { + this.storage = storage; + this.service = service; + } + + + public Resource getResource(String fileName, String uuid, HttpServletRequest request) { + if (accountProvider == null) { accountProvider = Containers.get().findObject(EntityFileAccountProvider.class); @@ -60,23 +59,11 @@ protected Resource getResource(HttpServletRequest request) { } File file = null; - String uuid = getParam(request, "uuid", null); - - if (uuid == null) { - String path = request.getPathInfo(); - if (path.contains(UUID)) { - uuid = path.substring(path.lastIndexOf(UUID) + UUID.length()); - uuid = StringUtils.removeFilenameExtension(uuid); - } - } - - if (uuid == null) { - return null; - } - Long currentAccountId = accountProvider.getAccountId(); EntityFile entityFile = service.getEntityFile(uuid); + + if (entityFile != null && (currentAccountId == null || currentAccountId.equals(0L) || entityFile.isShared() || entityFile.getAccountId().equals(currentAccountId))) { StoredEntityFile storedEntityFile = storage.download(entityFile); diff --git a/sources/core/src/main/java/tools/dynamia/modules/entityfile/service/impl/EntityFileServiceImpl.java b/sources/core/src/main/java/tools/dynamia/modules/entityfile/service/impl/EntityFileServiceImpl.java index b6f7918..79cfb64 100644 --- a/sources/core/src/main/java/tools/dynamia/modules/entityfile/service/impl/EntityFileServiceImpl.java +++ b/sources/core/src/main/java/tools/dynamia/modules/entityfile/service/impl/EntityFileServiceImpl.java @@ -18,6 +18,9 @@ package tools.dynamia.modules.entityfile.service.impl; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -101,7 +104,7 @@ private EntityFile createDir(EntityFile parent, Object targetEntity, String name @Override @Transactional public EntityFile createEntityFile(UploadedFileInfo fileInfo, Object target, String description) { - logger.info("Creating new entity file for " + target + ", file: " + fileInfo.getFullName()); + logger.info("Creating new entity file for " + (target != null ? target : "temporal entity") + ", file: " + fileInfo.getFullName()); EntityFile entityFile = new EntityFile(); entityFile.setDescription(description); entityFile.setContentType(fileInfo.getContentType()); @@ -294,8 +297,11 @@ public void download(EntityFile entityFile, File outputFile) { @Override public EntityFile getEntityFile(String uuid) { try { - return crudService.findSingle(EntityFile.class, QueryParameters.with("uuid", QueryConditions.eq(uuid)) - .add("accountId", QueryConditions.isNotNull())); + CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(EntityFile.class); + Root root = query.from(EntityFile.class); + query.select(root).where(cb.equal(root.get("uuid"), uuid)); + return entityManager.createQuery(query).setMaxResults(1).getSingleResult(); } catch (Exception e) { logger.error("Error loading entity file with uuid: " + uuid + ". " + e.getMessage(), e); diff --git a/sources/pom.xml b/sources/pom.xml index 50b14b4..978a58b 100644 --- a/sources/pom.xml +++ b/sources/pom.xml @@ -63,9 +63,9 @@ UTF-8 - 5.3.0 + 5.2.1 3.3.3 - 2.28.0 + 2.28.11 17 3.13.0 UTF-8 diff --git a/sources/s3/src/main/java/tools/dynamia/modules/entityfiles/s3/S3EntityFileStorage.java b/sources/s3/src/main/java/tools/dynamia/modules/entityfiles/s3/S3EntityFileStorage.java index 0900745..a30cf70 100644 --- a/sources/s3/src/main/java/tools/dynamia/modules/entityfiles/s3/S3EntityFileStorage.java +++ b/sources/s3/src/main/java/tools/dynamia/modules/entityfiles/s3/S3EntityFileStorage.java @@ -65,7 +65,7 @@ public class S3EntityFileStorage implements EntityFileStorage { public static final String AWS_S3_REGION = "AWS_S3_REGION"; public static final String AWS_S3_BUCKET = "AWS_S3_BUCKET"; private static final Logger log = LoggerFactory.getLogger(S3EntityFileStorage.class); - private final LoggingService logger = new SLF4JLoggingService(S3EntityFileStorage.class, "S3"); + private final LoggingService logger = new SLF4JLoggingService(S3EntityFileStorage.class, "S3: "); private final SimpleCache URL_CACHE = new SimpleCache<>(); private final SimpleCache PARAMS_CACHE = new SimpleCache<>(); @@ -126,10 +126,10 @@ public void upload(EntityFile entityFile, UploadedFileInfo fileInfo) { final var metadata = Map.of( - "accountId", entityFile.getAccountId().toString(), + "accountId", entityFile.getAccountId() != null ? entityFile.getAccountId().toString() : "", "uuid", entityFile.getUuid(), - "creator", entityFile.getCreator(), - "databaseId", String.valueOf(entityFile.getId()) + "creator", entityFile.getCreator() != null ? entityFile.getCreator() : "anonymous", + "databaseId", entityFile.getId() != null ? String.valueOf(entityFile.getId()) : "" ); final var contentType = URLConnection.guessContentTypeFromName(entityFile.getName()); @@ -198,8 +198,8 @@ protected String generateSignedURL(String bucketName, String fileName) { PresignedGetObjectRequest presignedRequest = S3Utils.generatePresignedObjetRequest(bucketName, fileName, Duration.ofMinutes(30)); - logger.info("Presigned URL: [{}]", presignedRequest.url().toString()); - logger.info("HTTP method: [{}]", presignedRequest.httpRequest().method()); + logger.info("Presigned URL: " + presignedRequest.url().toString()); + logger.info("HTTP method: " + presignedRequest.httpRequest().method()); return presignedRequest.url().toExternalForm(); diff --git a/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/EntityFilesInstaller.java b/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/EntityFilesModuleProvider.java similarity index 77% rename from sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/EntityFilesInstaller.java rename to sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/EntityFilesModuleProvider.java index 7cecab6..7ed9e94 100644 --- a/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/EntityFilesInstaller.java +++ b/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/EntityFilesModuleProvider.java @@ -1,49 +1,50 @@ - -/* - * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1 - * Colombia / South America - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package tools.dynamia.modules.entityfile.ui; - -import tools.dynamia.crud.cfg.ConfigPage; -import tools.dynamia.integration.sterotypes.Provider; -import tools.dynamia.navigation.Module; -import tools.dynamia.navigation.ModuleProvider; -import tools.dynamia.navigation.PageGroup; - - -/** - * - * @author Mario Serrano Leones - */ -@Provider -public class EntityFilesInstaller implements ModuleProvider { - - @Override - public Module getModule() { - Module module = Module.getRef("system"); - - PageGroup pg = new PageGroup("config", "Configuracion"); - module.addPageGroup(pg); - { - pg.addPage(new ConfigPage("entityFile", "Archivos", "EntityFileCFG")); - - } - - return module; - } - -} + +/* + * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1 + * Colombia / South America + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tools.dynamia.modules.entityfile.ui; + +import tools.dynamia.crud.cfg.ConfigPage; +import tools.dynamia.integration.sterotypes.Provider; +import tools.dynamia.navigation.Module; +import tools.dynamia.navigation.ModuleProvider; +import tools.dynamia.navigation.PageGroup; + + +/** + * @author Mario Serrano Leones + */ +@Provider +public class EntityFilesModuleProvider implements ModuleProvider { + + @Override + public Module getModule() { + Module module = Module.getRef("system") + .name("System") + .icon("settings"); + + PageGroup pg = new PageGroup("config", "Configuration"); + module.addPageGroup(pg); + { + pg.addPage(new ConfigPage("entityFile", "Entity Files", "EntityFileCFG")); + + } + + return module; + } + +} diff --git a/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/actions/ViewFileURLAction.java b/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/actions/ViewFileURLAction.java index 9e2b1ab..0d90b7b 100644 --- a/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/actions/ViewFileURLAction.java +++ b/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/actions/ViewFileURLAction.java @@ -21,6 +21,7 @@ import tools.dynamia.actions.ActionGroup; import tools.dynamia.actions.InstallAction; import tools.dynamia.actions.ReadableOnly; +import tools.dynamia.ui.UIMessages; @InstallAction public class ViewFileURLAction extends AbstractEntityFileAction implements ReadableOnly { @@ -35,7 +36,8 @@ public ViewFileURLAction() { @Override public void actionPerformed(EntityFileActionEvent evt) { if (evt.getEntityFile() != null) { - Messagebox.show(evt.getEntityFile().getStoredEntityFile().getUrl()); + String url = evt.getEntityFile().getStoredEntityFile().getUrl(); + UIMessages.showMessageDialog("
" + url + "
"); } } } diff --git a/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/components/EntityFileImage.java b/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/components/EntityFileImage.java index 139c8ab..2879fc3 100644 --- a/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/components/EntityFileImage.java +++ b/sources/ui/src/main/java/tools/dynamia/modules/entityfile/ui/components/EntityFileImage.java @@ -53,7 +53,7 @@ public class EntityFileImage extends Image { private boolean thumbnail = false; private int thumbnailHeight = 64; private int thumbnailWidth = 64; - private String noPhotoPath = "/zkau/web/tools/images/no-photo.jpg"; + private String noPhotoPath = "/static/dynamia-tools/images/no-photo.jpg"; public EntityFile getValue() { return entityFile; diff --git a/sources/ui/src/main/resources/META-INF/descriptors/EntityFileConfig.yml b/sources/ui/src/main/resources/META-INF/descriptors/EntityFileConfig.yml index 0b814c4..68518e2 100644 --- a/sources/ui/src/main/resources/META-INF/descriptors/EntityFileConfig.yml +++ b/sources/ui/src/main/resources/META-INF/descriptors/EntityFileConfig.yml @@ -39,10 +39,11 @@ fields: params: parameterName: AWS_S3_BUCKET cacheable: true - s3Endpoint: - label: Endpoint + s3Region: + label: Region params: - parameterName: AWS_S3_ENDPOINT + parameterName: AWS_S3_REGION + defaultValue: us-east-1 cacheable: true s3User: label: Identity @@ -58,7 +59,7 @@ fields: groups: s3: label: Amazon Web Service (S3) - fields: [ s3BucketName,s3Endpoint,s3User,s3Secret ] + fields: [ s3BucketName,s3Region,s3User,s3Secret ] layout: columns: 4 \ No newline at end of file