View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.crawler.service;
17  
18  import java.util.List;
19  import java.util.Map;
20  
21  import org.apache.logging.log4j.LogManager;
22  import org.apache.logging.log4j.Logger;
23  import org.codelibs.fess.crawler.entity.OpenSearchUrlQueue;
24  import org.codelibs.fess.crawler.service.impl.OpenSearchUrlQueueService;
25  import org.codelibs.fess.crawler.util.OpenSearchCrawlerConfig;
26  import org.codelibs.fess.helper.CrawlingConfigHelper;
27  import org.codelibs.fess.opensearch.config.exentity.CrawlingConfig;
28  import org.codelibs.fess.opensearch.config.exentity.CrawlingConfig.ConfigName;
29  import org.codelibs.fess.util.ComponentUtil;
30  import org.opensearch.index.query.QueryBuilders;
31  import org.opensearch.index.query.functionscore.FunctionScoreQueryBuilder;
32  import org.opensearch.index.query.functionscore.RandomScoreFunctionBuilder;
33  import org.opensearch.search.sort.SortBuilders;
34  import org.opensearch.search.sort.SortOrder;
35  
36  /**
37   * Fess-specific URL queue service that extends OpenSearch URL queue functionality.
38   * This service provides customized URL fetching strategies including sequential and random ordering
39   * based on crawling configuration parameters.
40   */
41  public class FessUrlQueueService extends OpenSearchUrlQueueService {
42  
43      private static final Logger logger = LogManager.getLogger(FessUrlQueueService.class);
44  
45      /** Configuration value for sequential URL processing order */
46      protected static final String ORDER_SEQUENTIAL = "sequential";
47  
48      /** Configuration value for random URL processing order */
49      protected static final String ORDER_RANDOM = "random";
50  
51      /**
52       * Constructs a new FessUrlQueueService with the specified crawler configuration.
53       *
54       * @param crawlerConfig the OpenSearch crawler configuration
55       */
56      public FessUrlQueueService(final OpenSearchCrawlerConfig crawlerConfig) {
57          super(crawlerConfig);
58      }
59  
60      /**
61       * Fetches URL queue list for the specified session with configurable ordering strategy.
62       * Supports sequential (default) and random ordering based on crawling configuration.
63       *
64       * @param sessionId the crawling session identifier
65       * @return list of URL queue entries for processing
66       */
67      @Override
68      protected List<OpenSearchUrlQueue> fetchUrlQueueList(final String sessionId) {
69          final CrawlingConfigHelper crawlingConfigHelper = ComponentUtil.getCrawlingConfigHelper();
70          final CrawlingConfig crawlingConfig = crawlingConfigHelper.get(sessionId);
71          final Map<String, String> configParams = crawlingConfig.getConfigParameterMap(ConfigName.CONFIG);
72          final String crawlOrder = configParams.getOrDefault(CrawlingConfig.Param.Config.CRAWL_ORDER, ORDER_SEQUENTIAL);
73          if (ORDER_RANDOM.equals(crawlOrder)) {
74              return getList(OpenSearchUrlQueue.class, sessionId,
75                      QueryBuilders.functionScoreQuery(QueryBuilders.matchAllQuery(),
76                              new FunctionScoreQueryBuilder.FilterFunctionBuilder[] { new FunctionScoreQueryBuilder.FilterFunctionBuilder(
77                                      new RandomScoreFunctionBuilder().seed(sessionId.hashCode())) }),
78                      0, pollingFetchSize, SortBuilders.scoreSort().order(SortOrder.DESC));
79          } else if (!ORDER_SEQUENTIAL.equals(crawlOrder)) {
80              logger.warn("Invalid crawl order specified: {}. Falling back to sequential.", crawlOrder);
81          }
82          return super.fetchUrlQueueList(sessionId);
83      }
84  }