View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.logic;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.Optional;
24  import org.apache.commons.lang3.tuple.Triple;
25  import org.apache.syncope.common.lib.to.EntityTO;
26  import org.apache.syncope.common.lib.to.JobTO;
27  import org.apache.syncope.common.lib.types.JobAction;
28  import org.apache.syncope.common.lib.types.JobType;
29  import org.apache.syncope.core.persistence.api.dao.JobStatusDAO;
30  import org.apache.syncope.core.persistence.api.entity.JobStatus;
31  import org.apache.syncope.core.provisioning.api.job.JobManager;
32  import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
33  import org.apache.syncope.core.provisioning.java.job.SystemLoadReporterJob;
34  import org.apache.syncope.core.provisioning.java.job.TaskJob;
35  import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob;
36  import org.apache.syncope.core.provisioning.java.job.report.ReportJob;
37  import org.quartz.JobDetail;
38  import org.quartz.JobKey;
39  import org.quartz.Scheduler;
40  import org.quartz.SchedulerException;
41  import org.quartz.Trigger;
42  import org.quartz.impl.matchers.GroupMatcher;
43  import org.springframework.beans.factory.NoSuchBeanDefinitionException;
44  import org.springframework.scheduling.quartz.SchedulerFactoryBean;
45  
46  abstract class AbstractJobLogic<T extends EntityTO> extends AbstractTransactionalLogic<T> {
47  
48      protected final JobManager jobManager;
49  
50      protected final SchedulerFactoryBean scheduler;
51  
52      protected final JobStatusDAO jobStatusDAO;
53  
54      protected AbstractJobLogic(
55              final JobManager jobManager,
56              final SchedulerFactoryBean scheduler,
57              final JobStatusDAO jobStatusDAO) {
58  
59          this.jobManager = jobManager;
60          this.scheduler = scheduler;
61          this.jobStatusDAO = jobStatusDAO;
62      }
63  
64      protected abstract Triple<JobType, String, String> getReference(JobKey jobKey);
65  
66      protected JobTO getJobTO(final JobKey jobKey, final boolean includeCustom) throws SchedulerException {
67          JobTO jobTO = null;
68  
69          if (scheduler.getScheduler().checkExists(jobKey)) {
70              Triple<JobType, String, String> reference = getReference(jobKey);
71              if (reference != null) {
72                  jobTO = new JobTO();
73                  jobTO.setType(reference.getLeft());
74                  jobTO.setRefKey(reference.getMiddle());
75                  jobTO.setRefDesc(reference.getRight());
76              } else if (includeCustom) {
77                  JobDetail jobDetail = scheduler.getScheduler().getJobDetail(jobKey);
78                  if (!TaskJob.class.isAssignableFrom(jobDetail.getJobClass())
79                          && !ReportJob.class.isAssignableFrom(jobDetail.getJobClass())
80                          && !SystemLoadReporterJob.class.isAssignableFrom(jobDetail.getJobClass())
81                          && !NotificationJob.class.isAssignableFrom(jobDetail.getJobClass())) {
82  
83                      jobTO = new JobTO();
84                      jobTO.setType(JobType.CUSTOM);
85                      jobTO.setRefKey(jobKey.getName());
86                      jobTO.setRefDesc(jobDetail.getJobClass().getName());
87                  }
88              }
89  
90              if (jobTO != null) {
91                  List<? extends Trigger> jobTriggers = scheduler.getScheduler().getTriggersOfJob(jobKey);
92                  if (jobTriggers.isEmpty()) {
93                      jobTO.setScheduled(false);
94                  } else {
95                      jobTO.setScheduled(true);
96                      jobTO.setStart(jobTriggers.get(0).getStartTime().toInstant().atOffset(FormatUtils.DEFAULT_OFFSET));
97                  }
98  
99                  jobTO.setRunning(jobManager.isRunning(jobKey));
100 
101                 jobTO.setStatus("UNKNOWN");
102                 if (jobTO.isRunning()) {
103                     try {
104                         jobTO.setStatus(Optional.ofNullable(jobStatusDAO.find(jobTO.getRefDesc())).
105                                 map(JobStatus::getStatus).
106                                 orElse(jobTO.getStatus()));
107                     } catch (NoSuchBeanDefinitionException e) {
108                         LOG.warn("Could not find job {} implementation", jobKey, e);
109                     }
110                 }
111             }
112         }
113 
114         return jobTO;
115     }
116 
117     protected List<JobTO> doListJobs(final boolean includeCustom) {
118         List<JobTO> jobTOs = new ArrayList<>();
119         try {
120             for (JobKey jobKey : scheduler.getScheduler().
121                     getJobKeys(GroupMatcher.jobGroupEquals(Scheduler.DEFAULT_GROUP))) {
122 
123                 JobTO jobTO = getJobTO(jobKey, includeCustom);
124                 if (jobTO != null) {
125                     jobTOs.add(jobTO);
126                 }
127             }
128         } catch (SchedulerException e) {
129             LOG.debug("Problems while retrieving scheduled jobs", e);
130         }
131 
132         return jobTOs;
133     }
134 
135     protected void doActionJob(final JobKey jobKey, final JobAction action) {
136         try {
137             if (scheduler.getScheduler().checkExists(jobKey)) {
138                 switch (action) {
139                     case START:
140                         scheduler.getScheduler().triggerJob(jobKey);
141                         break;
142 
143                     case STOP:
144                         scheduler.getScheduler().interrupt(jobKey);
145                         break;
146 
147                     case DELETE:
148                         scheduler.getScheduler().deleteJob(jobKey);
149                         break;
150 
151                     default:
152                 }
153             } else {
154                 LOG.warn("Could not find job {}", jobKey);
155             }
156         } catch (SchedulerException e) {
157             LOG.debug("Problems during {} operation on job {}", action.toString(), jobKey, e);
158         }
159     }
160 }