View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  
22  package org.opencastproject.scheduler.impl;
23  
24  import org.opencastproject.kernel.scanner.AbstractBufferScanner;
25  import org.opencastproject.kernel.scanner.AbstractScanner;
26  import org.opencastproject.scheduler.api.SchedulerException;
27  import org.opencastproject.scheduler.api.SchedulerService;
28  import org.opencastproject.security.api.Organization;
29  import org.opencastproject.security.api.OrganizationDirectoryService;
30  import org.opencastproject.security.api.SecurityService;
31  import org.opencastproject.security.api.UnauthorizedException;
32  import org.opencastproject.serviceregistry.api.ServiceRegistry;
33  import org.opencastproject.util.NeedleEye;
34  
35  import org.osgi.service.cm.ManagedService;
36  import org.osgi.service.component.ComponentContext;
37  import org.osgi.service.component.annotations.Activate;
38  import org.osgi.service.component.annotations.Component;
39  import org.osgi.service.component.annotations.Deactivate;
40  import org.osgi.service.component.annotations.Reference;
41  import org.quartz.JobDetail;
42  import org.quartz.JobExecutionContext;
43  import org.quartz.Scheduler;
44  import org.quartz.impl.StdSchedulerFactory;
45  import org.slf4j.Logger;
46  import org.slf4j.LoggerFactory;
47  
48  import java.util.Optional;
49  
50  @Component(
51      immediate = true,
52      service = ManagedService.class,
53      property = {
54          "service.description=Cleanup Finished Recordings from the Schedule Scanner"
55      }
56  )
57  public class OldScheduledScanner extends AbstractBufferScanner implements ManagedService {
58  
59    /** The logging facility */
60    private static final Logger logger = LoggerFactory.getLogger(OldScheduledScanner.class);
61    public static final String SCANNER_NAME = "Cleanup Finished Scheduled Events Scanner";
62    public static final String JOB_GROUP = "mh-scheduler-cleanup-job-group";
63    public static final String JOB_NAME = "mh-scheduler-cleanup-job";
64    public static final String TRIGGER_GROUP = "mh-scheduler-cleanup-trigger";
65    public static final String TRIGGER_NAME = "mh-scheduler-cleanup-trigger";
66  
67    /** Reference to the scheduler service. */
68    private SchedulerService service;
69  
70    public OldScheduledScanner() {
71      try {
72        quartz = new StdSchedulerFactory().getScheduler();
73        quartz.start();
74        // create and set the job. To actually run it call schedule(..)
75        final JobDetail job = new JobDetail(getJobName(), getJobGroup(), Runner.class);
76        job.setDurability(false);
77        job.setVolatility(true);
78        job.getJobDataMap().put(JOB_PARAM_PARENT, this);
79        quartz.addJob(job, true);
80      } catch (org.quartz.SchedulerException e) {
81        throw new RuntimeException(e);
82      }
83    }
84  
85    @Activate
86    @Override
87    public void activate(ComponentContext cc) {
88      super.activate(cc);
89    }
90  
91    @Deactivate
92    @Override
93    public void deactivate() {
94      super.deactivate();
95    }
96  
97    /**
98     * Method to set the service this REST endpoint uses
99     *
100    * @param service
101    */
102   @Reference
103   public void setService(SchedulerService service) {
104     this.service = service;
105   }
106 
107   @Reference
108   @Override
109   public void bindServiceRegistry(ServiceRegistry serviceRegistry) {
110     super.bindServiceRegistry(serviceRegistry);
111   }
112 
113   @Reference
114   @Override
115   public void bindOrganizationDirectoryService(OrganizationDirectoryService organizationDirectoryService) {
116     super.bindOrganizationDirectoryService(organizationDirectoryService);
117   }
118 
119   @Reference
120   @Override
121   public void bindSecurityService(SecurityService securityService) {
122     super.bindSecurityService(securityService);
123   }
124 
125   @Override
126   public void setQuartz(Scheduler quartz) {
127     this.quartz = quartz;
128   }
129 
130   /**
131    * Method to unset the service this REST endpoint uses
132    *
133    * @param service
134    */
135   public void unsetService(SchedulerService service) {
136     if (this.service == service) {
137       this.service = null;
138     }
139   }
140 
141   @Override
142   public String getJobGroup() {
143     return JOB_GROUP;
144   }
145 
146   @Override
147   public String getJobName() {
148     return JOB_NAME;
149   }
150 
151   @Override
152   public String getTriggerGroupName() {
153     return TRIGGER_GROUP;
154   }
155 
156   @Override
157   public String getTriggerName() {
158     return TRIGGER_NAME;
159   }
160 
161   @Override
162   public String getScannerName() {
163     return SCANNER_NAME;
164   }
165 
166   @Override
167   public void scan() {
168     try {
169       service.removeScheduledRecordingsBeforeBuffer(getBuffer());
170     } catch (UnauthorizedException e) {
171       logger.error("Unable to scan for finished recordings, not authorized: ", e);
172     } catch (SchedulerException e) {
173       logger.error("Unable to scan for finished recordings: ", e);
174     }
175   }
176 
177   /** Quartz job to which cleans up the workflow instances */
178   public static class Runner extends TypedQuartzJob<AbstractScanner> {
179     private static final NeedleEye eye = new NeedleEye();
180 
181     public Runner() {
182       super(Optional.of(eye));
183     }
184 
185     @Override
186     protected void execute(final AbstractScanner parameters, JobExecutionContext ctx) {
187       logger.debug("Starting " + parameters.getScannerName() + " job.");
188 
189       // iterate all organizations
190       for (final Organization org : parameters.getOrganizationDirectoryService().getOrganizations()) {
191         // set the organization on the current thread
192         parameters.getAdminContextFor(org.getId()).runInContext(parameters::scan);
193       }
194 
195       logger.info("Finished " + parameters.getScannerName() + " job.");
196     }
197   }
198 }