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.app.service;
17  
18  import java.util.List;
19  
20  import org.apache.logging.log4j.LogManager;
21  import org.apache.logging.log4j.Logger;
22  import org.codelibs.core.beans.util.BeanUtil;
23  import org.codelibs.fess.Constants;
24  import org.codelibs.fess.app.pager.SchedulerPager;
25  import org.codelibs.fess.mylasta.direction.FessConfig;
26  import org.codelibs.fess.opensearch.config.cbean.ScheduledJobCB;
27  import org.codelibs.fess.opensearch.config.exbhv.ScheduledJobBhv;
28  import org.codelibs.fess.opensearch.config.exentity.ScheduledJob;
29  import org.codelibs.fess.util.ComponentUtil;
30  import org.dbflute.cbean.result.PagingResultBean;
31  import org.dbflute.optional.OptionalEntity;
32  import org.lastaflute.job.LaCron;
33  
34  import jakarta.annotation.Resource;
35  
36  /**
37   * Service class for managing scheduled jobs.
38   */
39  public class ScheduledJobService {
40  
41      /**
42       * Constructor.
43       */
44      public ScheduledJobService() {
45          super();
46      }
47  
48      private static final Logger logger = LogManager.getLogger(ScheduledJobService.class);
49  
50      /**
51       * The behavior for scheduled jobs.
52       */
53      @Resource
54      protected ScheduledJobBhv scheduledJobBhv;
55  
56      /**
57       * The Fess configuration.
58       */
59      @Resource
60      protected FessConfig fessConfig;
61  
62      /**
63       * Gets a list of scheduled jobs based on the pager.
64       * @param scheduledJobPager The pager for scheduled jobs.
65       * @return A list of scheduled jobs.
66       */
67      public List<ScheduledJob> getScheduledJobList(final SchedulerPager scheduledJobPager) {
68  
69          final PagingResultBean<ScheduledJob> scheduledJobList = scheduledJobBhv.selectPage(cb -> {
70              cb.paging(scheduledJobPager.getPageSize(), scheduledJobPager.getCurrentPageNumber());
71              setupListCondition(cb, scheduledJobPager);
72          });
73  
74          // update pager
75          BeanUtil.copyBeanToBean(scheduledJobList, scheduledJobPager, option -> option.include(Constants.PAGER_CONVERSION_RULE));
76          scheduledJobPager.setPageNumberList(scheduledJobList.pageRange(op -> {
77              op.rangeSize(fessConfig.getPagingPageRangeSizeAsInteger());
78          }).createPageNumberList());
79  
80          return scheduledJobList;
81      }
82  
83      /**
84       * Gets a list of scheduled jobs that have been updated after a specific time.
85       * @param updateTime The update time.
86       * @return A list of scheduled jobs.
87       */
88      public List<ScheduledJob> getScheduledJobListAfter(final long updateTime) {
89          return scheduledJobBhv.selectPage(cb -> {
90              cb.fetchFirst(fessConfig.getPageScheduledJobMaxFetchSizeAsInteger());
91              cb.query().setAvailable_Equal(Boolean.TRUE);
92              cb.query().setUpdatedTime_GreaterThan(updateTime);
93          });
94      }
95  
96      /**
97       * Gets a scheduled job by its ID.
98       * @param id The ID of the scheduled job.
99       * @return An optional entity of the scheduled job.
100      */
101     public OptionalEntity<ScheduledJob> getScheduledJob(final String id) {
102         return scheduledJobBhv.selectByPK(id);
103     }
104 
105     /**
106      * Deletes a scheduled job.
107      * @param scheduledJob The scheduled job to delete.
108      */
109     public void delete(final ScheduledJob scheduledJob) {
110         scheduledJobBhv.delete(scheduledJob, op -> {
111             op.setRefreshPolicy(Constants.TRUE);
112         });
113         ComponentUtil.getJobHelper().remove(scheduledJob);
114     }
115 
116     /**
117      * Sets up the list condition for the scheduled job query.
118      * @param cb The scheduled job condition bean.
119      * @param scheduledJobPager The scheduled job pager.
120      */
121     protected void setupListCondition(final ScheduledJobCB cb, final SchedulerPager scheduledJobPager) {
122         if (scheduledJobPager.id != null) {
123             cb.query().docMeta().setId_Equal(scheduledJobPager.id);
124         }
125         // TODO Long, Integer, String supported only.
126 
127         // setup condition
128         cb.query().addOrderBy_SortOrder_Asc();
129         cb.query().addOrderBy_Name_Asc();
130 
131         // search
132 
133     }
134 
135     /**
136      * Gets a list of all scheduled jobs.
137      * @return A list of all scheduled jobs.
138      */
139     public List<ScheduledJob> getScheduledJobList() {
140         return scheduledJobBhv.selectList(cb -> {
141             cb.query().addOrderBy_SortOrder_Asc();
142             cb.query().addOrderBy_Name_Asc();
143             cb.fetchFirst(fessConfig.getPageScheduledJobMaxFetchSizeAsInteger());
144         });
145     }
146 
147     /**
148      * Stores a scheduled job.
149      * @param scheduledJob The scheduled job to store.
150      */
151     public void store(final ScheduledJob scheduledJob) {
152         scheduledJobBhv.insertOrUpdate(scheduledJob, op -> {
153             op.setRefreshPolicy(Constants.TRUE);
154         });
155     }
156 
157     /**
158      * Gets a list of crawler jobs.
159      * @return A list of crawler jobs.
160      */
161     public List<ScheduledJob> getCrawlerJobList() {
162         return scheduledJobBhv.selectList(cb -> {
163             cb.query().setCrawler_Equal(Constants.T);
164             cb.query().addOrderBy_SortOrder_Asc();
165             cb.query().addOrderBy_Name_Asc();
166             cb.fetchFirst(fessConfig.getPageScheduledJobMaxFetchSizeAsInteger());
167         });
168     }
169 
170     /**
171      * Starts all available scheduled jobs.
172      * @param cron The cron scheduler.
173      */
174     public void start(final LaCron cron) {
175         scheduledJobBhv.selectCursor(cb -> {
176             cb.query().setAvailable_Equal(Constants.T);
177             cb.query().addOrderBy_SortOrder_Asc();
178             cb.query().addOrderBy_Name_Asc();
179         }, scheduledJob -> {
180             try {
181                 ComponentUtil.getJobHelper().register(cron, scheduledJob);
182             } catch (final Exception e) {
183                 logger.error("Failed to start job: id={}", scheduledJob.getId(), e);
184             }
185         });
186     }
187 }