From 83bcdb017af7f0de181be6cb5f05c6e2502be90a Mon Sep 17 00:00:00 2001 From: Thuy Nguyen <145430420+nntthuy-axonivy@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:30:31 +0700 Subject: [PATCH] MARP-1332 Trigger the ExternalDocument job if detected new release version (#224) --- .../market/MarketplaceServiceApplication.java | 3 +- .../ExternalDocumentController.java | 6 +++- .../market/schedulingtask/ScheduledTasks.java | 4 ++- .../service/ExternalDocumentService.java | 2 +- .../impl/ExternalDocumentServiceImpl.java | 13 ++++--- .../service/impl/ProductServiceImpl.java | 35 ++++++++++++------- .../market/service/SystemTasksTest.java | 3 +- .../impl/ExternalDocumentServiceImplTest.java | 7 ++-- .../service/impl/ProductServiceImplTest.java | 3 ++ 9 files changed, 51 insertions(+), 25 deletions(-) diff --git a/marketplace-service/src/main/java/com/axonivy/market/MarketplaceServiceApplication.java b/marketplace-service/src/main/java/com/axonivy/market/MarketplaceServiceApplication.java index 87fdc7472..fbc21396b 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/MarketplaceServiceApplication.java +++ b/marketplace-service/src/main/java/com/axonivy/market/MarketplaceServiceApplication.java @@ -14,6 +14,7 @@ import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; +import java.util.ArrayList; import java.util.List; @Log4j2 @@ -60,7 +61,7 @@ private void syncExternalDocumentData(List productIds) { if (ObjectUtils.isEmpty(productIds)) { log.warn("Synchronizing External Document: Nothing updated"); } - productIds.forEach(id -> externalDocumentService.syncDocumentForProduct(id, false)); + productIds.forEach(id -> externalDocumentService.syncDocumentForProduct(id, new ArrayList<>(), false)); watch.stop(); log.warn("Synchronizing External Document: Finished synchronizing data for Document in [{}] milliseconds", watch.getTime()); diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ExternalDocumentController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ExternalDocumentController.java index ac8d850b7..116714892 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/controller/ExternalDocumentController.java +++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ExternalDocumentController.java @@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.ArrayList; import java.util.List; import static com.axonivy.market.constants.RequestMappingConstants.*; @@ -73,7 +74,10 @@ public ResponseEntity syncDocumentForProduct( if (ObjectUtils.isEmpty(products)) { return new ResponseEntity<>(message, HttpStatus.NO_CONTENT); } - products.forEach(product -> externalDocumentService.syncDocumentForProduct(product.getId(), resetSync)); + + for (Product product : products) { + externalDocumentService.syncDocumentForProduct(product.getId(), new ArrayList<>(), resetSync); + } message.setHelpCode(ErrorCode.SUCCESSFUL.getCode()); message.setHelpText(ErrorCode.SUCCESSFUL.getHelpText()); diff --git a/marketplace-service/src/main/java/com/axonivy/market/schedulingtask/ScheduledTasks.java b/marketplace-service/src/main/java/com/axonivy/market/schedulingtask/ScheduledTasks.java index 078ba2fdd..28f6eafd2 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/schedulingtask/ScheduledTasks.java +++ b/marketplace-service/src/main/java/com/axonivy/market/schedulingtask/ScheduledTasks.java @@ -8,6 +8,8 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import java.util.ArrayList; + @Log4j2 @Component @AllArgsConstructor @@ -31,7 +33,7 @@ public void syncDataForProductFromGitHubRepo() { public void syncDataForProductDocuments() { log.warn("Started sync data for product document"); for (var product : productRepo.findAllProductsHaveDocument()) { - externalDocumentService.syncDocumentForProduct(product.getId(), false); + externalDocumentService.syncDocumentForProduct(product.getId(), new ArrayList<>(), false); } } } diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/ExternalDocumentService.java b/marketplace-service/src/main/java/com/axonivy/market/service/ExternalDocumentService.java index 2a09fddbe..5b74f4b4e 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/ExternalDocumentService.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/ExternalDocumentService.java @@ -6,7 +6,7 @@ import java.util.List; public interface ExternalDocumentService { - void syncDocumentForProduct(String productId, boolean isResetSync); + void syncDocumentForProduct(String productId, List nonSyncReleasedVersions, boolean isResetSync); List findAllProductsHaveDocument(); diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ExternalDocumentServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ExternalDocumentServiceImpl.java index 799a647b9..5efc700e8 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ExternalDocumentServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ExternalDocumentServiceImpl.java @@ -20,6 +20,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -37,13 +38,17 @@ public class ExternalDocumentServiceImpl implements ExternalDocumentService { final FileDownloadService fileDownloadService; @Override - public void syncDocumentForProduct(String productId, boolean isResetSync) { + public void syncDocumentForProduct(String productId, List nonSyncReleasedVersions, boolean isResetSync) { productRepo.findById(productId).ifPresent(product -> { var docArtifacts = Optional.ofNullable(product.getArtifacts()).orElse(List.of()) .stream().filter(artifact -> BooleanUtils.isTrue(artifact.getDoc())).toList(); - List releasedVersions = Optional.ofNullable(product.getReleasedVersions()).orElse(List.of()) - .stream().filter(VersionUtils::isValidFormatReleasedVersion).toList(); - if (ObjectUtils.isEmpty(docArtifacts) || ObjectUtils.isEmpty(releasedVersions)) { + + List releasedVersions = ObjectUtils.isEmpty(nonSyncReleasedVersions) + ? Optional.ofNullable(product.getReleasedVersions()).orElse(new ArrayList<>()) + : nonSyncReleasedVersions; + releasedVersions = releasedVersions.stream().filter(VersionUtils::isValidFormatReleasedVersion).toList(); + + if (ObjectUtils.isEmpty(docArtifacts) || ObjectUtils.isEmpty(releasedVersions) ) { return; } diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java index df1d19ced..836ed1da2 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java @@ -35,6 +35,7 @@ import com.axonivy.market.repository.ProductJsonContentRepository; import com.axonivy.market.repository.ProductModuleContentRepository; import com.axonivy.market.repository.ProductRepository; +import com.axonivy.market.service.ExternalDocumentService; import com.axonivy.market.service.ImageService; import com.axonivy.market.service.MetadataService; import com.axonivy.market.service.ProductContentService; @@ -114,6 +115,7 @@ public class ProductServiceImpl implements ProductService { private final ImageService imageService; private final MongoTemplate mongoTemplate; private final ProductContentService productContentService; + private final ExternalDocumentService externalDocumentService; private final ObjectMapper mapper = new ObjectMapper(); private final SecureRandom random = new SecureRandom(); private final MetadataService metadataService; @@ -131,7 +133,8 @@ public ProductServiceImpl(ProductRepository productRepo, ProductCustomSortRepository productCustomSortRepo, MavenArtifactVersionRepository mavenArtifactVersionRepo, ProductJsonContentRepository productJsonContentRepo, ImageRepository imageRepo, MetadataSyncRepository metadataSyncRepo, MetadataRepository metadataRepo, ImageService imageService, - MongoTemplate mongoTemplate, ProductContentService productContentService, MetadataService metadataService) { + MongoTemplate mongoTemplate, ProductContentService productContentService, + ExternalDocumentService externalDocumentService, MetadataService metadataService) { this.productRepo = productRepo; this.productModuleContentRepo = productModuleContentRepo; this.axonIvyMarketRepoService = axonIvyMarketRepoService; @@ -147,6 +150,7 @@ public ProductServiceImpl(ProductRepository productRepo, this.imageService = imageService; this.mongoTemplate = mongoTemplate; this.productContentService = productContentService; + this.externalDocumentService = externalDocumentService; this.metadataService = metadataService; } @@ -489,6 +493,7 @@ private void updateProductFromReleasedVersions(Product product) { getMetadataContent(mavenArtifact, product, nonSyncReleasedVersions); } metadataService.updateArtifactAndMetadata(product.getId(), nonSyncReleasedVersions, product.getArtifacts()); + externalDocumentService.syncDocumentForProduct(product.getId(), nonSyncReleasedVersions, false); } private void getMetadataContent(Artifact artifact, Product product, List nonSyncReleasedVersions) { @@ -500,30 +505,34 @@ private void getMetadataContent(Artifact artifact, Product product, List } } - private void updateContentsFromMavenXML(Product product, String metadataContent, Artifact mavenArtifact, List nonSyncReleasedVersions) { + private void updateContentsFromMavenXML(Product product, String metadataContent, Artifact mavenArtifact, + List nonSyncReleasedVersions) { Document document = MetadataReaderUtils.getDocumentFromXMLContent(metadataContent); - String latestVersion = MetadataReaderUtils.getElementValue(document, MavenConstants.LATEST_VERSION_TAG); - if (StringUtils.equals(latestVersion, product.getNewestReleaseVersion())) { - return; - } - - product.setNewestPublishedDate(getNewestPublishedDate(document)); - product.setNewestReleaseVersion(latestVersion); NodeList versionNodes = document.getElementsByTagName(MavenConstants.VERSION_TAG); List mavenVersions = new ArrayList<>(); for (int i = 0; i < versionNodes.getLength(); i++) { mavenVersions.add(versionNodes.item(i).getTextContent()); } - updateProductCompatibility(product, mavenVersions); - + // Check if having new released version in Maven List currentVersions = ObjectUtils.isNotEmpty(product.getReleasedVersions()) ? product.getReleasedVersions() : productModuleContentRepo.findVersionsByProductId(product.getId()); - mavenVersions = mavenVersions.stream().filter(version -> !currentVersions.contains(version)).toList(); + if (ObjectUtils.isEmpty(mavenVersions)) { + return; + } + + Date lastUpdated = getLastUpdatedDate(document); + if (ObjectUtils.isEmpty(product.getNewestPublishedDate()) || lastUpdated.after(product.getNewestPublishedDate())) { + String latestVersion = MetadataReaderUtils.getElementValue(document, MavenConstants.LATEST_VERSION_TAG); + product.setNewestPublishedDate(lastUpdated); + product.setNewestReleaseVersion(latestVersion); + } + updateProductCompatibility(product, mavenVersions); + Optional.ofNullable(product.getReleasedVersions()).ifPresentOrElse(releasedVersion -> {}, () -> product.setReleasedVersions(new ArrayList<>())); @@ -541,7 +550,7 @@ private void updateContentsFromMavenXML(Product product, String metadataContent, } } - private Date getNewestPublishedDate(Document document) { + private Date getLastUpdatedDate(Document document) { DateTimeFormatter lastUpdatedFormatter = DateTimeFormatter.ofPattern(MavenConstants.DATE_TIME_FORMAT); LocalDateTime newestPublishedDate = LocalDateTime.parse(Objects.requireNonNull(MetadataReaderUtils.getElementValue(document, diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/SystemTasksTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/SystemTasksTest.java index 683c5f316..b5244631e 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/SystemTasksTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/SystemTasksTest.java @@ -9,6 +9,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.ArrayList; import java.util.List; import static org.mockito.Mockito.*; @@ -36,7 +37,7 @@ void testSyncDoc() { when(productRepo.findAllProductsHaveDocument()).thenReturn(List.of(mockProduct)); tasks.syncDataForProductDocuments(); verify(productRepo, times(1)).findAllProductsHaveDocument(); - verify(externalDocumentService, times(1)).syncDocumentForProduct(PORTAL, false); + verify(externalDocumentService, times(1)).syncDocumentForProduct(PORTAL, new ArrayList<>(), false); } @Test diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ExternalDocumentServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ExternalDocumentServiceImplTest.java index 0e0eb5412..07168e7c6 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ExternalDocumentServiceImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ExternalDocumentServiceImplTest.java @@ -13,6 +13,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -41,16 +42,16 @@ class ExternalDocumentServiceImplTest { @Test void testSyncDocumentForProduct() throws IOException { when(productRepository.findById(PORTAL)).thenReturn(mockPortalProductHasNoArtifact()); - service.syncDocumentForProduct(PORTAL, true); + service.syncDocumentForProduct(PORTAL, new ArrayList<>(), true); verify(productRepository, times(1)).findById(any()); verify(externalDocumentMetaRepository, times(0)).findByProductIdAndVersion(any(), any()); when(productRepository.findById(PORTAL)).thenReturn(mockPortalProduct()); - service.syncDocumentForProduct(PORTAL, false); + service.syncDocumentForProduct(PORTAL, new ArrayList<>(), false); verify(externalDocumentMetaRepository, times(2)).findByProductIdAndVersion(any(), any()); when(fileDownloadService.downloadAndUnzipFile(any(), anyBoolean())).thenReturn("data" + RELATIVE_LOCATION); - service.syncDocumentForProduct(PORTAL, true); + service.syncDocumentForProduct(PORTAL, new ArrayList<>(), true); verify(externalDocumentMetaRepository, times(2)).save(any()); } diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java index 30f87f52d..0dd20f6bc 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java @@ -31,6 +31,7 @@ import com.axonivy.market.repository.ProductJsonContentRepository; import com.axonivy.market.repository.ProductModuleContentRepository; import com.axonivy.market.repository.ProductRepository; +import com.axonivy.market.service.ExternalDocumentService; import com.axonivy.market.service.ImageService; import com.axonivy.market.service.MetadataService; import com.axonivy.market.service.ProductContentService; @@ -126,6 +127,8 @@ class ProductServiceImplTest extends BaseSetup { @Mock private ImageService imageService; @Mock + private ExternalDocumentService externalDocumentService; + @Mock private MavenArtifactVersionRepository mavenArtifactVersionRepo; @Mock private ProductContentService productContentService;