diff --git a/server/src/main/java/org/eclipse/openvsx/search/ElasticSearchService.java b/server/src/main/java/org/eclipse/openvsx/search/ElasticSearchService.java index 9e9e5abd2..02c5df725 100644 --- a/server/src/main/java/org/eclipse/openvsx/search/ElasticSearchService.java +++ b/server/src/main/java/org/eclipse/openvsx/search/ElasticSearchService.java @@ -9,6 +9,7 @@ ********************************************************************************/ package org.eclipse.openvsx.search; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -20,6 +21,7 @@ import com.google.common.base.Strings; import org.eclipse.openvsx.entities.Extension; +import org.eclipse.openvsx.migration.HandlerJobRequest; import org.eclipse.openvsx.repositories.RepositoryService; import org.eclipse.openvsx.search.RelevanceService.SearchStats; import org.eclipse.openvsx.util.ErrorResultException; @@ -29,6 +31,7 @@ import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; +import org.jobrunr.scheduling.JobRequestScheduler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -65,6 +68,9 @@ public class ElasticSearchService implements ISearchService { @Autowired RelevanceService relevanceService; + @Autowired + JobRequestScheduler scheduler; + @Value("${ovsx.elasticsearch.enabled:true}") boolean enableSearch; @Value("${ovsx.elasticsearch.clear-on-start:false}") @@ -95,6 +101,7 @@ public boolean isEnabled() { @Retryable(DataAccessResourceFailureException.class) @CacheEvict(value = CACHE_AVERAGE_REVIEW_RATING, allEntries = true) public void initSearchIndex(ApplicationStartedEvent event) { + scheduler.scheduleRecurrently("ElasticSearchUpdateIndex", "0 0 4 * * *", ZoneId.of("UTC"), new HandlerJobRequest<>(ElasticSearchUpdateIndexJobRequestHandler.class)); if (!isEnabled() || !clearOnStart && searchOperations.indexOps(ExtensionSearch.class).exists()) { return; } @@ -106,11 +113,10 @@ public void initSearchIndex(ApplicationStartedEvent event) { } /** - * Task scheduled once per day to soft-update the search index. This is necessary - * because the relevance of index entries might consider the extension publishing - * timestamps in relation to the current time or the extension rating. + * Soft-update the search index, because the relevance of index entries + * consider the extension publishing timestamps in relation to the current + * time or the extension rating. */ - @Scheduled(cron = "0 0 4 * * *", zone = "UTC") @Retryable(DataAccessResourceFailureException.class) @CacheEvict(value = CACHE_AVERAGE_REVIEW_RATING, allEntries = true) public void updateSearchIndex() { diff --git a/server/src/main/java/org/eclipse/openvsx/search/ElasticSearchUpdateIndexJobRequestHandler.java b/server/src/main/java/org/eclipse/openvsx/search/ElasticSearchUpdateIndexJobRequestHandler.java new file mode 100644 index 000000000..0aa87fd24 --- /dev/null +++ b/server/src/main/java/org/eclipse/openvsx/search/ElasticSearchUpdateIndexJobRequestHandler.java @@ -0,0 +1,29 @@ +/** ****************************************************************************** + * Copyright (c) 2023 Precies. Software Ltd and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * ****************************************************************************** */ +package org.eclipse.openvsx.search; + +import org.eclipse.openvsx.migration.HandlerJobRequest; +import org.jobrunr.jobs.annotations.Job; +import org.jobrunr.jobs.lambdas.JobRequestHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ElasticSearchUpdateIndexJobRequestHandler implements JobRequestHandler { + + @Autowired + ElasticSearchService search; + + @Override + @Job(name = "Task scheduled once per day to soft-update the search index.", retries = 0) + public void run(HandlerJobRequest jobRequest) throws Exception { + search.updateSearchIndex(); + } +} diff --git a/server/src/test/java/org/eclipse/openvsx/search/ElasticSearchServiceTest.java b/server/src/test/java/org/eclipse/openvsx/search/ElasticSearchServiceTest.java index 2d376cc60..c7e458ffc 100644 --- a/server/src/test/java/org/eclipse/openvsx/search/ElasticSearchServiceTest.java +++ b/server/src/test/java/org/eclipse/openvsx/search/ElasticSearchServiceTest.java @@ -9,19 +9,12 @@ ********************************************************************************/ package org.eclipse.openvsx.search; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - import org.eclipse.openvsx.cache.LatestExtensionVersionCacheKeyGenerator; import org.eclipse.openvsx.entities.*; import org.eclipse.openvsx.repositories.RepositoryService; import org.eclipse.openvsx.util.TargetPlatform; import org.eclipse.openvsx.util.VersionService; +import org.jobrunr.scheduling.JobRequestScheduler; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; @@ -38,8 +31,16 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import javax.persistence.EntityManager; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; @ExtendWith(SpringExtension.class) +@MockBean({JobRequestScheduler.class}) public class ElasticSearchServiceTest { @MockBean