diff --git a/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/property/PropertyApartmentSharingServiceImpl.java b/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/property/PropertyApartmentSharingServiceImpl.java index cdc06a41e..ae5946e8a 100644 --- a/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/property/PropertyApartmentSharingServiceImpl.java +++ b/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/property/PropertyApartmentSharingServiceImpl.java @@ -1,40 +1,50 @@ package fr.dossierfacile.api.dossierfacileapiowner.property; import fr.dossierfacile.api.dossierfacileapiowner.mail.MailService; +import fr.dossierfacile.common.entity.ApartmentSharing; import fr.dossierfacile.common.entity.Property; import fr.dossierfacile.common.entity.PropertyApartmentSharing; import fr.dossierfacile.common.entity.Tenant; import fr.dossierfacile.common.enums.TenantType; +import fr.dossierfacile.common.repository.PropertyLogRepository; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import static fr.dossierfacile.common.entity.PropertyLog.*; +import java.util.Optional; + @Slf4j @Service @AllArgsConstructor public class PropertyApartmentSharingServiceImpl implements PropertyApartmentSharingService { private final PropertyApartmentSharingRepository propertyApartmentSharingRepository; + private final PropertyLogRepository logRepository; private final MailService mailService; @Override public void deletePropertyApartmentSharing(PropertyApartmentSharing propertyApartmentSharing) { propertyApartmentSharingRepository.delete(propertyApartmentSharing); + logRepository.save(applicationDeletedByOwner(propertyApartmentSharing)); } @Override public void subscribeTenantApartmentSharingToProperty(Tenant tenant, Property property, boolean hasAccess) { if (tenant.getTenantType() == TenantType.CREATE) { - PropertyApartmentSharing propertyApartmentSharing = propertyApartmentSharingRepository - .findByPropertyAndApartmentSharing(property, tenant.getApartmentSharing()) - .orElse(PropertyApartmentSharing.builder() - .accessFull(hasAccess) - .token(hasAccess ? tenant.getApartmentSharing().getToken() : tenant.getApartmentSharing().getTokenPublic()) - .property(property) - .apartmentSharing(tenant.getApartmentSharing()) - .build() - ); - propertyApartmentSharingRepository.save(propertyApartmentSharing); - mailService.sendEmailNewApplicant(tenant, property.getOwner(), property); + ApartmentSharing apartmentSharing = tenant.getApartmentSharing(); + Optional existingPropertyApartmentSharing = propertyApartmentSharingRepository + .findByPropertyAndApartmentSharing(property, apartmentSharing); + if (existingPropertyApartmentSharing.isEmpty()) { + PropertyApartmentSharing propertyApartmentSharing = PropertyApartmentSharing.builder() + .accessFull(hasAccess) + .token(hasAccess ? apartmentSharing.getToken() : apartmentSharing.getTokenPublic()) + .property(property) + .apartmentSharing(apartmentSharing) + .build(); + propertyApartmentSharingRepository.save(propertyApartmentSharing); + logRepository.save(applicationReceived(property, apartmentSharing)); + mailService.sendEmailNewApplicant(tenant, property.getOwner(), property); + } } else { throw new IllegalStateException("Tenant is not the main tenant"); } diff --git a/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/register/AuthenticationFacade.java b/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/register/AuthenticationFacade.java index a8a7e0bde..724fc9260 100644 --- a/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/register/AuthenticationFacade.java +++ b/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/register/AuthenticationFacade.java @@ -1,5 +1,6 @@ package fr.dossierfacile.api.dossierfacileapiowner.register; +import fr.dossierfacile.common.converter.AcquisitionData; import fr.dossierfacile.common.entity.Owner; public interface AuthenticationFacade { @@ -8,5 +9,6 @@ public interface AuthenticationFacade { Owner getOwner(); - String getKeycloakClientId(); + Owner getOwner(AcquisitionData acquisitionData); + } diff --git a/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/register/AuthenticationFacadeImpl.java b/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/register/AuthenticationFacadeImpl.java index 3e314e25b..b6656ee1f 100644 --- a/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/register/AuthenticationFacadeImpl.java +++ b/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/register/AuthenticationFacadeImpl.java @@ -3,6 +3,7 @@ import com.google.common.base.Strings; import fr.dossierfacile.api.dossierfacileapiowner.log.OwnerLogService; import fr.dossierfacile.api.dossierfacileapiowner.user.OwnerRepository; +import fr.dossierfacile.common.converter.AcquisitionData; import fr.dossierfacile.common.entity.Owner; import fr.dossierfacile.common.enums.OwnerLogType; import lombok.AllArgsConstructor; @@ -70,14 +71,19 @@ private String getFranceConnectBirthDate() { @Override public Owner getOwner() { + return getOwner(null); + } + + @Override + public Owner getOwner(AcquisitionData acquisitionData) { if (!keycloakService.isKeycloakUser(getKeycloakUserId())) { throw new AccessDeniedException("invalid token"); } - Optional optionalOwner = ownerRepository.findByKeycloakId(getKeycloakUserId()); - if (optionalOwner.isEmpty()) { - optionalOwner = ownerRepository.findByEmail(getUserEmail()); + Optional existingOwner = ownerRepository.findByKeycloakId(getKeycloakUserId()); + if (existingOwner.isEmpty()) { + existingOwner = ownerRepository.findByEmail(getUserEmail()); } - Owner owner = optionalOwner.orElse(Owner.builder().email(getUserEmail()).build()); + Owner owner = existingOwner.orElse(Owner.builder().email(getUserEmail()).build()); owner.setKeycloakId(getKeycloakUserId()); owner.setFranceConnect(isFranceConnect()); if (isFranceConnect()) { @@ -89,16 +95,16 @@ public Owner getOwner() { owner.setLastName(getLastName()); owner.setPreferredName(getPreferredName()); } + if (existingOwner.isEmpty() && acquisitionData != null) { + owner.setAcquisitionCampaign(acquisitionData.campaign()); + owner.setAcquisitionSource(acquisitionData.source()); + owner.setAcquisitionMedium(acquisitionData.medium()); + } owner = ownerRepository.saveAndFlush(owner); - if (optionalOwner.isEmpty()) { + if (existingOwner.isEmpty()) { ownerLogService.saveLog(OwnerLogType.ACCOUNT_CREATED_VIA_KC, owner.getId()); } return owner; } - @Override - public String getKeycloakClientId() { - return ((Jwt) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getClaimAsString("azp"); - } - } diff --git a/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/user/OwnerController.java b/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/user/OwnerController.java index 585ef9a9a..33d4b9a71 100644 --- a/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/user/OwnerController.java +++ b/dossierfacile-api-owner/src/main/java/fr/dossierfacile/api/dossierfacileapiowner/user/OwnerController.java @@ -2,25 +2,25 @@ import fr.dossierfacile.api.dossierfacileapiowner.register.AuthenticationFacade; import fr.dossierfacile.api.dossierfacileapiowner.register.KeycloakService; +import fr.dossierfacile.common.converter.AcquisitionData; import fr.dossierfacile.common.entity.Owner; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.http.client.HttpResponseException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; import javax.servlet.http.HttpServletResponse; -import java.time.LocalDateTime; - import static org.springframework.http.ResponseEntity.ok; @RestController @@ -55,8 +55,8 @@ public ResponseEntity logout() { } @GetMapping(value = "/profile") - public ResponseEntity profile() { - Owner owner = authenticationFacade.getOwner(); + public ResponseEntity profile(@RequestParam MultiValueMap params) { + Owner owner = authenticationFacade.getOwner(AcquisitionData.from(params)); ownerService.updateLastLoginDate(owner); return ok(ownerMapper.toOwnerModel(owner)); } diff --git a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/controller/TenantController.java b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/controller/TenantController.java index 3fa1f618f..17231d094 100644 --- a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/controller/TenantController.java +++ b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/controller/TenantController.java @@ -1,5 +1,6 @@ package fr.dossierfacile.api.front.controller; +import fr.dossierfacile.common.converter.AcquisitionData; import fr.dossierfacile.api.front.form.ShareFileByMailForm; import fr.dossierfacile.api.front.mapper.PropertyOMapper; import fr.dossierfacile.api.front.mapper.TenantMapper; @@ -17,12 +18,14 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import static org.springframework.http.ResponseEntity.badRequest; @@ -43,8 +46,8 @@ public class TenantController { private final UserService userService; @GetMapping(value = "/profile", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity profile() { - Tenant tenant = authenticationFacade.getLoggedTenant(); + public ResponseEntity profile(@RequestParam MultiValueMap params) { + Tenant tenant = authenticationFacade.getLoggedTenant(AcquisitionData.from(params)); tenantService.updateLastLoginDateAndResetWarnings(tenant); return ok(tenantMapper.toTenantModel(tenant)); } diff --git a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/dfc/controller/DfcTenantController.java b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/dfc/controller/DfcTenantController.java index 57ccba4c2..83a9d0010 100644 --- a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/dfc/controller/DfcTenantController.java +++ b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/dfc/controller/DfcTenantController.java @@ -44,7 +44,7 @@ public ResponseEntity profilePartner() { if (tenant == null) { KeycloakUser kcUser = authenticationFacade.getKeycloakUser(); - tenant = tenantService.registerFromKeycloakUser(kcUser, partner); + tenant = tenantService.registerFromKeycloakUser(kcUser, partner, null); } else { userService.linkTenantToPartner(tenant, partner, null); } diff --git a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/security/AuthenticationFacadeImpl.java b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/security/AuthenticationFacadeImpl.java index 5a647d348..54d5c3a6a 100644 --- a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/security/AuthenticationFacadeImpl.java +++ b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/security/AuthenticationFacadeImpl.java @@ -1,20 +1,19 @@ package fr.dossierfacile.api.front.security; import fr.dossierfacile.api.front.exception.TenantNotFoundException; +import fr.dossierfacile.common.converter.AcquisitionData; import fr.dossierfacile.api.front.model.KeycloakUser; import fr.dossierfacile.api.front.security.interfaces.AuthenticationFacade; import fr.dossierfacile.api.front.service.interfaces.DocumentService; import fr.dossierfacile.api.front.service.interfaces.TenantPermissionsService; import fr.dossierfacile.api.front.service.interfaces.TenantService; import fr.dossierfacile.api.front.service.interfaces.TenantStatusService; -import fr.dossierfacile.api.front.util.SentryUtil; import fr.dossierfacile.common.entity.Tenant; import fr.dossierfacile.common.enums.DocumentCategory; import fr.dossierfacile.common.enums.LogType; import fr.dossierfacile.common.enums.TenantFileStatus; import fr.dossierfacile.common.repository.TenantCommonRepository; import fr.dossierfacile.common.service.interfaces.LogService; -import io.sentry.SentryLevel; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -106,19 +105,35 @@ public Tenant getTenant(Long tenantId) { @Override public Tenant getLoggedTenant() { + return getLoggedTenant(null); + } + + @Override + public Tenant getLoggedTenant(AcquisitionData acquisitionData) { KeycloakUser kcUser = getKeycloakUser(); if (!kcUser.isEmailVerified() && !kcUser.isFranceConnect()) { throw new AccessDeniedException("Email is not verified" + kcUser.getEmail()); } - Tenant tenant = tenantRepository.findByKeycloakId(kcUser.getKeycloakId()); - if (tenant == null) { - log.error(SentryUtil.captureMessage("User try to connect with not found keycloakId " + kcUser.getKeycloakId(), SentryLevel.ERROR)); - tenant = tenantRepository.findByEmail(kcUser.getEmail()) - .orElseGet(() -> tenantService.registerFromKeycloakUser(kcUser, null)); - } + Tenant tenant = findOrCreateTenant(kcUser, acquisitionData); return synchronizeTenant(tenant, kcUser); } + private Tenant findOrCreateTenant(KeycloakUser kcUser, AcquisitionData acquisitionData) { + String keycloakId = kcUser.getKeycloakId(); + Tenant tenant = tenantRepository.findByKeycloakId(keycloakId); + if (tenant != null) { + return tenant; + } + log.warn("No tenant account found associated with keycloakId {}", keycloakId); + Optional tenantByEmail = tenantRepository.findByEmail(kcUser.getEmail()); + if (tenantByEmail.isPresent()) { + log.info("Found tenant by email from keycloak"); + return tenantByEmail.get(); + } + log.info("Creating tenant account associated with keycloakId {}", keycloakId); + return tenantService.registerFromKeycloakUser(kcUser, null, acquisitionData); + } + private Tenant synchronizeTenant(Tenant tenant, KeycloakUser user) { // check if some data should be updated if (!matches(tenant, user)) { @@ -133,6 +148,9 @@ private Tenant synchronizeTenant(Tenant tenant, KeycloakUser user) { if (!Boolean.TRUE.equals(tenant.getFranceConnect()) && user.isFranceConnect()) { log.info("Local account link to FranceConnect account, for tenant with ID {}", tenant.getId()); logService.saveLog(LogType.FC_ACCOUNT_LINK, tenant.getId()); + } else if (tenant.getKeycloakId() == null ){ + log.info("First tenant connection from DF, for tenant with ID {}", tenant.getId()); + logService.saveLog(LogType.ACCOUNT_LINK, tenant.getId()); } tenant.setKeycloakId(user.getKeycloakId()); diff --git a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/security/interfaces/AuthenticationFacade.java b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/security/interfaces/AuthenticationFacade.java index c83dacb3a..dad97d7e3 100644 --- a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/security/interfaces/AuthenticationFacade.java +++ b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/security/interfaces/AuthenticationFacade.java @@ -1,5 +1,6 @@ package fr.dossierfacile.api.front.security.interfaces; +import fr.dossierfacile.common.converter.AcquisitionData; import fr.dossierfacile.api.front.model.KeycloakUser; import fr.dossierfacile.common.entity.Tenant; @@ -14,9 +15,9 @@ public interface AuthenticationFacade { Tenant getLoggedTenant(); + Tenant getLoggedTenant(AcquisitionData acquisitionData); + Tenant getTenant(Long id); String getFranceConnectLink(String redirectUri); - - } diff --git a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/service/TenantServiceImpl.java b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/service/TenantServiceImpl.java index 57752b74d..dcf9bb69b 100644 --- a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/service/TenantServiceImpl.java +++ b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/service/TenantServiceImpl.java @@ -2,6 +2,7 @@ import fr.dossierfacile.api.front.exception.MailSentLimitException; import fr.dossierfacile.api.front.exception.TenantNotFoundException; +import fr.dossierfacile.common.converter.AcquisitionData; import fr.dossierfacile.api.front.model.KeycloakUser; import fr.dossierfacile.api.front.model.tenant.EmailExistsModel; import fr.dossierfacile.api.front.model.tenant.TenantModel; @@ -10,7 +11,6 @@ import fr.dossierfacile.api.front.register.form.partner.EmailExistsForm; import fr.dossierfacile.api.front.service.interfaces.KeycloakService; import fr.dossierfacile.api.front.service.interfaces.MailService; -import fr.dossierfacile.api.front.service.interfaces.PropertyService; import fr.dossierfacile.api.front.service.interfaces.TenantService; import fr.dossierfacile.api.front.service.interfaces.UserApiService; import fr.dossierfacile.api.front.util.Obfuscator; @@ -52,7 +52,6 @@ public class TenantServiceImpl implements TenantService { private final LogService logService; private final MailService mailService; private final PartnerCallBackService partnerCallBackService; - private final PropertyService propertyService; private final RegisterFactory registerFactory; private final TenantCommonRepository tenantRepository; private final KeycloakService keycloakService; @@ -109,7 +108,7 @@ public Tenant findByKeycloakId(String keycloakId) { @Override @Transactional - public Tenant registerFromKeycloakUser(KeycloakUser kcUser, String partner) { + public Tenant registerFromKeycloakUser(KeycloakUser kcUser, String partner, AcquisitionData acquisitionData) { // check user still exists in keycloak if (keycloakService.getKeyCloakUser(kcUser.getKeycloakId()) == null) { throw new TenantNotFoundException("User doesn't exist anymore in KC - token is out-of-date"); @@ -125,6 +124,12 @@ public Tenant registerFromKeycloakUser(KeycloakUser kcUser, String partner) { .honorDeclaration(false) .build()); + if (acquisitionData != null) { + tenant.setAcquisitionCampaign(acquisitionData.campaign()); + tenant.setAcquisitionSource(acquisitionData.source()); + tenant.setAcquisitionMedium(acquisitionData.medium()); + } + if (!kcUser.isEmailVerified()) { // createdAccount without verified email should be deactivated keycloakService.disableAccount(kcUser.getKeycloakId()); @@ -140,7 +145,7 @@ public Tenant registerFromKeycloakUser(KeycloakUser kcUser, String partner) { if (kcUser.isFranceConnect()) { logService.saveLog(LogType.FC_ACCOUNT_CREATION, tenant.getId()); } else { - logService.saveLog(LogType.ACCOUNT_CREATED, tenant.getId()); + logService.saveLog(LogType.ACCOUNT_CREATED_VIA_KC, tenant.getId()); } return tenantRepository.save(tenant); } diff --git a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/service/interfaces/TenantService.java b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/service/interfaces/TenantService.java index db4089286..b4c47e5f8 100644 --- a/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/service/interfaces/TenantService.java +++ b/dossierfacile-api-tenant/src/main/java/fr/dossierfacile/api/front/service/interfaces/TenantService.java @@ -1,5 +1,6 @@ package fr.dossierfacile.api.front.service.interfaces; +import fr.dossierfacile.common.converter.AcquisitionData; import fr.dossierfacile.api.front.model.KeycloakUser; import fr.dossierfacile.api.front.model.tenant.EmailExistsModel; import fr.dossierfacile.api.front.model.tenant.TenantModel; @@ -26,7 +27,7 @@ public interface TenantService { Tenant findByKeycloakId(String keycloakId); - Tenant registerFromKeycloakUser(KeycloakUser kcUser, String partner); + Tenant registerFromKeycloakUser(KeycloakUser kcUser, String partner, AcquisitionData acquisitionData); Optional findByEmail(String email); diff --git a/dossierfacile-bo/src/main/java/fr/gouv/bo/configuration/WebSecurityConfig.java b/dossierfacile-bo/src/main/java/fr/gouv/bo/configuration/WebSecurityConfig.java index 452084b3b..063754274 100644 --- a/dossierfacile-bo/src/main/java/fr/gouv/bo/configuration/WebSecurityConfig.java +++ b/dossierfacile-bo/src/main/java/fr/gouv/bo/configuration/WebSecurityConfig.java @@ -69,7 +69,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .hasRole("ADMIN") .antMatchers("/bo/tenant/{tenantId}/processFile") .hasAnyRole("ADMIN", "OPERATOR", "PARTNER") - .antMatchers("/bo/**", "/bo", "/documents/**") + .antMatchers("/bo/**", "/bo", "/documents/**", "/bo/dashboard") .hasAnyRole("ADMIN", "OPERATOR") .anyRequest() .authenticated() diff --git a/dossierfacile-bo/src/main/java/fr/gouv/bo/controller/BODashboardController.java b/dossierfacile-bo/src/main/java/fr/gouv/bo/controller/BODashboardController.java new file mode 100644 index 000000000..4e15690e9 --- /dev/null +++ b/dossierfacile-bo/src/main/java/fr/gouv/bo/controller/BODashboardController.java @@ -0,0 +1,39 @@ +package fr.gouv.bo.controller; + +import fr.dossierfacile.common.entity.BOUser; +import fr.gouv.bo.dto.EmailDTO; +import fr.gouv.bo.service.LogService; +import fr.gouv.bo.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.security.Principal; +import java.util.List; + +@Controller +@RequestMapping(value = "/bo/dashboard") +public class BODashboardController { + public final String EMAIL = "email"; + @Autowired + private LogService logService; + @Autowired + private UserService userService; + + @GetMapping("") + public String myDashboard(Model model, Principal principal) { + if (principal == null) { + return "redirect:/login"; + } + BOUser operator = userService.findUserByEmail(principal.getName()); + List listTreatedCountByDay = logService.listLastTreatedFilesByOperator(operator.getId()); + + model.addAttribute("operator", operator); + model.addAttribute("listTreatedCountByDay", listTreatedCountByDay); + + model.addAttribute(EMAIL, new EmailDTO()); + return "bo/dashboard"; + } +} diff --git a/dossierfacile-bo/src/main/java/fr/gouv/bo/controller/BOTenantController.java b/dossierfacile-bo/src/main/java/fr/gouv/bo/controller/BOTenantController.java index 695461399..8a81d6455 100644 --- a/dossierfacile-bo/src/main/java/fr/gouv/bo/controller/BOTenantController.java +++ b/dossierfacile-bo/src/main/java/fr/gouv/bo/controller/BOTenantController.java @@ -224,7 +224,6 @@ public String processFile(@PathVariable("id") Long id, CustomMessage customMessa Tenant tenant = tenantService.find(id); checkPartnerRights(tenant, principal); tenantService.processFile(id, customMessage, principal); - tenantService.updateOperatorDateTimeTenant(id); return tenantService.redirectToApplication(principal, null); } diff --git a/dossierfacile-bo/src/main/java/fr/gouv/bo/dto/CustomMessage.java b/dossierfacile-bo/src/main/java/fr/gouv/bo/dto/CustomMessage.java index cf57de863..f3331e305 100644 --- a/dossierfacile-bo/src/main/java/fr/gouv/bo/dto/CustomMessage.java +++ b/dossierfacile-bo/src/main/java/fr/gouv/bo/dto/CustomMessage.java @@ -13,6 +13,7 @@ @NoArgsConstructor @Builder public class CustomMessage { + private String timeSpent; private List messageItems = new ArrayList<>(); private List guarantorItems = new ArrayList<>(); } diff --git a/dossierfacile-bo/src/main/java/fr/gouv/bo/model/ProcessedDocuments.java b/dossierfacile-bo/src/main/java/fr/gouv/bo/model/ProcessedDocuments.java index a57f6d3b7..3a481fb52 100644 --- a/dossierfacile-bo/src/main/java/fr/gouv/bo/model/ProcessedDocuments.java +++ b/dossierfacile-bo/src/main/java/fr/gouv/bo/model/ProcessedDocuments.java @@ -1,15 +1,23 @@ package fr.gouv.bo.model; import fr.gouv.bo.dto.CustomMessage; +import lombok.extern.slf4j.Slf4j; -public record ProcessedDocuments(Integer count) { +@Slf4j +public record ProcessedDocuments(Integer count, Integer timeSpent) { - public static final ProcessedDocuments NONE = new ProcessedDocuments(null); - public static final ProcessedDocuments ONE = new ProcessedDocuments(1); + public static final ProcessedDocuments NONE = new ProcessedDocuments(null, null); + public static final ProcessedDocuments ONE = new ProcessedDocuments(1, null); public static ProcessedDocuments in(CustomMessage customMessage) { int count = customMessage.getMessageItems().size() + customMessage.getGuarantorItems().size(); - return new ProcessedDocuments(count); + try { + int timeSpent = Integer.parseInt(customMessage.getTimeSpent()) / 1000; + return new ProcessedDocuments(count, timeSpent); + } catch (Exception e) { + log.error("Unable to parse timeSpent in customMessage ts= " + customMessage.getTimeSpent()); + } + return new ProcessedDocuments(count, null); } } diff --git a/dossierfacile-bo/src/main/java/fr/gouv/bo/repository/BoLogRepository.java b/dossierfacile-bo/src/main/java/fr/gouv/bo/repository/BoLogRepository.java index fcf512a60..51d31f316 100644 --- a/dossierfacile-bo/src/main/java/fr/gouv/bo/repository/BoLogRepository.java +++ b/dossierfacile-bo/src/main/java/fr/gouv/bo/repository/BoLogRepository.java @@ -4,6 +4,8 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; @@ -14,4 +16,14 @@ public interface BoLogRepository extends JpaRepository { Page findAll(Pageable pageable); Page findAllByTenantId(Long tenantId, Pageable pageable); + + @Query(value = """ + SELECT DATE(creation_date) AS creation_date, COUNT(*) AS record_count + FROM tenant_log + WHERE operator_id = :operatorId + AND ( log_type = 'ACCOUNT_VALIDATED' OR log_type = 'ACCOUNT_DENIED' ) + AND creation_date BETWEEN CURRENT_DATE - :minusDays AND CURRENT_DATE + 1 + GROUP BY DATE(creation_date) + """, nativeQuery = true) + List countTreatedFromXDaysGroupByDate(@Param("operatorId") Long operatorId, @Param("minusDays") int minusDays); } diff --git a/dossierfacile-bo/src/main/java/fr/gouv/bo/service/LogService.java b/dossierfacile-bo/src/main/java/fr/gouv/bo/service/LogService.java index dd2fc8eed..3daf76a53 100644 --- a/dossierfacile-bo/src/main/java/fr/gouv/bo/service/LogService.java +++ b/dossierfacile-bo/src/main/java/fr/gouv/bo/service/LogService.java @@ -34,4 +34,8 @@ public void saveByLog(Log log) { logRepository.save(log); } + public List listLastTreatedFilesByOperator(Long operatorId){ + return logRepository.countTreatedFromXDaysGroupByDate(operatorId, 3); + } + } diff --git a/dossierfacile-bo/src/main/java/fr/gouv/bo/service/TenantService.java b/dossierfacile-bo/src/main/java/fr/gouv/bo/service/TenantService.java index 84aa63e0e..c79dd121d 100644 --- a/dossierfacile-bo/src/main/java/fr/gouv/bo/service/TenantService.java +++ b/dossierfacile-bo/src/main/java/fr/gouv/bo/service/TenantService.java @@ -522,8 +522,13 @@ public void updateOperatorDateTimeTenant(Long tenantId) { } //todo : Review this method to refactor with the others DENY OR VALIDATE documents for tenants - public String processFile(Long tenantId, CustomMessage customMessage, Principal principal) { + public synchronized String processFile(Long tenantId, CustomMessage customMessage, Principal principal) { Tenant tenant = find(tenantId); + //check tenant status before trying to validate or to deny + if ( tenant.getStatus() != TenantFileStatus.TO_PROCESS) { + log.error("Operator try to validate/deny a not TO PROCESS tenant : t={} op={}", tenantId, principal.getName()); + throw new IllegalStateException("You cannot treat a tenant which is not TO PROCESS"); + } User operator = userService.findUserByEmail(principal.getName()); if (tenant == null) { @@ -540,6 +545,7 @@ public String processFile(Long tenantId, CustomMessage customMessage, Principal Message message = sendCustomMessage(tenant, customMessage, checkValueOfCustomMessage(customMessage)); changeTenantStatusToDeclined(tenant, operator, message, processedDocuments); } + updateOperatorDateTimeTenant(tenantId); return "redirect:/bo"; } @@ -589,7 +595,7 @@ private void changeTenantStatusToValidated(Tenant tenant, User operator, Process tenantRepository.save(tenant); logService.saveByLog(new Log(LogType.ACCOUNT_VALIDATED, tenant.getId(), operator.getId())); - operatorLogRepository.save(new OperatorLog(tenant, operator, tenant.getStatus(), ActionOperatorType.STOP_PROCESS, processedDocuments.count())); + operatorLogRepository.save(new OperatorLog(tenant, operator, tenant.getStatus(), ActionOperatorType.STOP_PROCESS, processedDocuments.count(), processedDocuments.timeSpent() )); if (tenant.getApartmentSharing().getApplicationType() == ApplicationType.GROUP) { mailService.sendEmailToTenantAfterValidateAllDocumentsOfTenant(tenant); @@ -612,7 +618,7 @@ private void changeTenantStatusToDeclined(Tenant tenant, User operator, Message logService.saveByLog(new Log(LogType.ACCOUNT_DENIED, tenant.getId(), operator.getId(), (message == null) ? null : message.getId())); operatorLogRepository.save(new OperatorLog( - tenant, operator, tenant.getStatus(), ActionOperatorType.STOP_PROCESS, processedDocuments.count() + tenant, operator, tenant.getStatus(), ActionOperatorType.STOP_PROCESS, processedDocuments.count(), processedDocuments.timeSpent() )); if (tenant.getApartmentSharing().getApplicationType() == ApplicationType.COUPLE) { tenant.getApartmentSharing().getTenants().stream() diff --git a/dossierfacile-bo/src/main/resources/static/js/process-file.js b/dossierfacile-bo/src/main/resources/static/js/process-file.js index 514a2fd73..41c108fbe 100644 --- a/dossierfacile-bo/src/main/resources/static/js/process-file.js +++ b/dossierfacile-bo/src/main/resources/static/js/process-file.js @@ -32,6 +32,7 @@ $(document).keydown(function (e) { }); var textArea = true; +var startTime = null; $(document).on("keydown", function (event) { //ctrl+1 if ((event.which == 49 && event.ctrlKey)) { @@ -71,6 +72,24 @@ $(document).ready(function () { $('#validDecline').click(); }); + startTime = new Date(); + document.addEventListener('visibilitychange', function () { + if (document.visibilityState === 'visible') { + startTime = new Date() ; + } else { + if (startTime) { + var timeSpent = (new Date() - startTime) + Number(document.getElementById('timeSpent').value); + document.getElementById('timeSpent').value = timeSpent; + } + } + }); + document.getElementById('validDecline').addEventListener('click', function () { + var timeSpent = (new Date() - startTime) + Number(document.getElementById('timeSpent').value); + document.getElementById('timeSpent').value = timeSpent; + console.log('time spent in ms = ' + timeSpent); + document.getElementById('processFileForm').submit(); + }); + function updateStatus() { var list=[]; var checkboxChecked = $('[type="checkbox"]').filter((k,v) => v.checked === true); diff --git a/dossierfacile-bo/src/main/resources/templates/bo/apartment-sharing-view.html b/dossierfacile-bo/src/main/resources/templates/bo/apartment-sharing-view.html index 3ea5ecec8..6adfc649d 100644 --- a/dossierfacile-bo/src/main/resources/templates/bo/apartment-sharing-view.html +++ b/dossierfacile-bo/src/main/resources/templates/bo/apartment-sharing-view.html @@ -499,7 +499,7 @@

Partner(s)

- + diff --git a/dossierfacile-bo/src/main/resources/templates/bo/dashboard.html b/dossierfacile-bo/src/main/resources/templates/bo/dashboard.html new file mode 100644 index 000000000..0efd6700c --- /dev/null +++ b/dossierfacile-bo/src/main/resources/templates/bo/dashboard.html @@ -0,0 +1,46 @@ + + + + DossierFacile + + +
+
+

Info Opérateur

+
Déclaration sur l'honneur
Mot du locataire
+ + + + + + + + +
Id
Email
+ +
+

Les derniers dossiers traités

+
+ + + + + + + + + + + + + +
DateNombre de dossiers traités
+
+
+ + + + diff --git a/dossierfacile-bo/src/main/resources/templates/bo/process-file.html b/dossierfacile-bo/src/main/resources/templates/bo/process-file.html index 3cf5e0436..945f6bbb9 100644 --- a/dossierfacile-bo/src/main/resources/templates/bo/process-file.html +++ b/dossierfacile-bo/src/main/resources/templates/bo/process-file.html @@ -327,6 +327,7 @@

Vérifications automatiques :

+
diff --git a/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/converter/AcquisitionData.java b/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/converter/AcquisitionData.java new file mode 100644 index 000000000..918aeccee --- /dev/null +++ b/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/converter/AcquisitionData.java @@ -0,0 +1,17 @@ +package fr.dossierfacile.common.converter; + +import lombok.Builder; +import org.springframework.util.MultiValueMap; + +@Builder +public record AcquisitionData(String campaign, String source, String medium) { + + public static AcquisitionData from(MultiValueMap params) { + return AcquisitionData.builder() + .campaign(params.getFirst("campaign")) + .source(params.getFirst("source")) + .medium(params.getFirst("medium")) + .build(); + } + +} diff --git a/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/entity/OperatorLog.java b/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/entity/OperatorLog.java index 1081476b9..e0c32fe52 100644 --- a/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/entity/OperatorLog.java +++ b/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/entity/OperatorLog.java @@ -55,17 +55,21 @@ public class OperatorLog { private Integer processedDocuments; - public OperatorLog(Tenant tenant, User operator, TenantFileStatus tenantFileStatus, ActionOperatorType actionOperatorType, Integer processedDocuments) { + @Column(name = "time_spent") + private Integer timeSpent; + + public OperatorLog(Tenant tenant, User operator, TenantFileStatus tenantFileStatus, ActionOperatorType actionOperatorType, Integer processedDocuments, Integer timeSpent) { this.tenant = tenant; this.operator = operator; this.tenantFileStatus = tenantFileStatus; this.actionOperatorType = actionOperatorType; creationDate = LocalDateTime.now(); this.processedDocuments = processedDocuments; + this.timeSpent = timeSpent; } public OperatorLog(Tenant tenant, User operator, TenantFileStatus tenantFileStatus, ActionOperatorType actionOperatorType) { - this(tenant, operator, tenantFileStatus, actionOperatorType, null); + this(tenant, operator, tenantFileStatus, actionOperatorType, null, null); } } diff --git a/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/entity/User.java b/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/entity/User.java index 0b166d4e7..2d00cdc79 100644 --- a/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/entity/User.java +++ b/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/entity/User.java @@ -117,6 +117,10 @@ public abstract class User implements Serializable { @OneToOne(mappedBy = "user", cascade = CascadeType.ALL) private ConfirmationToken confirmationToken; + private String acquisitionCampaign; + private String acquisitionSource; + private String acquisitionMedium; + public User(UserType userType){ this.userType = userType; } diff --git a/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/enums/LogType.java b/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/enums/LogType.java index dd557b812..b2efed924 100644 --- a/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/enums/LogType.java +++ b/dossierfacile-common-library/src/main/java/fr/dossierfacile/common/enums/LogType.java @@ -3,6 +3,8 @@ public enum LogType { CUSTOM_EMAIL(Constants.TENANT_MESSAGES), ACCOUNT_CREATED(null), + ACCOUNT_CREATED_VIA_KC(null), + ACCOUNT_LINK(null),// first connection on DF ACCOUNT_COMPLETED(null), ACCOUNT_DENIED("operatorId"), ACCOUNT_EDITED(null), diff --git a/dossierfacile-common-library/src/main/resources/db/changelog/databaseChangeLog.xml b/dossierfacile-common-library/src/main/resources/db/changelog/databaseChangeLog.xml index 745958fbe..751bf5027 100644 --- a/dossierfacile-common-library/src/main/resources/db/changelog/databaseChangeLog.xml +++ b/dossierfacile-common-library/src/main/resources/db/changelog/databaseChangeLog.xml @@ -127,5 +127,7 @@ + + diff --git a/dossierfacile-common-library/src/main/resources/db/migration/202311080001-add-processed-documents-time-spent-column.xml b/dossierfacile-common-library/src/main/resources/db/migration/202311080001-add-processed-documents-time-spent-column.xml new file mode 100644 index 000000000..425de1c10 --- /dev/null +++ b/dossierfacile-common-library/src/main/resources/db/migration/202311080001-add-processed-documents-time-spent-column.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/dossierfacile-common-library/src/main/resources/db/migration/202311090000-update-user-account-table.xml b/dossierfacile-common-library/src/main/resources/db/migration/202311090000-update-user-account-table.xml new file mode 100644 index 000000000..ecba1158d --- /dev/null +++ b/dossierfacile-common-library/src/main/resources/db/migration/202311090000-update-user-account-table.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/DataSourceDossierConfiguration.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/DataSourceDossierConfiguration.java deleted file mode 100644 index 4c87b2b08..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/DataSourceDossierConfiguration.java +++ /dev/null @@ -1,76 +0,0 @@ -package fr.dossierfacile.garbagecollector.configuration; - - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; -import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import javax.sql.DataSource; -import java.util.HashMap; - -@Configuration -@EnableTransactionManagement -@PropertySource({"classpath:application.properties"}) -@EnableJpaRepositories(entityManagerFactoryRef = "dossierEntityManager", transactionManagerRef = "dossierTransactionManager", - basePackages = {"fr.dossierfacile.garbagecollector.repo.guarantor","fr.dossierfacile.garbagecollector.repo.document", "fr.dossierfacile.garbagecollector.repo.file", "fr.dossierfacile.garbagecollector.repo.garbagecollection", "fr.dossierfacile.common"}) -public class DataSourceDossierConfiguration { - @Autowired - private Environment env; - - @Bean - public LocalContainerEntityManagerFactoryBean dossierEntityManager() { - LocalContainerEntityManagerFactoryBean em - = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(productDataSource()); - em.setPackagesToScan( - "fr.dossierfacile.garbagecollector.repo.guarantor", "fr.dossierfacile.garbagecollector.model.document", "fr.dossierfacile.garbagecollector.model.file", "fr.dossierfacile.garbagecollector.model.garbagecollection", "fr.dossierfacile.common"); - - HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); - em.setJpaVendorAdapter(vendorAdapter); - HashMap properties = new HashMap<>(); - properties.put("hibernate.hbm2ddl.auto", - env.getProperty("hibernate.hbm2ddl.auto")); - properties.put("hibernate.dialect", - env.getProperty("hibernate.dialect")); - properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName()); - properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName()); - em.setJpaPropertyMap(properties); - - return em; - } - - @Bean - public DataSource productDataSource() { - - DriverManagerDataSource dataSource - = new DriverManagerDataSource(); - dataSource.setDriverClassName( - env.getProperty("postgre2.datasource.driver-class-name")); - dataSource.setUrl(env.getProperty("postgre2.datasource.url")); - dataSource.setUsername(env.getProperty("postgre2.datasource.username")); - dataSource.setPassword(env.getProperty("postgre2.datasource.password")); - - return dataSource; - } - - @Bean - public PlatformTransactionManager dossierTransactionManager() { - - JpaTransactionManager transactionManager - = new JpaTransactionManager(); - transactionManager.setEntityManagerFactory( - dossierEntityManager().getObject()); - return transactionManager; - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/DataSourceObjectConfiguration.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/DataSourceObjectConfiguration.java deleted file mode 100644 index 52e8b39fd..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/DataSourceObjectConfiguration.java +++ /dev/null @@ -1,109 +0,0 @@ -package fr.dossierfacile.garbagecollector.configuration; - -import liquibase.integration.spring.SpringLiquibase; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.data.jpa.datatables.repository.DataTablesRepositoryFactoryBean; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import javax.sql.DataSource; -import java.util.HashMap; - -@Configuration -@EnableTransactionManagement -@PropertySource({"classpath:application.properties"}) -@EnableJpaRepositories(entityManagerFactoryRef = "objectEntityManager", transactionManagerRef = "objectTransactionManager", - basePackages = { "fr.dossierfacile.garbagecollector.repo.object","fr.dossierfacile.garbagecollector.repo.marker" }, - repositoryFactoryBeanClass = DataTablesRepositoryFactoryBean.class) -public class DataSourceObjectConfiguration { - - @Autowired - private Environment env; - - @Bean - @Primary - public LocalContainerEntityManagerFactoryBean objectEntityManager() { - LocalContainerEntityManagerFactoryBean em - = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(userDataSource()); - em.setPackagesToScan( - "fr.dossierfacile.garbagecollector.model.object","fr.dossierfacile.garbagecollector.model.marker"); - - HibernateJpaVendorAdapter vendorAdapter - = new HibernateJpaVendorAdapter(); - em.setJpaVendorAdapter(vendorAdapter); - HashMap properties = new HashMap<>(); - properties.put("hibernate.hbm2ddl.auto", - env.getProperty("hibernate.hbm2ddl.auto")); - properties.put("hibernate.dialect", - env.getProperty("hibernate.dialect")); - em.setJpaPropertyMap(properties); - - return em; - } - - @Primary - @Bean - public DataSource userDataSource() { - - DriverManagerDataSource dataSource - = new DriverManagerDataSource(); - dataSource.setDriverClassName( - env.getProperty("postgre.datasource.driver-class-name")); - dataSource.setUrl(env.getProperty("postgre.datasource.jdbc-url")); - dataSource.setUsername(env.getProperty("postgre.datasource.username")); - dataSource.setPassword(env.getProperty("postgre.datasource.password")); - - return dataSource; - } - - @Primary - @Bean - public PlatformTransactionManager objectTransactionManager() { - - JpaTransactionManager transactionManager - = new JpaTransactionManager(); - transactionManager.setEntityManagerFactory( - objectEntityManager().getObject()); - return transactionManager; - } - - - @Bean - @ConfigurationProperties(prefix = "postgre.datasource") - public DataSource secondaryDataSource() { - return DataSourceBuilder.create().build(); - } - - @Bean - @ConfigurationProperties(prefix = "postgre.datasource.liquibase") - public LiquibaseProperties secondaryLiquibaseProperties() { - return new LiquibaseProperties(); - } - - @Bean - public SpringLiquibase secondaryLiquibase() { - return springLiquibase(secondaryDataSource(), secondaryLiquibaseProperties()); - } - - private static SpringLiquibase springLiquibase(DataSource dataSource, LiquibaseProperties properties) { - SpringLiquibase liquibase = new SpringLiquibase(); - liquibase.setDataSource(dataSource); - liquibase.setChangeLog("classpath:db/changelog/databaseCollectorChangeLog.xml"); - return liquibase; - } - -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/MvcConfig.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/MvcConfig.java deleted file mode 100644 index 3b56ff0a0..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/MvcConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package fr.dossierfacile.garbagecollector.configuration; - -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -public class MvcConfig implements WebMvcConfigurer { - - public void addViewControllers(ViewControllerRegistry registry) { - registry.addViewController("/login").setViewName("login"); - } - -} \ No newline at end of file diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/SecurityConfiguration.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/SecurityConfiguration.java deleted file mode 100644 index 93ce5e822..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/SecurityConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -package fr.dossierfacile.garbagecollector.configuration; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - - -@Configuration -@EnableWebSecurity -class SecurityConfiguration extends WebSecurityConfigurerAdapter { - - @Value("${app.username}") - private String username; - @Value("${app.password}") - private String password; - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .antMatchers("/").permitAll() - .anyRequest().authenticated() - .and() - .formLogin() - .loginPage("/login") - .permitAll() - .and() - .logout() - .permitAll(); - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication() - .passwordEncoder(passwordEncoder()) - .withUser(username).password(passwordEncoder().encode(password)).roles("USER"); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - -} \ No newline at end of file diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/controller/FileController.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/controller/FileController.java deleted file mode 100644 index ec53f8732..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/controller/FileController.java +++ /dev/null @@ -1,47 +0,0 @@ -package fr.dossierfacile.garbagecollector.controller; - -import fr.dossierfacile.garbagecollector.service.interfaces.OvhService; -import java.io.IOException; -import java.io.InputStream; -import javax.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.IOUtils; -import org.openstack4j.model.storage.object.SwiftObject; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; - -@RequiredArgsConstructor -@Controller -@Slf4j -public class FileController { - - private static final String FILE_NO_EXIST = "The file does not exist"; - - private final OvhService ovhService; - - @GetMapping("/tenants_files/{fileName:.+}") - public void getImageAsByteArray(@PathVariable("fileName") String fileName, HttpServletResponse response) { - SwiftObject object = ovhService.get(fileName); - if (object != null) { - try (InputStream in = object.download().getInputStream()) { - if (fileName.endsWith(".pdf")) { - response.setContentType(MediaType.APPLICATION_PDF_VALUE); - } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) { - response.setContentType(MediaType.IMAGE_JPEG_VALUE); - } else { - response.setContentType(MediaType.IMAGE_PNG_VALUE); - } - IOUtils.copy(in, response.getOutputStream()); - } catch (final IOException e) { - log.error(FILE_NO_EXIST); - response.setStatus(404); - } - } else { - log.error(FILE_NO_EXIST); - response.setStatus(404); - } - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/controller/ObjectController.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/controller/ObjectController.java deleted file mode 100644 index 47050b66c..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/controller/ObjectController.java +++ /dev/null @@ -1,107 +0,0 @@ -package fr.dossierfacile.garbagecollector.controller; - -import com.fasterxml.jackson.annotation.JsonView; -import fr.dossierfacile.garbagecollector.model.object.Object; -import fr.dossierfacile.garbagecollector.service.ScheduledDeleteService; -import fr.dossierfacile.garbagecollector.service.interfaces.MarkerService; -import fr.dossierfacile.garbagecollector.service.interfaces.ObjectService; -import fr.dossierfacile.garbagecollector.service.interfaces.OvhService; -import fr.dossierfacile.garbagecollector.transactions.interfaces.MarkerTransactions; -import fr.dossierfacile.garbagecollector.transactions.interfaces.ObjectTransactions; -import java.util.ArrayList; -import java.util.List; -import javax.validation.Valid; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.jpa.datatables.mapping.DataTablesInput; -import org.springframework.data.jpa.datatables.mapping.DataTablesOutput; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; - -@Slf4j -@Controller -@RequiredArgsConstructor -public class ObjectController { - - private final ObjectService objectService; - private final OvhService ovhService; - private final MarkerService markerService; - private final ScheduledDeleteService scheduledDeleteService; - private final ObjectTransactions objectTransactions; - private final MarkerTransactions markerTransactions; - - @GetMapping("/") - public String index() { - return "redirect:checker"; - } - - //main view - @GetMapping("/checker") - public String object(Model model) { - model.addAttribute("total_objects_to_delete", objectService.countAllObjectsForDeletion()); - model.addAttribute("total_objects_scanned", objectService.countAllObjectsScanned()); - model.addAttribute("is_scanner_running", markerService.isRunning()); - model.addAttribute("is_delete_running", scheduledDeleteService.isActive()); - - return "index"; - } - - //get objects - @GetMapping("/start-stop-scanner") - public String toggleScanner() { - boolean toggleToStart = markerService.toggleScanner(); - if (toggleToStart) { - markerService.startScanner(); - } - return "redirect:/checker"; - } - - @GetMapping("/restart-scanner") - public String restartScanner() { - markerService.stopScanner(); - - // waiting until the scanner stop - while (markerService.stoppingScanner()) {} - - objectTransactions.deleteAllObjects(); - markerTransactions.deleteAllMarkers(); - - markerService.setRunningToTrue(); - markerService.startScanner(); - return "redirect:/checker"; - } - - @GetMapping(value = "/update-scanner-info", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> currentReadObjects() { - List result = new ArrayList<>(); - result.add(String.valueOf(objectService.countAllObjectsForDeletion())); - result.add(String.valueOf(objectService.countAllObjectsScanned())); - result.add(String.valueOf(markerService.isRunning())); - result.add(String.valueOf(scheduledDeleteService.isActive())); - return ResponseEntity.ok(result); - } - - @JsonView(DataTablesOutput.View.class) - @GetMapping(value = "/objects") - public ResponseEntity> getObjects(@Valid DataTablesInput input) { - return ResponseEntity.ok(objectService.getAllObjectsForDeletion(input)); - } - - //delete one object - @GetMapping("/delete/{path}") - public String deleteObject(@PathVariable("path") String path) { - ovhService.delete(path); - objectService.deleteObjectByPath(path); - return "redirect:/checker"; - } - - @GetMapping("/delete/toggle") - public String toggleDelete() { - scheduledDeleteService.setIsActive(!scheduledDeleteService.isActive()); - return "redirect:/checker"; - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/dto/PathDTO.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/dto/PathDTO.java deleted file mode 100644 index 7fa9398a4..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/dto/PathDTO.java +++ /dev/null @@ -1,19 +0,0 @@ -package fr.dossierfacile.garbagecollector.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - - -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -@Getter -@Setter -public class PathDTO { - private String path; -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/exceptions/OvhConnectionFailedException.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/exceptions/OvhConnectionFailedException.java deleted file mode 100644 index 579adafeb..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/exceptions/OvhConnectionFailedException.java +++ /dev/null @@ -1,14 +0,0 @@ -package fr.dossierfacile.garbagecollector.exceptions; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(HttpStatus.BAD_REQUEST) -public class OvhConnectionFailedException extends RuntimeException { - public OvhConnectionFailedException(String message, Throwable throwable) { - super(message, throwable); - } - public OvhConnectionFailedException(String message) { - super(message); - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/document/GarbageDocument.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/document/GarbageDocument.java deleted file mode 100644 index 53399fad4..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/document/GarbageDocument.java +++ /dev/null @@ -1,31 +0,0 @@ -package fr.dossierfacile.garbagecollector.model.document; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import java.io.Serializable; - -@Entity -@AllArgsConstructor -@NoArgsConstructor -@Data -@Builder -@Table(name = "document") -public class GarbageDocument implements Serializable { - - private static final long serialVersionUID = -3603815939453106021L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String name; - -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/file/GarbageFile.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/file/GarbageFile.java deleted file mode 100644 index d2309e744..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/file/GarbageFile.java +++ /dev/null @@ -1,42 +0,0 @@ -package fr.dossierfacile.garbagecollector.model.file; - -import fr.dossierfacile.common.entity.StorageFile; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import java.io.Serializable; - -@Entity -@AllArgsConstructor -@NoArgsConstructor -@Data -@Builder -@Table(name = "file") -public class GarbageFile implements Serializable { - - private static final long serialVersionUID = -6823677462929911744L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @OneToOne(cascade = CascadeType.REMOVE) - @JoinColumn(name = "storage_file_id") - private StorageFile storageFile; - - @OneToOne(cascade = CascadeType.REMOVE) - @JoinColumn(name = "preview_file_id") - private StorageFile preview; - - -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/marker/Marker.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/marker/Marker.java deleted file mode 100644 index eede7125b..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/marker/Marker.java +++ /dev/null @@ -1,28 +0,0 @@ -package fr.dossierfacile.garbagecollector.model.marker; - -import lombok.Getter; -import lombok.Setter; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import java.io.Serializable; - -@Getter -@Setter -@Entity -@Table(name = "marker") -public class Marker implements Serializable { - - private static final long serialVersionUID = -3603815939453106021L; - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "path") - private String path; - -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/object/Object.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/object/Object.java deleted file mode 100644 index f4e436c4f..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/object/Object.java +++ /dev/null @@ -1,34 +0,0 @@ -package fr.dossierfacile.garbagecollector.model.object; - -import com.fasterxml.jackson.annotation.JsonView; -import java.io.Serializable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import lombok.Getter; -import lombok.Setter; -import org.springframework.data.jpa.datatables.mapping.DataTablesOutput; - -@Getter -@Setter -@Entity -@Table(name = "object") -public class Object implements Serializable { - - private static final long serialVersionUID = 609998597255420002L; - - @JsonView(DataTablesOutput.View.class) - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @JsonView(DataTablesOutput.View.class) - @Column(name = "path") - private String path; - - @Column(name = "to_delete", columnDefinition = "boolean default false") - private boolean toDelete = false; -} \ No newline at end of file diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/document/DocumentRepository.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/document/DocumentRepository.java deleted file mode 100644 index 74de090c6..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/document/DocumentRepository.java +++ /dev/null @@ -1,35 +0,0 @@ -package fr.dossierfacile.garbagecollector.repo.document; - -import fr.dossierfacile.garbagecollector.model.document.GarbageDocument; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; - -public interface DocumentRepository extends JpaRepository { - @Query(value = "SELECT distinct document.* " + - "FROM document left join tenant on document.tenant_id=tenant.id " + - "where tenant.status='ARCHIVED' and document.name is not null " + - "and document.name <> '' " + - "ORDER BY document.id desc LIMIT :limit", nativeQuery = true) - List getArchivedDocumentWithPdf(@Param("limit") Integer limit); - - @Query(value = "SELECT distinct document.* " + - "FROM document left join guarantor on document.guarantor_id=guarantor.id " + - "LEFT JOIN tenant on guarantor.tenant_id=tenant.id " + - "where tenant.status='ARCHIVED' and document.name is not null " + - "and document.name <> '' " + - "ORDER BY document.id desc LIMIT :limit", nativeQuery = true) - List getGuarantorArchivedDocumentWithPdf(@Param("limit") Integer limit); - - @Query(value = "select d1.*\n" + - "from document d1\n" + - "where d1.tenant_id = :tenantId\n" + - "union\n" + - "select d2.*\n" + - "from document d2\n" + - " join guarantor g on d2.guarantor_id = g.id\n" + - "where g.tenant_id = :tenantId", nativeQuery = true) - List findAllAssociatedToTenantId(Long tenantId); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/file/FileRepository.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/file/FileRepository.java deleted file mode 100644 index d14533c9d..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/file/FileRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package fr.dossierfacile.garbagecollector.repo.file; - -import fr.dossierfacile.garbagecollector.model.file.GarbageFile; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; - -public interface FileRepository extends JpaRepository { - - @Query(value = """ - select path from storage_file sf where sf.path in (:path) - """, nativeQuery = true) - List existingFiles(@Param("path") List path); - -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/guarantor/GuarantorRepository.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/guarantor/GuarantorRepository.java deleted file mode 100644 index f465dfd61..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/guarantor/GuarantorRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package fr.dossierfacile.garbagecollector.repo.guarantor; - -import fr.dossierfacile.common.entity.Guarantor; -import fr.dossierfacile.common.entity.Tenant; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface GuarantorRepository extends JpaRepository { - - List findGuarantorsByTenant(Tenant tenant); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/marker/MarkerRepository.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/marker/MarkerRepository.java deleted file mode 100644 index d681078bb..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/marker/MarkerRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package fr.dossierfacile.garbagecollector.repo.marker; - -import fr.dossierfacile.garbagecollector.model.marker.Marker; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -public interface MarkerRepository extends JpaRepository { - Marker findByPath(String path); - - @Query(value = "SELECT * FROM marker ORDER BY id DESC LIMIT 2", nativeQuery = true) - List lastTwoMarkers(); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/object/ObjectRepository.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/object/ObjectRepository.java deleted file mode 100644 index 19246f1c4..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/object/ObjectRepository.java +++ /dev/null @@ -1,31 +0,0 @@ -package fr.dossierfacile.garbagecollector.repo.object; - -import fr.dossierfacile.garbagecollector.model.object.Object; -import java.util.List; -import org.springframework.data.jpa.datatables.repository.DataTablesRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.transaction.annotation.Transactional; - -public interface ObjectRepository extends DataTablesRepository { - - Object findObjectByPath(String path); - - @Query(value = "SELECT * FROM object where object.path in (:paths)", nativeQuery = true) - List findObjectsByPaths(List paths); - - void deleteByPath(String path); - - long countByToDeleteIsTrue(); - - @Query(value = "SELECT * FROM object where to_delete = true ORDER BY id LIMIT :limit", nativeQuery = true) - List getBatchObjectsForDeletion(@Param("limit") Integer limit); - - @Modifying - @Transactional - @Query(value = "delete from object where id > (select id from object where path = :path)", nativeQuery = true) - void deleteObjectsMayorThan(@Param("path") String path); - - long countAllByPath(String path); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/MarkerServiceImpl.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/MarkerServiceImpl.java deleted file mode 100644 index e7e25b008..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/MarkerServiceImpl.java +++ /dev/null @@ -1,214 +0,0 @@ -package fr.dossierfacile.garbagecollector.service; - -import fr.dossierfacile.garbagecollector.model.marker.Marker; -import fr.dossierfacile.garbagecollector.model.object.Object; -import fr.dossierfacile.garbagecollector.repo.file.FileRepository; -import fr.dossierfacile.garbagecollector.repo.marker.MarkerRepository; -import fr.dossierfacile.garbagecollector.repo.object.ObjectRepository; -import fr.dossierfacile.garbagecollector.service.interfaces.MarkerService; -import fr.dossierfacile.garbagecollector.service.interfaces.OvhService; -import fr.dossierfacile.garbagecollector.transactions.interfaces.MarkerTransactions; -import fr.dossierfacile.garbagecollector.transactions.interfaces.ObjectTransactions; - -import java.util.List; -import java.util.stream.Collectors; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.openstack4j.api.storage.ObjectStorageObjectService; -import org.openstack4j.model.storage.object.SwiftObject; -import org.openstack4j.model.storage.object.options.ObjectListOptions; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.springframework.util.Assert; - -@Service -@Slf4j -@RequiredArgsConstructor -public class MarkerServiceImpl implements MarkerService { - - private static final int PAGE_SIZE = 50; - public static final String MARKER_FOR_DELETION = "GARBAGE_"; - - private final OvhService ovhService; - private final MarkerTransactions markerTransactions; - private final ObjectTransactions objectTransactions; - private final MarkerRepository markerRepository; - private final ObjectRepository objectRepository; - private final FileRepository fileRepository; - - private boolean isRunning = false; - private boolean isCanceled = false; - - @Value("${ovh.container:default}") - private String ovhContainerName; - - @Override - public boolean toggleScanner() { - boolean toggleToStart = false; - if (isRunning) { - //the startScanner() method WILL STOP running (isRunning=false) after reading isCanceled = true; - isCanceled = true; - } else { - //the startScanner() method WILL START running (isRunning=true) after the controller launch it - isCanceled = false; - isRunning = true; - toggleToStart = true; - } - return toggleToStart; - } - - @Override - public boolean isRunning() { - return isRunning; - } - - @Override - public boolean stoppingScanner() { - return isRunning && isCanceled; - } - - @Override - public void stopScanner() { - if (isRunning) { - isCanceled = true; - } - } - - @Override - public void setRunningToTrue() { - isRunning = true; - } - - @Override - @Async - public void startScanner() { - if (isCanceled) { - isRunning = false; - isCanceled = false; - return; - } - log.info("Starting/Resuming scanner ..."); - log.info("Connecting to OVH ...\n"); - - final ObjectStorageObjectService objService = ovhService.getObjectStorage(); - - int iterationNumber = 1; - try { - final ObjectListOptions listOptions = initialize(); - - int totalObjectsRead = (int) objectRepository.count(); - - log.info("\n----------------------------------------" + - "\nTotal objects read : " + totalObjectsRead + - "\n----------------------------------------"); - - List objects; - do { - long iterationElapsedTime = System.currentTimeMillis(); - if (isCanceled) { - break; - } - //get list of object from OVH - long start1 = System.currentTimeMillis(); - objects = objService.list(ovhContainerName, listOptions); - long end1 = System.currentTimeMillis(); - System.out.println("Elapsed Time for get object list in mili seconds: " + (end1 - start1)); - //save marker - if (!objects.isEmpty()) { - String nameLastElement = objects.get(objects.size() - 1).getName(); - listOptions.marker(nameLastElement); - - markerTransactions.saveMarkerIfNotYetSaved(nameLastElement); - - start1 = System.currentTimeMillis(); - List existingObjects = objectRepository.findObjectsByPaths(objects.stream().map(SwiftObject::getName).collect(Collectors.toList())); - objects = objects.stream().filter(o -> existingObjects.stream().filter(e -> e.getPath().equals(o.getName())).findAny().isEmpty()).collect(Collectors.toList()); - - end1 = System.currentTimeMillis(); - System.out.println("Elapsed Time for object filtering in mili seconds: " + (end1 - start1)); - - start1 = System.currentTimeMillis(); - List names = objects.stream() - .map(SwiftObject::getName) - .filter(name -> !name.startsWith(MARKER_FOR_DELETION)) - .collect(Collectors.toList()); - List matchingFilesInDB = fileRepository.existingFiles(names); - end1 = System.currentTimeMillis(); - System.out.println("Elapsed Time for get existing files in mili seconds: " + (end1 - start1)); - - objects.parallelStream().forEach(swiftObject -> { - if (isCanceled) { - return; - } - String nameFile = swiftObject.getName(); - try { - if (!nameFile.startsWith(MARKER_FOR_DELETION)) { - nameFile = renameFileIfNotInDatabase(nameFile, matchingFilesInDB); - } - objectTransactions.saveObject(nameFile); - } catch (Exception e) { - log.error(e.getMessage(), e); - } - }); - - //copy the names of objects from OVH to DB - if (isCanceled) { - break; - } - totalObjectsRead = (int) objectRepository.count(); - iterationElapsedTime = System.currentTimeMillis() - iterationElapsedTime; - String textIteration = "------ Iteration [" + iterationNumber++ + "] ------- " + iterationElapsedTime / 1000 + "sec. --"; - log.info("\n\n" + textIteration + - "\nTotal objects read : " + totalObjectsRead + - "\n" + "-".repeat(textIteration.length()) + "\n"); - Thread.sleep(1000); - } else { - log.info("SCANNING FINISHED\n"); - } - } while (!objects.isEmpty()); - - } catch (Exception e) { - log.error(e.getMessage(), e.getCause()); - } - log.info("Disconnecting from OVH ...\n"); - isRunning = false; - isCanceled = false; - } - - private ObjectListOptions initialize() { - final ObjectListOptions listOptions = ObjectListOptions.create().limit(PAGE_SIZE); - if (markerRepository.count() == 0) { - return listOptions; - } else if (markerRepository.count() == 1) { - markerTransactions.deleteAllMarkers(); - objectTransactions.deleteAllObjects(); - } else { - // markerRepository.count() >= 2 - List lastTwoMarkers = markerRepository.lastTwoMarkers(); - Marker lastMarker = lastTwoMarkers.get(0); - Marker penultimateMarker = lastTwoMarkers.get(1); - - String markerBeforeLastOne = penultimateMarker.getPath(); - listOptions.marker(markerBeforeLastOne); - - //delete last marker to ensure checking again all elements between penultimate and last elements were processed - markerTransactions.deleteMarker(lastMarker); - long number1 = objectRepository.countAllByPath(penultimateMarker.getPath()); - long number2 = objectRepository.countAllByPath(MARKER_FOR_DELETION + penultimateMarker.getPath()); - Assert.isTrue(number1 + number2 == 1, "There is no exactly 1 marker with name [" + penultimateMarker.getPath() + "] or [" + MARKER_FOR_DELETION + penultimateMarker.getPath() + "] in the objects saved"); - objectTransactions.deleteObjectsMayorThan(penultimateMarker.getPath()); - } - return listOptions; - } - - private String renameFileIfNotInDatabase(String nameFile, List names) { - if (!names.contains(nameFile)) { - String oldName = nameFile; - nameFile = MARKER_FOR_DELETION + nameFile; - ovhService.renameFile(oldName, nameFile); - } - return nameFile; - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ObjectServiceImpl.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ObjectServiceImpl.java deleted file mode 100644 index 4621028a9..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ObjectServiceImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -package fr.dossierfacile.garbagecollector.service; - -import fr.dossierfacile.garbagecollector.model.object.Object; -import fr.dossierfacile.garbagecollector.repo.object.ObjectRepository; -import fr.dossierfacile.garbagecollector.service.interfaces.ObjectService; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.jpa.datatables.mapping.DataTablesInput; -import org.springframework.data.jpa.datatables.mapping.DataTablesOutput; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class ObjectServiceImpl implements ObjectService { - - private final ObjectRepository objectRepository; - - @Override - public List getBatchObjectsForDeletion(Integer limit) { - return objectRepository.getBatchObjectsForDeletion(limit); - } - - @Override - public DataTablesOutput getAllObjectsForDeletion(DataTablesInput input) { - Specification specification = (root, query, criteriaBuilder) -> criteriaBuilder.isTrue(root.get("toDelete")); - return objectRepository.findAll(input, specification); - } - - @Override - public long countAllObjectsScanned() { - return objectRepository.count(); - } - - @Override - public long countAllObjectsForDeletion() { - return objectRepository.countByToDeleteIsTrue(); - } - - @Override - public void deleteList(List objectList) { - objectRepository.deleteAll(objectList); - } - - @Override - @Transactional - public void deleteObjectByPath(String path) { - objectRepository.deleteByPath(path); - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/OvhServiceImpl.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/OvhServiceImpl.java deleted file mode 100644 index 4210d90e8..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/OvhServiceImpl.java +++ /dev/null @@ -1,143 +0,0 @@ -package fr.dossierfacile.garbagecollector.service; - -import fr.dossierfacile.garbagecollector.exceptions.OvhConnectionFailedException; -import fr.dossierfacile.garbagecollector.service.interfaces.OvhService; -import io.sentry.Sentry; -import lombok.extern.slf4j.Slf4j; -import org.openstack4j.api.OSClient; -import org.openstack4j.api.exceptions.AuthenticationException; -import org.openstack4j.api.exceptions.ClientResponseException; -import org.openstack4j.api.storage.ObjectStorageObjectService; -import org.openstack4j.core.transport.Config; -import org.openstack4j.model.common.Identifier; -import org.openstack4j.model.storage.object.SwiftObject; -import org.openstack4j.model.storage.object.options.ObjectLocation; -import org.openstack4j.openstack.OSFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -@Slf4j -public class OvhServiceImpl implements OvhService { - private static final String OVH_CONNECT = "OVH connect. "; - private static final String EXCEPTION = "Sentry ID Exception: "; - - @Value("${ovh.project.domain:default}") - private String ovhProjectDomain; - @Value("${ovh.auth.url:default}") - private String ovhAuthUrl; - @Value("${ovh.username:default}") - private String ovhUsername; - @Value("${ovh.password:default}") - private String ovhPassword; - @Value("${ovh.project.name:default}") - private String ovhProjectName; - @Value("${ovh.region:default}") - private String ovhRegion; - @Value("${ovh.container:default}") - private String ovhContainerName; - @Value("${ovh.connection.reattempts:3}") - private Integer ovhConnectionReattempts; - private String tokenId; - - private OSClient.OSClientV3 connect() { - OSClient.OSClientV3 os = null; - Identifier domainIdentifier = Identifier.byId(ovhProjectDomain); - int attempts = 0; - while (attempts++ < ovhConnectionReattempts && os == null) { - try { - if (tokenId == null) { - os = OSFactory.builderV3() - .endpoint(ovhAuthUrl) - .credentials(ovhUsername, ovhPassword, domainIdentifier) - .scopeToProject(Identifier.byName(ovhProjectName), Identifier.byName(ovhProjectDomain)) - .withConfig(Config.newConfig().withReadTimeout(60000).withConnectionTimeout(60000)) - .authenticate(); - os.useRegion(ovhRegion); - tokenId = os.getToken().getId(); - } else { - os = OSFactory.builderV3() - .endpoint(ovhAuthUrl) - .token(tokenId) - .scopeToProject(Identifier.byName(ovhProjectName), Identifier.byName(ovhProjectDomain)) - .withConfig(Config.newConfig().withReadTimeout(60000).withConnectionTimeout(60000)) - .authenticate(); - os.useRegion(ovhRegion); - } - } catch (AuthenticationException | ClientResponseException e) { - if (e instanceof ClientResponseException) { - log.error(e.toString()); - } - os = OSFactory.builderV3() - .endpoint(ovhAuthUrl) - .credentials(ovhUsername, ovhPassword, domainIdentifier) - .scopeToProject(Identifier.byName(ovhProjectName), Identifier.byName(ovhProjectDomain)) - .withConfig(Config.newConfig().withReadTimeout(60000).withConnectionTimeout(60000)) - .authenticate(); - os.useRegion(ovhRegion); - tokenId = os.getToken().getId(); - } catch (Exception e) { - log.error(e.getMessage()); - if (attempts == ovhConnectionReattempts) { - log.error(OVH_CONNECT + EXCEPTION + Sentry.captureException(e)); - log.error(e.getClass().getName()); - String customExceptionMessage = OVH_CONNECT + "Could not connect to the storage provider after " + attempts + " attempts with given credentials"; - throw new OvhConnectionFailedException(customExceptionMessage, e.getCause()); - } - } - } - return os; - } - - @Override - @Async - public void delete(String name) { - connect().objectStorage().objects().delete(ovhContainerName, name); - } - - @Override - @Async - public void delete(List name) { - name.forEach(this::delete); - } - - @Override - public SwiftObject get(String name) { - return connect().objectStorage().objects().get(ovhContainerName, name); - } - - @Override - public ObjectStorageObjectService getObjectStorage() { - OSClient.OSClientV3 os = connect(); - return os.objectStorage().objects(); - } - - @Override - public void renameFile(String oldName, String newName) { - final ObjectStorageObjectService objService = getObjectStorage(); - String eTag = objService.copy(ObjectLocation.create(ovhContainerName, oldName), ObjectLocation.create(ovhContainerName, newName)); - if (eTag != null && !eTag.isEmpty()) { - objService.delete(ovhContainerName, oldName); - log.info("[" + oldName + "] renamed to [" + newName + "]"); - return; - } - log.info(eTag); - log.error("[" + oldName + "] was not renamed successfully"); - String customExceptionMessage = OVH_CONNECT + "Could not rename the file [" + oldName + "]"; - throw new OvhConnectionFailedException(customExceptionMessage); - } - - @Override - public boolean hasConnection() { - //check if there is connection to ovh - if (getObjectStorage() == null) { - log.warn("No connection to OVH " + "\n"); - return false; - } - return true; - } - -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledDeleteService.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledDeleteService.java deleted file mode 100644 index 1c8fbff3e..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledDeleteService.java +++ /dev/null @@ -1,71 +0,0 @@ -package fr.dossierfacile.garbagecollector.service; - -import fr.dossierfacile.common.entity.StorageFileToDelete; -import fr.dossierfacile.common.repository.StorageFileToDeleteRepository; -import fr.dossierfacile.common.service.interfaces.FileStorageToDeleteService; -import fr.dossierfacile.garbagecollector.model.object.Object; -import fr.dossierfacile.garbagecollector.service.interfaces.ObjectService; -import fr.dossierfacile.garbagecollector.service.interfaces.OvhService; -import fr.dossierfacile.garbagecollector.transactions.interfaces.ObjectTransactions; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; - -@Slf4j -@Service -@RequiredArgsConstructor -public class ScheduledDeleteService { - - private final StorageFileToDeleteRepository storageFileToDeleteRepository; - private final FileStorageToDeleteService fileStorageToDeleteService; - private static final Integer LIMIT_OBJECTS_TO_DELETE = 500; - private final ObjectService objectService; - private final ObjectTransactions objectTransactions; - private final OvhService ovhService; - private final AtomicBoolean isActive = new AtomicBoolean(false); - - public boolean isActive() { - return isActive.get(); - } - - public void setIsActive(boolean value) { - this.isActive.set(value); - } - - /** - * Every 5 seconds will delete a maximum of 500 elements - */ - @Scheduled(fixedDelay = 5000) - public void scheduleFixedDelayTask() { - if (!isActive.get()) return; - //check if there is connection to ovh - if (ovhService.getObjectStorage() == null) { - log.warn("No connection to OVH " + "\n"); - return; - } - List objectList = objectService.getBatchObjectsForDeletion(LIMIT_OBJECTS_TO_DELETE); - //check if there are data to process - if (objectList.isEmpty()) { - log.warn("No objects to remove found." + "\n"); - this.isActive.set(false); - return; - } - List allPaths = objectList.stream().map(Object::getPath).collect(Collectors.toList()); - ovhService.delete(allPaths); - objectTransactions.deleteListObjects(objectList); - System.out.println("Deleted files: " + objectList.size() + "\n"); - } - - @Scheduled(fixedDelay = 10000) - public void deleteFileInProviderTask() { - List storageFileToDeleteList = storageFileToDeleteRepository.findAll(); - for (StorageFileToDelete storageFileToDelete : storageFileToDeleteList) { - fileStorageToDeleteService.delete(storageFileToDelete); - } - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/MailService.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/MailService.java deleted file mode 100644 index 119b7ed85..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/MailService.java +++ /dev/null @@ -1,12 +0,0 @@ -package fr.dossierfacile.garbagecollector.service.interfaces; - -import fr.dossierfacile.common.entity.ConfirmationToken; -import fr.dossierfacile.common.entity.User; - -public interface MailService { - - void sendEmailFirstWarningForDeletionOfDocuments(User user, ConfirmationToken confirmationToken); - - void sendEmailSecondWarningForDeletionOfDocuments(User user, ConfirmationToken confirmationToken); - -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/MarkerService.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/MarkerService.java deleted file mode 100644 index bd9c6dcc5..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/MarkerService.java +++ /dev/null @@ -1,10 +0,0 @@ -package fr.dossierfacile.garbagecollector.service.interfaces; - -public interface MarkerService { - boolean toggleScanner(); - boolean isRunning(); - boolean stoppingScanner(); - void stopScanner(); - void setRunningToTrue(); - void startScanner(); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/ObjectService.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/ObjectService.java deleted file mode 100644 index 0384e98e2..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/ObjectService.java +++ /dev/null @@ -1,21 +0,0 @@ -package fr.dossierfacile.garbagecollector.service.interfaces; - -import fr.dossierfacile.garbagecollector.model.object.Object; -import java.util.List; -import org.springframework.data.jpa.datatables.mapping.DataTablesInput; -import org.springframework.data.jpa.datatables.mapping.DataTablesOutput; - -public interface ObjectService { - - List getBatchObjectsForDeletion(Integer limit); - - DataTablesOutput getAllObjectsForDeletion(DataTablesInput input); - - long countAllObjectsScanned(); - - long countAllObjectsForDeletion(); - - void deleteList(List objectList); - - void deleteObjectByPath(String path); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/OvhService.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/OvhService.java deleted file mode 100644 index 3d4f1d55b..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/OvhService.java +++ /dev/null @@ -1,19 +0,0 @@ -package fr.dossierfacile.garbagecollector.service.interfaces; - -import java.util.List; -import org.openstack4j.api.storage.ObjectStorageObjectService; -import org.openstack4j.model.storage.object.SwiftObject; - -public interface OvhService { - void delete(String name); - - void delete(List name); - - SwiftObject get(String name); - - ObjectStorageObjectService getObjectStorage(); - - void renameFile(String oldName, String newName); - - boolean hasConnection(); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/TenantWarningService.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/TenantWarningService.java deleted file mode 100644 index c4a557842..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/interfaces/TenantWarningService.java +++ /dev/null @@ -1,12 +0,0 @@ -package fr.dossierfacile.garbagecollector.service.interfaces; - -import fr.dossierfacile.common.entity.Tenant; - -import java.time.LocalDateTime; -import java.util.List; - -public interface TenantWarningService { - void handleTenantWarning(Tenant t, int warnings); - - void deleteOldArchivedWarning(long tenantId); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/MarkerTransactionsImpl.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/MarkerTransactionsImpl.java deleted file mode 100644 index 1f5583b7f..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/MarkerTransactionsImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package fr.dossierfacile.garbagecollector.transactions; - -import fr.dossierfacile.garbagecollector.model.marker.Marker; -import fr.dossierfacile.garbagecollector.repo.marker.MarkerRepository; -import fr.dossierfacile.garbagecollector.transactions.interfaces.MarkerTransactions; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class MarkerTransactionsImpl implements MarkerTransactions { - private final MarkerRepository markerRepository; - - @Override - @Transactional - public void saveMarkerIfNotYetSaved(String name) { - if (markerRepository.findByPath(name) == null) { - Marker marker = new Marker(); - marker.setPath(name); - markerRepository.saveAndFlush(marker); - } - } - - @Override - @Transactional - public void deleteAllMarkers() { - markerRepository.deleteAll(); - } - - @Override - @Transactional - public void deleteMarker(Marker marker) { - markerRepository.delete(marker); - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/ObjectTransactionsImpl.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/ObjectTransactionsImpl.java deleted file mode 100644 index 036703ec1..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/ObjectTransactionsImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package fr.dossierfacile.garbagecollector.transactions; - -import fr.dossierfacile.garbagecollector.model.object.Object; -import fr.dossierfacile.garbagecollector.repo.file.FileRepository; -import fr.dossierfacile.garbagecollector.repo.object.ObjectRepository; -import fr.dossierfacile.garbagecollector.transactions.interfaces.ObjectTransactions; - -import java.util.List; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import static fr.dossierfacile.garbagecollector.service.MarkerServiceImpl.MARKER_FOR_DELETION; - -@Service -@Slf4j -@RequiredArgsConstructor -public class ObjectTransactionsImpl implements ObjectTransactions { - private final ObjectRepository objectRepository; - private final FileRepository fileRepository; - - @Override - @Transactional - public void saveObject(String nameFile) { - Object object = new Object(); - // If the [File] doesn't exist in the [Database] then it will be marked with [true] to delete - object.setToDelete(nameFile.startsWith(MARKER_FOR_DELETION)); - object.setPath(nameFile); - objectRepository.save(object); - } - - @Override - @Transactional - public void deleteAllObjects() { - objectRepository.deleteAll(); - } - - @Override - @Transactional - public void deleteListObjects(List objectList) { - objectRepository.deleteAll(objectList); - } - - @Override - @Transactional - public void deleteObjectsMayorThan(String path) { - objectRepository.deleteObjectsMayorThan(path); - } -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/interfaces/MarkerTransactions.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/interfaces/MarkerTransactions.java deleted file mode 100644 index 55f2d9492..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/interfaces/MarkerTransactions.java +++ /dev/null @@ -1,9 +0,0 @@ -package fr.dossierfacile.garbagecollector.transactions.interfaces; - -import fr.dossierfacile.garbagecollector.model.marker.Marker; - -public interface MarkerTransactions { - void saveMarkerIfNotYetSaved(String name); - void deleteAllMarkers(); - void deleteMarker(Marker marker); -} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/interfaces/ObjectTransactions.java b/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/interfaces/ObjectTransactions.java deleted file mode 100644 index 22d359fa0..000000000 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/transactions/interfaces/ObjectTransactions.java +++ /dev/null @@ -1,11 +0,0 @@ -package fr.dossierfacile.garbagecollector.transactions.interfaces; - -import fr.dossierfacile.garbagecollector.model.object.Object; -import java.util.List; - -public interface ObjectTransactions { - void saveObject(String nameFile); - void deleteAllObjects(); - void deleteListObjects(List objectList); - void deleteObjectsMayorThan(String path); -} diff --git a/dossierfacile-garbage-collector/src/main/resources/db/changelog/databaseCollectorChangeLog.xml b/dossierfacile-garbage-collector/src/main/resources/db/changelog/databaseCollectorChangeLog.xml deleted file mode 100644 index 85937186d..000000000 --- a/dossierfacile-garbage-collector/src/main/resources/db/changelog/databaseCollectorChangeLog.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/dossierfacile-garbage-collector/src/main/resources/db/migration/202203031400-init-database.xml b/dossierfacile-garbage-collector/src/main/resources/db/migration/202203031400-init-database.xml deleted file mode 100644 index caccedfba..000000000 --- a/dossierfacile-garbage-collector/src/main/resources/db/migration/202203031400-init-database.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - -- public.object - - -- Drop table - - -- DROP TABLE public.object; - - CREATE TABLE public.object - ( - id bigserial NOT NULL, - path text NULL, - to_delete bool NULL DEFAULT false, - CONSTRAINT path_pkey PRIMARY KEY (id) - ); - - -- public.maker - - -- Drop table - - -- DROP TABLE public.marker; - - CREATE TABLE public.marker - ( - id bigserial NOT NULL, - path text NULL, - CONSTRAINT path2_pkey PRIMARY KEY (id) - ); - - - diff --git a/dossierfacile-garbage-collector/src/main/resources/static/css/Layout.css b/dossierfacile-garbage-collector/src/main/resources/static/css/Layout.css deleted file mode 100644 index 6892c9e76..000000000 --- a/dossierfacile-garbage-collector/src/main/resources/static/css/Layout.css +++ /dev/null @@ -1,1134 +0,0 @@ -@font-face { - font-family: "REFSAN"; - src: url("../fonts/REFSAN.TTF") format("truetype"); -} - -@font-face { - font-family: "Avenir Book"; - src: url("../fonts/Avenir-Book.ttf") format("truetype"); -} - -* { - line-height: 1; -} - -p { - line-height: 1.5; -} - -body { - padding: 0; - margin: 0; - height: 100%; - width: 100%; - background-color: #f8f8f8; - font-family: "REFSAN"; - font-size: 16px; - color: #333333; -} - -body table { - color: #333333; -} - -.btn { - border-radius: 50px; - padding: 10px 50px 12px; - font-size: 24px; - line-height: 1; -} - -@media (max-width: 700px) { - .btn-responsive { - font-size: 18px !important; - max-width: 90%; - white-space: pre-wrap; - /* css-3 */ - white-space: -moz-pre-wrap; - /* Mozilla, since 1999 */ - white-space: pre-wrap; - /* Opera 4-6 */ - white-space: -o-pre-wrap; - /* Opera 7 */ - word-wrap: break-word; - /* Internet Explorer 5.5+ */ - } -} - -@media (max-width: 700px) { - .btn-responsive a.btn-responsive { - padding: -50px; - text-align: center; - line-height: 1; - } -} - -.btn-primary { - background-color: #003189; - color: #f5f5fe !important; -} - -.btn-primary * { - color: #f5f5fe !important; -} - -.btn-default { - background-color: unset; - color: #003189 !important; - border-color: #003189; - opacity: 0.8; -} - -.btn-primary:focus, -.btn-primary:hover, -.btn-primary:active, -.btn-default:focus, -.btn-default:hover, -.btn-default:active { - background-color: #002059 !important; - border-color: transparent !important; - color: #f8f8f8 !important; - opacity: 1; - -webkit-transition: background-color 0.2s linear; - transition: background-color 0.2s linear; -} - -.btn-primary:focus *, -.btn-primary:hover *, -.btn-primary:active *, -.btn-default:focus *, -.btn-default:hover *, -.btn-default:active * { - color: #f8f8f8 !important; -} - - -.text-primary { - color: #003189; -} - -.text-primary1 { - opacity: 0.8; -} - -.text-alter { - color: #e9ebf1; -} - -.title { - font-size: 26px; -} - - -.little-title { - font-size: 24px; -} - -.subtitle { - font-size: 20px; -} - -.subtitle1 { - font-size: 18px; -} - -.bg-white { - background-color: white; -} - -.icon svg, .icon img { - width: 100px; - height: 100px; - line-height: 1; -} - -.space-separator { - padding: 8px 0; -} - -.space-separator-top { - padding-top: 15px; -} - -.space-separator-bottom { - padding-bottom: 15px; -} - -.medium-space-separator { - padding: 30px 0; -} - -.medium-space-separator-top { - padding-top: 30px; -} - -.big-space-separator { - padding-top: 60px; - padding-bottom: 60px; -} - -.big-space-separator-bottom { - padding-bottom: 60px; -} - - -.logo { - width: 300px; -} - -.line-separator { - width: 50%; - margin: 50px 25%; - border-top: 1px solid #b6caee; -} - -p { - line-height: 1.5; -} - -a { - color: #333333; -} - -a:hover { - color: #003189; - border-color: transparent; -} - -.padding { - padding: 15px; -} - -.padding-left-15px { - padding-left: 15px !important; -} - -.padding-right { - padding-right: 15px; -} - -.margin { - margin: 15px; -} - -.margin-left { - margin-left: 15px; -} - -.margin-right { - margin-right: 15px; -} - -.margin-top { - margin-top: 15px; -} - -.margin-bottom { - margin-bottom: 15px; -} - -.medium-margin { - margin: 30px; -} - -.medium-margin-left { - margin-left: 30px; -} - -.medium-margin-right { - margin-right: 30px; -} - -.medium-margin-top { - margin-top: 30px; -} - -.medium-margin-bottom { - margin-bottom: 30px; -} - -.no-margin, .no-spaces { - margin: 0; -} - -.no-padding, .no-spaces { - padding: 0; -} - -.line { - border-top: 1px solid #9c8d7a; -} - -.form-control-formatted { - line-height: 1; - color: #003189; -} - -.form-control-formatted:focus, .form-control-formatted.active { - -webkit-box-shadow: none; - box-shadow: none; -} - -textarea { - line-height: 1.5; -} - -input, select.rounded-select { - border: 1px solid #003189 !important; - padding-left: 20px !important; - padding-right: 20px; -} - -input.form-control { - height: 40px; -} - - -.form-control-untouched { - border-color: #b6caee !important; - -webkit-box-shadow: none; - box-shadow: none; -} - -.form-control-untouched::-webkit-input-placeholder, .form-control-untouched:-moz-placeholder, .form-control-untouched::-moz-placeholder, .form-control-untouched:-ms-input-placeholder { - color: #b6caee; -} - -label { - color: #003189; - opacity: 0.8; -} - -.formatted-label { - padding-left: 20px; -} - -.input-icon { - position: relative; -} - -.input-icon input { - padding-left: 20px; - padding-right: 30px; - height: 40px; -} - -.input-icon img, .input-icon .img { - position: absolute; - top: 6px; - right: 6px; - width: 28px; - height: 28px; - background-color: #003189; - border-radius: 50%; - padding: 9px; - cursor: pointer; - display: inline-block; -} - -.input-icon.formatted-icon-input { - display: inline-block; -} - -.input-icon.formatted-icon-input input::-webkit-input-placeholder, .input-icon.formatted-icon-input input:-moz-placeholder, .input-icon.formatted-icon-input input::-moz-placeholder, .input-icon.formatted-icon-input input:-ms-input-placeholder { - color: #003189; -} - -.input-icon.info-icon img, .input-icon.info-icon .img { - border: 1px solid #1267fb; - color: #1267fb; - background-color: transparent; -} - -.input-icon .img span { - position: relative; - bottom: 3.5px; -} - -.border { - border-width: 1px; - border-style: solid; -} - -.border-primary { - border-color: #b6caee; -} - -.border-bottom { - border-bottom-width: 1px; - border-bottom-style: solid; -} - -.modal { - padding: 10px; -} - -.invalid { - border-color: #fe0000 !important; -} - -.wide { - width: 100%; - background: red; -} - -.tooltip { - font-family: "REFSAN", sans-serif; - font-size: 14px; -} - -.tooltip.left .tooltip-arrow { - border-left-color: #04274a; -} - -.tooltip.bottom .tooltip-arrow { - border-bottom-color: #04274a; -} - -.tooltip-inner { - min-width: 200px; - color: #e9ebf1; - background-color: #04274a; - line-height: 1.5; - padding: 5px; - text-align: center; -} - -.tooltip-inner::first-letter { - text-transform: capitalize; -} - -input::-webkit-outer-spin-button, -input::-webkit-inner-spin-button { - /* display: none; <- Crashes Chrome on hover */ - -webkit-appearance: none; - margin: 0; /* <-- Apparently some margin are still there even though it's hidden */ -} - -#chat-page { - position: relative; - height: 100%; -} - -.chat-page-user { - width: 75%; -} - -.chat-container { - margin-left: auto; - margin-right: auto; - background-color: #fff; - box-shadow: 0 1px 11px rgba(0, 0, 0, 0.27); - margin-top: 30px; - position: relative; -} - -#chat-page ul { - list-style-type: none; - background-color: #FFF; - margin: 0; - overflow: auto; - overflow-y: scroll; - padding: 0 20px 0px 20px; - height: calc(100vh - 220px); -} - -#chat-page #messageForm { - padding: 20px; -} - -#chat-page ul li { - line-height: 1.5rem; - padding: 10px 20px; - margin: 0; - border-bottom: 1px solid #f4f4f4; -} - -#chat-page ul li p { - margin: 0; -} - -#chat-page .event-message { - width: 100%; - text-align: center; - clear: both; -} - -#chat-page .event-message p { - color: #777; - font-size: 14px; - word-wrap: break-word; -} - -#chat-page .chat-message { - /*padding-left: 68px;*/ - position: relative; -} - -#chat-page .chat-message i { - /*position: absolute;*/ - width: 42px; - height: 42px; - overflow: hidden; - left: 10px; - display: inline-block; - vertical-align: middle; - font-size: 18px; - line-height: 42px; - color: #fff; - text-align: center; - border-radius: 50%; - font-style: normal; - text-transform: uppercase; -} - -#chat-page .chat-message span { - color: #333; - font-weight: 600; -} - -#chat-page .chat-message p { - color: #43464b; -} - -#messageForm .input-group input { - float: left; - width: calc(100% - 85px); -} - -#messageForm .input-group button { - float: left; - width: 80px; - height: 38px; - margin-left: 5px; -} - -@media screen and (max-width: 730px) { - - .chat-container { - margin-left: 10px; - margin-right: 10px; - margin-top: 10px; - } -} - -@media screen and (max-width: 480px) { - .chat-container { - height: calc(100% - 30px); - overflow: auto; - max-height: 600px; - - } - - #chat-page ul { - height: calc(100% - 120px); - } - - #messageForm .input-group button { - width: 65px; - } - - #messageForm .input-group input { - width: calc(100% - 70px); - } - -} - -.customMessage { - height: auto !important; - overflow-y: hidden !important; -} - -.message-you { - width: 100%; - display: flex; -} - -.message { - width: 100%; - display: flex; -} - -.container-message-you { - width: 100%; - margin-left: 2rem; - text-align: left; - font-size: 12px; -} - -.container-message { - width: 100%; - margin-left: 2rem; - text-align: left; - font-size: 12px; -} - -.title-header-you { - - padding-left: revert; -} - -.date-you { - text-align: right; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-style: normal; - color: #062218; -} -.date-you-two { - text-align: right; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-style: normal; - color: #062218; - -} - -.title-header { - margin-bottom: 20px; - padding-left: revert; -} - -.letter-bo{ - font-family: 'Segoe UI', sans-serif; - color: #000000; -} - -.content-you { - -} - -.message-admin { - background-color: #fffefe !important; -} - -.message-admin ul { - background-color: #f8f8f8 !important; -} - -textarea { - resize: vertical; -} - -.container-message p { - white-space: pre-wrap; -} - -.container-message-you p { - white-space: pre-wrap; -} - -.horizontal { - flex-direction: row; -} - -.align-items-center { - align-items: center; -} - -.display-flex { - display: flex !important; -} - -.label-check { - background-color: #ffc81c; -!important; - color: black !important; -} - -.padding-right-0px { - padding-right: 0px !important; -} - -.padding-top-10px { - padding-top: 10px !important; -} - -.custom-badge-dange-bo { - background-color: red !important; - color: white !important; -} -form-search{} -@import url(https://fonts.googleapis.com/css?family=Open+Sans); -.search { - display: flex; - background: #f2f2f2; - font-family: 'Open Sans', sans-serif; - margin-left: 350px; -} - -.searchTerm { - width: auto; - border: 3px solid #111c1d; - border-right: none; - padding: 3px; - border-radius: 5px 0 0 5px; - outline: none; - color: #9DBFAF; -} - -.searchTerm:focus{ - color: #0d1213; -} - -.searchButton { - width: 40px; - height: 36px; - border: 1px solid #00B4CC; - background: #00B4CC; - text-align: center; - color: #fff; - border-radius: 0 5px 5px 0; - cursor: pointer; - font-size: 20px; -} - -/*Resize the wrap to see the search bar change!*/ -.wrap{ - float: right; -} - -.btn-right-pull{ - margin-right: 5px; -} -.text-area-bo{ - border-image: none; - border-radius: 6px 6px 6px 6px; - border-style: none none solid none; - border-width: medium 1px 1px medium; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12) inset; - color: #555555; - font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; - font-size: 1em; - line-height: 1.4em; - padding: 5px 8px; - transition: background-color 0.2s ease 0s; - background: none repeat scroll 0 0 rgba(0, 0, 0, 0.07); -} - -.btn-regenerate-pdf { - color: black; - font-size: smaller; - font-weight: normal; - margin-left: 2%; - margin-top: 7px; -} -#tabs .nav-tabs > li.active > a { - background: lightgray; -} - -@media (max-width: 991px) { - - .footer_logo { - display: none; - } - - .footer_content { - text-align: center; - font-size: 14px; - } -} - -.fixed-header { - position: fixed; - left: 0; - right: 0; - top: 0; - height: 36px; - z-index: 500; -} - -.fixed-header-link-container { - position: absolute; - right: 0; -} - -.fixed-header-link-container form { - display: inline; -} - -.fixed-header-link { - text-decoration: none; - padding: 10px; -} - -.fixed-header-link:hover { - text-decoration: none; -} - -.profile:hover { - color: #003988; - order-color: transparent; -} - -.profile { - color: #003988; - display: inline-block; -} - -.logout { - background: none !important; - color: #D03433; - border: none; - padding: 0 !important; - font: inherit; - /*border is optional*/ - /*border-bottom:1px solid #444;*/ - display: inline-block; - cursor: pointer; -} - -.footer_content { - text-align: center; - margin-bottom: 20px; -} - -.footer_logo { - margin-bottom: 20px; -} - -.bold { - font-weight: bold; -} - -.logo { - float: left; -} - -.link-file { - background-color: #eee; - opacity: 1; - border-radius: 50px !important; - display: block; - width: 100%; - height: 40px; - padding: 9px 12px; - font-size: 14px; - line-height: 1.42857143; - color: #555; - border: 1px solid #ccc; -} - -.link-file:hover { - text-decoration: none; - border-color: #003189; - color: #003189; -} - -.link-file:focus { - text-decoration: none !important; - color: #003189; -} - -.icono-edit-file { - margin-left: -2px; -} - -.nounderline { - text-decoration: none !important; -} - -.top-buffer { - margin-top: 20px; -} - - - -.bo-btn { - border-radius: 50px; - padding: 6px 12px !important; - font-size: 14px !important; - line-height: 1; -} - -@media screen and ( max-width: 991px ) { - .bo-btn.btn-responsive { - white-space: pre-line; - } -} - -#formLocataire { - display: none; -} - -.logo2 { - margin-left: 20px; - height: 43px !important; - width: 43px !important; -} - -.logo2footer { - height: 60px !important; - /*width: 43px !important;*/ -} - -.btn-alt { - background-color: #e9ebf1; - color: #003189 !important; - font-size: 20px; -} - -.btn-alt:hover { - color: #e9ebf1 !important; -} - -@media screen and ( max-width: 991px ) { - .bo-btn.btn-responsive { - white-space: pre-line; - } - - .table-responsive .table th.big-col, - .table-responsive .table td.big-col { - display: none; - } - - .table-responsive .table th.centered, - .table-responsive .table td.centered { - text-align: center; - } - -} - - -@media screen and ( max-width: 600px ) { - .table-responsive .table th.medium-col, - .table-responsive .table td.medium-col { - display: none; - } -} - -.nav-tabs li a.properties-list { - cursor: pointer; -} - -.nav-tabs > li > a, -.nav-tabs > li > a:hover, -.nav-tabs > li > a:focus { - background-color: lightgray; -} - -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - background-color: rgb(212, 227, 252); - cursor: pointer; -} - - -@media screen and ( max-width: 700px ) { - #messageArea > .chat-message > .message > .avatar, - #messageArea > .chat-message > .message-you > .avatar { - display: none; - } - - #messageArea > .chat-message > .message > .container-message > .title-header, - #messageArea > .chat-message > .message-you > .container-message-you > .title-header-you { - display: block; - margin-bottom: 0px; - text-align: left; - } - - #messageArea > .chat-message > .message-you > .container-message-you > .title-header-you, - #messageArea > .chat-message > .message-you > .container-message-you > .content-you { - display: block; - float: left; - clear: both; - padding-right: 10%; - text-align: justify; - } - - #messageArea > .chat-message > .message > .container-message > .title-header, - #messageArea > .chat-message > .message > .container-message > .content > p { - display: block; - float: right; - clear: both; - padding-left: 10%; - text-align: justify; - } - - #messageArea > .chat-message > .message > .container-message > div:nth-child( 2 ), - #messageArea > .chat-message > .message-you > .container-message-you > .date-you { - display: none; - } - - .container.big-space-separator { - padding-top: 4px; - padding-bottom: 4px; - } - - .medium-margin-bottom { - padding: 5px; - margin: 0px; - } - - .hide-on-small-screen { - display: none; - } - - .hide-on-large-screen { - display: block; - } - - #modify-documents.collapse { - display: none; - } - - #modify-documents.collapse.in { - display: block; - } -} - - -#chat-page > .chat-container { - min-height: 100px; -} - -#chat-page > .chat-container > .row { - margin-left: 0px; - margin-right: 0px; -} - -#chat-page > .chat-container > .row > #messageForm { - margin: 20px; - padding: 0px; -} - -table > tbody > tr > td.statistics-pct { - background-image: linear-gradient(to right, var(--data-color), var(--data-color) var(--data-pct)%, transparent var(--data-pct)%, transparent); - background-repeat: no-repeat; - vertical-align: middle; -} - -.property-deleted { - text-decoration: line-through; -} - -span.ocr-result { - white-space: pre-line; - max-width: 60em; - display: inline-block; - max-height: 20em; - overflow: auto; -} - - - * {box-sizing: border-box;} - - -.topnav { - overflow: hidden; -} - -.topnav a { - float: left; - display: block; - color: black; - text-align: center; - padding: 14px 16px; - text-decoration: none; - font-size: 17px; -} - -.topnav a:hover { - background-color: #ddd; - color: black; -} - -.topnav a.active { - background-color: #2196F3; - color: white; -} - -.topnav .search-container { - float: right; -} - -.topnav input[type=text] { - padding: 6px; - margin-top: 8px; - font-size: 17px; - border: none; -} - -.topnav .search-container button { - float: right; - padding: 6px 10px; - margin-top: 8px; - margin-right: 16px; - background: #ddd; - font-size: 17px; - border: none; - cursor: pointer; -} - -.topnav .search-container button:hover { - background: #ccc; -} - -@media screen and (max-width: 600px) { - .topnav .search-container { - float: none; - } - .topnav a, .topnav input[type=text], .topnav .search-container button { - float: none; - display: block; - text-align: left; - width: 100%; - margin: 0; - padding: 14px; - } - .topnav input[type=text] { - border: 1px solid #ccc; - } -} -.styled-table { - border-collapse: collapse; - margin: 25px 0; - font-size: 0.9em; - font-family: sans-serif; - min-width: 400px; - box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); -} -.styled-table thead tr { - background-color: #009879; - color: #ffffff; - text-align: left; -} -.styled-table th, -.styled-table td { - padding: 12px 15px; -} -.styled-table tbody tr { - border-bottom: 1px solid #dddddd; -} - -.styled-table tbody tr:nth-of-type(even) { - background-color: #f3f3f3; -} - -.styled-table tbody tr:last-of-type { - border-bottom: 2px solid #003189; -} -.styled-table tbody tr.active-row { - font-weight: bold; -} -.pagination>li { - display: inline; -} -.pagination>li>a, .pagination>li>span { - position: relative; - float: left; - padding: 6px 12px; - margin-left: -1px; - line-height: 1.42857143; - color: #337ab7; - text-decoration: none; - background-color: #fff; - border: 1px solid #ddd; -} -.pagination li:hover{ - cursor: pointer; -} - -table#table_objects tr:hover { - background-color: gainsboro; -} - diff --git a/dossierfacile-garbage-collector/src/main/resources/static/js/jquery.spring-friendly.js b/dossierfacile-garbage-collector/src/main/resources/static/js/jquery.spring-friendly.js deleted file mode 100644 index c786bddd8..000000000 --- a/dossierfacile-garbage-collector/src/main/resources/static/js/jquery.spring-friendly.js +++ /dev/null @@ -1,73 +0,0 @@ -// From https://github.com/jquery/jquery/blob/master/src/serialize.js -// Overrides data serialization to allow Spring MVC to correctly map input parameters : column[0][data] now becomes column[0].data -(function($) { - var r20 = /%20/g, rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; - - function customBuildParams(prefix, obj, traditional, add) { - var name; - - if (jQuery.isArray(obj)) { - // Serialize array item. - jQuery.each(obj, function(i, v) { - if (traditional || rbracket.test(prefix)) { - // Treat each array item as a scalar. - add(prefix, v); - - } else { - // Item is non-scalar (array or object), encode its numeric - // index. - customBuildParams(prefix + "[" - + (typeof v === "object" ? i : "") + "]", v, - traditional, add); - } - }); - - } else if (!traditional && jQuery.type(obj) === "object") { - // Serialize object item. - for (name in obj) { - // This is where the magic happens - customBuildParams(prefix + "." + name, obj[name], traditional, - add); - } - - } else { - // Serialize scalar item. - add(prefix, obj); - } - } - - $.param = function(a, traditional) { - var prefix, s = [], add = function(key, value) { - // If value is a function, invoke it and return its value - value = jQuery.isFunction(value) ? value() : (value == null ? "" - : value); - s[s.length] = encodeURIComponent(key) + "=" - + encodeURIComponent(value); - }; - - // Set traditional to true for jQuery <= 1.3.2 behavior. - if (traditional === undefined) { - traditional = jQuery.ajaxSettings - && jQuery.ajaxSettings.traditional; - } - - // If an array was passed in, assume that it is an array of form - // elements. - if (jQuery.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) { - // Serialize the form elements - jQuery.each(a, function() { - add(this.name, this.value); - }); - - } else { - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for (prefix in a) { - customBuildParams(prefix, a[prefix], traditional, add); - } - } - - // Return the resulting serialization - return s.join("&").replace(r20, "+"); - }; -})(jQuery); \ No newline at end of file diff --git a/dossierfacile-garbage-collector/src/main/resources/templates/index.html b/dossierfacile-garbage-collector/src/main/resources/templates/index.html deleted file mode 100644 index acb422c5b..000000000 --- a/dossierfacile-garbage-collector/src/main/resources/templates/index.html +++ /dev/null @@ -1,225 +0,0 @@ - - - - DossierFacile - - - - - - - - - - -
- Object Checker -
-
- -
-
-
- -
- -
-
-
- - - - - -
-
-
- - -
-
-
- - - - - - - - - -
IdPath
-
-
-
- - - - - - - - - - diff --git a/dossierfacile-garbage-collector/src/main/resources/templates/login.html b/dossierfacile-garbage-collector/src/main/resources/templates/login.html deleted file mode 100644 index 1e57b01a3..000000000 --- a/dossierfacile-garbage-collector/src/main/resources/templates/login.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - Spring Security Example - - - - - - - - - - - - - \ No newline at end of file diff --git a/dossierfacile-garbage-collector/src/test/java/fr/dossierfacile/garbagecollector/CheckerApplicationTests.java b/dossierfacile-garbage-collector/src/test/java/fr/dossierfacile/garbagecollector/CheckerApplicationTests.java deleted file mode 100644 index 397e66c3b..000000000 --- a/dossierfacile-garbage-collector/src/test/java/fr/dossierfacile/garbagecollector/CheckerApplicationTests.java +++ /dev/null @@ -1,15 +0,0 @@ -package fr.dossierfacile.garbagecollector; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@Disabled -@SpringBootTest -class CheckerApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/dossierfacile-garbage-collector/.gitignore b/dossierfacile-task-scheduler/.gitignore similarity index 92% rename from dossierfacile-garbage-collector/.gitignore rename to dossierfacile-task-scheduler/.gitignore index 7bc4bf79e..549e00a2a 100644 --- a/dossierfacile-garbage-collector/.gitignore +++ b/dossierfacile-task-scheduler/.gitignore @@ -1,33 +1,33 @@ -HELP.md -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/**/target/ -!**/src/test/**/target/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ - -### VS Code ### -.vscode/ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/dossierfacile-garbage-collector/Dockerfile b/dossierfacile-task-scheduler/Dockerfile similarity index 85% rename from dossierfacile-garbage-collector/Dockerfile rename to dossierfacile-task-scheduler/Dockerfile index 550c8eee1..69ab75d50 100644 --- a/dossierfacile-garbage-collector/Dockerfile +++ b/dossierfacile-task-scheduler/Dockerfile @@ -1,6 +1,6 @@ -FROM amazoncorretto:20 -ENV TZ=Europe/Paris -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -ADD target/checker-0.0.1-SNAPSHOT.jar checker-0.0.1-SNAPSHOT.jar -ENTRYPOINT ["java","-jar","-Dlog4j2.formatMsgNoLookups=true","/dossierfacile-garbage-collector.jar"] -EXPOSE 8084 +FROM amazoncorretto:20 +ENV TZ=Europe/Paris +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +ADD target/checker-0.0.1-SNAPSHOT.jar checker-0.0.1-SNAPSHOT.jar +ENTRYPOINT ["java","-jar","-Dlog4j2.formatMsgNoLookups=true","/dossierfacile-task-scheduler.jar"] +EXPOSE 8084 diff --git a/dossierfacile-garbage-collector/lombok.config b/dossierfacile-task-scheduler/lombok.config similarity index 100% rename from dossierfacile-garbage-collector/lombok.config rename to dossierfacile-task-scheduler/lombok.config diff --git a/dossierfacile-garbage-collector/mvnw b/dossierfacile-task-scheduler/mvnw similarity index 97% rename from dossierfacile-garbage-collector/mvnw rename to dossierfacile-task-scheduler/mvnw index 4c1c42714..a16b5431b 100644 --- a/dossierfacile-garbage-collector/mvnw +++ b/dossierfacile-task-scheduler/mvnw @@ -1,310 +1,310 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# https://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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# https://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/dossierfacile-garbage-collector/pom.xml b/dossierfacile-task-scheduler/pom.xml similarity index 61% rename from dossierfacile-garbage-collector/pom.xml rename to dossierfacile-task-scheduler/pom.xml index 4fadb8070..141084021 100644 --- a/dossierfacile-garbage-collector/pom.xml +++ b/dossierfacile-task-scheduler/pom.xml @@ -8,26 +8,22 @@ 2.7.14 + fr.gouv - dossierfacile-garbage-collector + dossierfacile-task-scheduler 0.0.1-SNAPSHOT - dossierfacile-garbage-collector - Object Checker project for Spring Boot ${packaging.type} + 19 1.18.30 - 0.0.1-SNAPSHOT + fr.dossierfacile dossierfacile-common-library - ${dossierfacile.common.version} - - - org.springframework.boot - spring-boot-starter-thymeleaf + 0.0.1-SNAPSHOT org.springframework.boot @@ -42,12 +38,6 @@ org.springframework.boot spring-boot-starter-data-jpa - - org.springframework.boot - spring-boot-devtools - runtime - true - org.postgresql postgresql @@ -64,44 +54,6 @@ commons-lang3 3.11 - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-annotations - - - javax.validation - validation-api - 2.0.1.Final - compile - - - com.vladmihalcea - hibernate-types-52 - 2.21.1 - - - org.springframework.boot - spring-boot-starter-security - - - org.liquibase - liquibase-core - 4.8.0 - compile - - - com.github.darrachequesne - spring-data-jpa-datatables - 5.1.0 - com.sendinblue @@ -149,33 +101,13 @@ - - - - com.fasterxml.jackson - jackson-bom - 2.13.4.20221013 - import - pom - - - - - dossierfacile-garbage-collector + dossierfacile-task-scheduler org.springframework.boot spring-boot-maven-plugin - - org.liquibase - liquibase-maven-plugin - 4.1.1 - - src/main/resources/liquibase.properties - - diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/LoggingContext.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/LoggingContext.java similarity index 51% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/LoggingContext.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/LoggingContext.java index cbd7fbf9b..542fce83a 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/LoggingContext.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/LoggingContext.java @@ -1,6 +1,7 @@ -package fr.dossierfacile.garbagecollector; +package fr.dossierfacile.scheduler; import fr.dossierfacile.common.entity.StorageFile; +import fr.dossierfacile.scheduler.tasks.TaskName; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; @@ -8,6 +9,17 @@ public class LoggingContext { private static final String STORAGE_FILE = "storage_file_id"; + private static final String TASK_NAME = "task"; + + public static void startTask(TaskName taskName) { + MDC.put(TASK_NAME, taskName.name()); + log.info("Starting scheduled task"); + } + + public static void endTask() { + log.info("Finished scheduled task"); + MDC.clear(); + } public static void setStorageFile(StorageFile file) { if (file.getId() != null) { @@ -16,6 +28,7 @@ public static void setStorageFile(StorageFile file) { } public static void clear() { + MDC.remove(TASK_NAME); MDC.remove(STORAGE_FILE); } diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/CheckerApplication.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/TaskSchedulerApplication.java similarity index 75% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/CheckerApplication.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/TaskSchedulerApplication.java index 2e99be87f..904878163 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/CheckerApplication.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/TaskSchedulerApplication.java @@ -1,11 +1,11 @@ -package fr.dossierfacile.garbagecollector; +package fr.dossierfacile.scheduler; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -14,11 +14,12 @@ @EntityScan(basePackages = "fr.dossierfacile") @EnableAsync @EnableScheduling -@ComponentScan(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class, basePackages = "fr.dossierfacile") -public class CheckerApplication { +@EnableJpaRepositories(basePackages = "fr.dossierfacile") +@ComponentScan(basePackages = "fr.dossierfacile") +public class TaskSchedulerApplication { public static void main(String[] args) { - SpringApplication.run(CheckerApplication.class, args); + SpringApplication.run(TaskSchedulerApplication.class, args); } @Bean diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/GarbageCollectionConfiguration.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/GarbageCollectionConfiguration.java similarity index 79% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/GarbageCollectionConfiguration.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/GarbageCollectionConfiguration.java index 2c8c311f2..1509e2b82 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/GarbageCollectionConfiguration.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/GarbageCollectionConfiguration.java @@ -1,9 +1,9 @@ -package fr.dossierfacile.garbagecollector.configuration; +package fr.dossierfacile.scheduler.configuration; import fr.dossierfacile.common.repository.StorageFileRepository; import fr.dossierfacile.common.service.interfaces.FileStorageProviderService; -import fr.dossierfacile.garbagecollector.repo.garbagecollection.GarbageCollectionDetailsRepository; -import fr.dossierfacile.garbagecollector.service.ScheduledGarbageCollectionService; +import fr.dossierfacile.scheduler.tasks.garbagecollection.GarbageCollectionDetailsRepository; +import fr.dossierfacile.scheduler.tasks.garbagecollection.GarbageCollectionTask; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -21,7 +21,7 @@ public class GarbageCollectionConfiguration { name = "garbage-collection.enabled", havingValue = "true" ) - ScheduledGarbageCollectionService scheduledGarbageCollectionService( + GarbageCollectionTask garbageCollectionTask( GarbageCollectionDetailsRepository garbageCollectionDetailsRepository, StorageFileRepository storageFileRepository, List fileStorageProviderServices, @@ -29,7 +29,7 @@ ScheduledGarbageCollectionService scheduledGarbageCollectionService( ) { var storageProviderServicesMap = fileStorageProviderServices.stream() .collect(Collectors.toMap(FileStorageProviderService::getProvider, Function.identity())); - return new ScheduledGarbageCollectionService( + return new GarbageCollectionTask( garbageCollectionDetailsRepository, storageFileRepository, storageProviderServicesMap, diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/GeneralConfiguration.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/GeneralConfiguration.java similarity index 84% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/GeneralConfiguration.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/GeneralConfiguration.java index c2749d061..e9ee7fe10 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/GeneralConfiguration.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/GeneralConfiguration.java @@ -1,4 +1,4 @@ -package fr.dossierfacile.garbagecollector.configuration; +package fr.dossierfacile.scheduler.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/KeycloakConfig.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/KeycloakConfig.java similarity index 95% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/KeycloakConfig.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/KeycloakConfig.java index b0b92e9c1..27a25c330 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/KeycloakConfig.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/KeycloakConfig.java @@ -1,4 +1,4 @@ -package fr.dossierfacile.garbagecollector.configuration; +package fr.dossierfacile.scheduler.configuration; import org.keycloak.OAuth2Constants; import org.keycloak.admin.client.KeycloakBuilder; diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/MailConfiguration.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/MailConfiguration.java similarity index 92% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/MailConfiguration.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/MailConfiguration.java index 6fa8b2815..6a91ea63c 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/configuration/MailConfiguration.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/configuration/MailConfiguration.java @@ -1,4 +1,4 @@ -package fr.dossierfacile.garbagecollector.configuration; +package fr.dossierfacile.scheduler.configuration; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/TaskName.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/TaskName.java new file mode 100644 index 000000000..b3f25ec16 --- /dev/null +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/TaskName.java @@ -0,0 +1,10 @@ +package fr.dossierfacile.scheduler.tasks; + +public enum TaskName { + + GARBAGE_COLLECTION, + TENANT_WARNINGS, + STORAGE_FILES_BACKUP, + STORAGE_FILES_DELETION + +} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/garbagecollection/GarbageCollectionDetails.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionDetails.java similarity index 90% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/garbagecollection/GarbageCollectionDetails.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionDetails.java index d68416fac..987b1323a 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/garbagecollection/GarbageCollectionDetails.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionDetails.java @@ -1,4 +1,4 @@ -package fr.dossierfacile.garbagecollector.model.garbagecollection; +package fr.dossierfacile.scheduler.tasks.garbagecollection; import fr.dossierfacile.common.entity.ObjectStorageProvider; import lombok.AllArgsConstructor; diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/garbagecollection/GarbageCollectionDetailsRepository.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionDetailsRepository.java similarity index 66% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/garbagecollection/GarbageCollectionDetailsRepository.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionDetailsRepository.java index 31752fc72..d468de915 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/repo/garbagecollection/GarbageCollectionDetailsRepository.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionDetailsRepository.java @@ -1,7 +1,6 @@ -package fr.dossierfacile.garbagecollector.repo.garbagecollection; +package fr.dossierfacile.scheduler.tasks.garbagecollection; import fr.dossierfacile.common.entity.ObjectStorageProvider; -import fr.dossierfacile.garbagecollector.model.garbagecollection.GarbageCollectionDetails; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledGarbageCollectionService.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionTask.java similarity index 91% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledGarbageCollectionService.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionTask.java index 61cddaf9d..d4ed1a446 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledGarbageCollectionService.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/GarbageCollectionTask.java @@ -1,11 +1,9 @@ -package fr.dossierfacile.garbagecollector.service; +package fr.dossierfacile.scheduler.tasks.garbagecollection; import fr.dossierfacile.common.entity.ObjectStorageProvider; import fr.dossierfacile.common.repository.StorageFileRepository; import fr.dossierfacile.common.service.interfaces.FileStorageProviderService; -import fr.dossierfacile.garbagecollector.model.StoredObject; -import fr.dossierfacile.garbagecollector.model.garbagecollection.GarbageCollectionDetails; -import fr.dossierfacile.garbagecollector.repo.garbagecollection.GarbageCollectionDetailsRepository; +import fr.dossierfacile.scheduler.LoggingContext; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; @@ -14,11 +12,12 @@ import java.util.Map; import java.util.Optional; +import static fr.dossierfacile.scheduler.tasks.TaskName.GARBAGE_COLLECTION; import static java.util.concurrent.TimeUnit.SECONDS; @Slf4j @AllArgsConstructor -public class ScheduledGarbageCollectionService { +public class GarbageCollectionTask { private final GarbageCollectionDetailsRepository garbageCollectionDetailsRepository; private final StorageFileRepository storageFileRepository; @@ -28,9 +27,9 @@ public class ScheduledGarbageCollectionService { @Scheduled(fixedDelayString = "${garbage-collection.seconds-between-iterations:60}", timeUnit = SECONDS) void cleanGarbage() { - log.info("Starting garbage collection iteration"); + LoggingContext.startTask(GARBAGE_COLLECTION); storageProviderServices.keySet().forEach(this::cleanGarbageOn); - log.info("Finished garbage collection iteration"); + LoggingContext.endTask(); } private void cleanGarbageOn(ObjectStorageProvider provider) { diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/StoredObject.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/StoredObject.java similarity index 71% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/StoredObject.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/StoredObject.java index 3adbeeafd..6d088ad43 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/model/StoredObject.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/garbagecollection/StoredObject.java @@ -1,4 +1,4 @@ -package fr.dossierfacile.garbagecollector.model; +package fr.dossierfacile.scheduler.tasks.garbagecollection; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/BackupFilesService.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/storagesynchronization/BackupFilesTask.java similarity index 86% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/BackupFilesService.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/storagesynchronization/BackupFilesTask.java index c73e1e408..c8d042352 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/BackupFilesService.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/storagesynchronization/BackupFilesTask.java @@ -1,10 +1,10 @@ -package fr.dossierfacile.garbagecollector.service; +package fr.dossierfacile.scheduler.tasks.storagesynchronization; import fr.dossierfacile.common.entity.ObjectStorageProvider; import fr.dossierfacile.common.entity.StorageFile; import fr.dossierfacile.common.repository.StorageFileRepository; import fr.dossierfacile.common.service.interfaces.FileStorageService; -import fr.dossierfacile.garbagecollector.LoggingContext; +import fr.dossierfacile.scheduler.LoggingContext; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.PageRequest; @@ -15,15 +15,18 @@ import java.io.InputStream; import java.util.List; +import static fr.dossierfacile.scheduler.tasks.TaskName.STORAGE_FILES_BACKUP; + @Slf4j @Service @RequiredArgsConstructor -public class BackupFilesService { +public class BackupFilesTask { private final StorageFileRepository storageFileRepository; private final FileStorageService fileStorageService; @Scheduled(fixedDelayString = "${scheduled.process.storage.backup.delay.ms}") public void scheduleBackupTask() { + LoggingContext.startTask(STORAGE_FILES_BACKUP); Pageable limit = PageRequest.of(0, 100); List storageFiles = storageFileRepository.findAllWithOneProvider(limit); storageFiles.parallelStream().forEach(storageFile -> { @@ -35,6 +38,7 @@ public void scheduleBackupTask() { } LoggingContext.clear(); }); + LoggingContext.endTask(); } private static boolean isNotPresentOnProvider(StorageFile storageFile, ObjectStorageProvider objectStorageProvider) { diff --git a/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/storagesynchronization/DeleteFilesTask.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/storagesynchronization/DeleteFilesTask.java new file mode 100644 index 000000000..0f22c0273 --- /dev/null +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/storagesynchronization/DeleteFilesTask.java @@ -0,0 +1,34 @@ +package fr.dossierfacile.scheduler.tasks.storagesynchronization; + +import fr.dossierfacile.common.entity.StorageFileToDelete; +import fr.dossierfacile.common.repository.StorageFileToDeleteRepository; +import fr.dossierfacile.common.service.interfaces.FileStorageToDeleteService; +import fr.dossierfacile.scheduler.LoggingContext; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.util.List; + +import static fr.dossierfacile.scheduler.tasks.TaskName.STORAGE_FILES_DELETION; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DeleteFilesTask { + + private final StorageFileToDeleteRepository storageFileToDeleteRepository; + private final FileStorageToDeleteService fileStorageToDeleteService; + + @Scheduled(fixedDelay = 10000) + public void deleteFileInProviderTask() { + LoggingContext.startTask(STORAGE_FILES_DELETION); + List storageFileToDeleteList = storageFileToDeleteRepository.findAll(); + for (StorageFileToDelete storageFileToDelete : storageFileToDeleteList) { + fileStorageToDeleteService.delete(storageFileToDelete); + } + LoggingContext.endTask(); + } + +} diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/TenantWarningServiceImpl.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/TenantWarningService.java similarity index 87% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/TenantWarningServiceImpl.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/TenantWarningService.java index 867b27419..7f4555768 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/TenantWarningServiceImpl.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/TenantWarningService.java @@ -1,4 +1,4 @@ -package fr.dossierfacile.garbagecollector.service; +package fr.dossierfacile.scheduler.tasks.tenantwarning; import fr.dossierfacile.common.entity.ApartmentSharing; import fr.dossierfacile.common.entity.ConfirmationToken; @@ -16,24 +16,19 @@ import fr.dossierfacile.common.service.interfaces.LogService; import fr.dossierfacile.common.service.interfaces.PartnerCallBackService; import fr.dossierfacile.common.service.interfaces.TenantCommonService; -import fr.dossierfacile.garbagecollector.service.interfaces.MailService; -import fr.dossierfacile.garbagecollector.service.interfaces.TenantWarningService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.hibernate.Hibernate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.List; import java.util.Optional; @Slf4j @Service @AllArgsConstructor -public class TenantWarningServiceImpl implements TenantWarningService { +public class TenantWarningService { private final LogService logService; - private final MailService mailService; + private final WarningMailSender mailSender; private final ConfirmationTokenService confirmationTokenService; private final ConfirmationTokenRepository confirmationTokenRepository; private final TenantCommonRepository tenantRepository; @@ -43,8 +38,7 @@ public class TenantWarningServiceImpl implements TenantWarningService { private final ApartmentSharingRepository apartmentSharingRepository; private final KeycloakCommonService keycloakCommonService; - @Override - @Transactional("dossierTransactionManager") + @Transactional public void handleTenantWarning(Tenant t, int warnings) { Tenant tenant = tenantRepository.findById(t.getId()).get(); switch (warnings) { @@ -80,7 +74,7 @@ private void handleWarning1(Tenant t) { log.info("accountWarnings. SECOND warning for tenant with ID [" + t.getId() + "]"); t.setWarnings(2); tenantRepository.save(t); - mailService.sendEmailSecondWarningForDeletionOfDocuments(t, confirmationTokenService.createToken(t)); + mailSender.sendEmailSecondWarningForDeletionOfDocuments(t, confirmationTokenService.createToken(t)); logService.saveLog(LogType.SECOND_ACCOUNT_WARNING_FOR_DOCUMENT_DELETION, t.getId()); } @@ -88,12 +82,11 @@ private void handleWarning0(Tenant t) { log.info("accountWarnings. FIRST warning for tenant with ID [" + t.getId() + "]"); t.setWarnings(1); tenantRepository.save(t); - mailService.sendEmailFirstWarningForDeletionOfDocuments(t, confirmationTokenService.createToken(t)); + mailSender.sendEmailFirstWarningForDeletionOfDocuments(t, confirmationTokenService.createToken(t)); logService.saveLog(LogType.FIRST_ACCOUNT_WARNING_FOR_DOCUMENT_DELETION, t.getId()); } - @Override - @Transactional("dossierTransactionManager") + @Transactional public void deleteOldArchivedWarning(long tenantId) { log.info("Deleting tenant " + tenantId); Tenant tenant = tenantRepository.findById(tenantId).get(); diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledWarningService.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/TenantWarningTask.java similarity index 91% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledWarningService.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/TenantWarningTask.java index f9d212125..6a9516e18 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/ScheduledWarningService.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/TenantWarningTask.java @@ -1,9 +1,9 @@ -package fr.dossierfacile.garbagecollector.service; +package fr.dossierfacile.scheduler.tasks.tenantwarning; import fr.dossierfacile.common.entity.Tenant; import fr.dossierfacile.common.enums.TenantFileStatus; import fr.dossierfacile.common.repository.TenantCommonRepository; -import fr.dossierfacile.garbagecollector.service.interfaces.TenantWarningService; +import fr.dossierfacile.scheduler.LoggingContext; import io.sentry.Sentry; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -18,10 +18,12 @@ import java.time.LocalDateTime; import java.util.List; +import static fr.dossierfacile.scheduler.tasks.TaskName.TENANT_WARNINGS; + @Slf4j @Service @RequiredArgsConstructor -public class ScheduledWarningService { +public class TenantWarningTask { @Value("${months_for_deletion_of_documents:3}") private Integer monthsForDeletionOfDocuments; @Value("${months_for_deletion_of_archived_tenants:12}") @@ -33,13 +35,13 @@ public class ScheduledWarningService { @Scheduled(cron = "${cron.process.warnings}") public void accountWarningsForDocumentDeletion() { - log.info("accountWarnings. Executing scheduled task for account warnings at [" + LocalDateTime.now() + "]"); + LoggingContext.startTask(TENANT_WARNINGS); LocalDateTime localDateTime = LocalDateTime.now().minusMonths(monthsForDeletionOfDocuments); deleteOldArchivedAccount(); processAllWarnings(localDateTime, 2); processAllWarnings(localDateTime, 1); processAllWarnings(localDateTime, 0); - log.info("accountWarnings. Account warnings' task was finished"); + LoggingContext.endTask(); } private void deleteOldArchivedAccount() { diff --git a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/MailServiceImpl.java b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/WarningMailSender.java similarity index 94% rename from dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/MailServiceImpl.java rename to dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/WarningMailSender.java index c0c8a710e..01a2c2362 100644 --- a/dossierfacile-garbage-collector/src/main/java/fr/dossierfacile/garbagecollector/service/MailServiceImpl.java +++ b/dossierfacile-task-scheduler/src/main/java/fr/dossierfacile/scheduler/tasks/tenantwarning/WarningMailSender.java @@ -1,9 +1,8 @@ -package fr.dossierfacile.garbagecollector.service; +package fr.dossierfacile.scheduler.tasks.tenantwarning; import com.google.common.base.Strings; import fr.dossierfacile.common.entity.ConfirmationToken; import fr.dossierfacile.common.entity.User; -import fr.dossierfacile.garbagecollector.service.interfaces.MailService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -20,7 +19,7 @@ @Service @RequiredArgsConstructor @Slf4j -public class MailServiceImpl implements MailService { +public class WarningMailSender { private final TransactionalEmailsApi apiInstance; @Value("${sendinblue.url.domain}") private String sendinBlueUrlDomain; @@ -29,7 +28,6 @@ public class MailServiceImpl implements MailService { @Value("${sendinblue.template.id.second.warning.for.deletion.of.documents}") private Long templateSecondWarningForDeletionOfDocuments; - @Override public void sendEmailFirstWarningForDeletionOfDocuments(User user, ConfirmationToken confirmationToken) { Map variables = new HashMap<>(); variables.put("PRENOM", user.getFirstName()); @@ -55,7 +53,6 @@ public void sendEmailFirstWarningForDeletionOfDocuments(User user, ConfirmationT } } - @Override public void sendEmailSecondWarningForDeletionOfDocuments(User user, ConfirmationToken confirmationToken) { Map variables = new HashMap<>(); variables.put("PRENOM", user.getFirstName()); diff --git a/dossierfacile-garbage-collector/src/main/resources/application.properties b/dossierfacile-task-scheduler/src/main/resources/application.properties similarity index 64% rename from dossierfacile-garbage-collector/src/main/resources/application.properties rename to dossierfacile-task-scheduler/src/main/resources/application.properties index 5287fd700..52bcba0b0 100644 --- a/dossierfacile-garbage-collector/src/main/resources/application.properties +++ b/dossierfacile-task-scheduler/src/main/resources/application.properties @@ -1,15 +1,8 @@ -#object-name-db -postgre.datasource.jdbc-url= -postgre.datasource.username= -postgre.datasource.password= -postgre.datasource.driver-class-name=org.postgresql.Driver -postgre.datasource.liquibase.change-log=classpath:db/changelog/databaseCollectorChangeLog.xml - -#dossier-db -postgre2.datasource.url= -postgre2.datasource.username= -postgre2.datasource.password= -postgre2.datasource.driver-class-name=org.postgresql.Driver +spring.datasource.url= +spring.datasource.username= +spring.datasource.password= +spring.datasource.driver-class-name=org.postgresql.Driver +spring.liquibase.enabled=false #ovh ovh.auth.url= @@ -49,5 +42,5 @@ logging.level.root=info logging.path=logs logging.logstash.destination= -application.name=garbage-collector +application.name=task-scheduler environment= \ No newline at end of file diff --git a/dossierfacile-garbage-collector/src/main/resources/logback-spring-delayed.xml b/dossierfacile-task-scheduler/src/main/resources/logback-spring-delayed.xml similarity index 97% rename from dossierfacile-garbage-collector/src/main/resources/logback-spring-delayed.xml rename to dossierfacile-task-scheduler/src/main/resources/logback-spring-delayed.xml index 3b3c0aae9..c17a645c9 100644 --- a/dossierfacile-garbage-collector/src/main/resources/logback-spring-delayed.xml +++ b/dossierfacile-task-scheduler/src/main/resources/logback-spring-delayed.xml @@ -47,6 +47,7 @@ {"application":"${APPLICATION_NAME}", "environment":"${ENVIRONMENT}", "profiles":"${APPLICATION_PROFILES}"} storage_file_id + task diff --git a/pom.xml b/pom.xml index 7f788d686..285bb26db 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ dossierfacile-api-owner dossierfacile-api-watermark dossierfacile-pdf-generator - dossierfacile-garbage-collector + dossierfacile-task-scheduler pom